575{
576
577 {
579
581 if (!result)
582 {
584 LOG_WARN(
"server.loading",
">> Loaded 0 object pools. DB table `pool_template` is empty.");
586 return;
587 }
588
590 do
591 {
592 Field* fields = result->Fetch();
593
595
597 pPoolTemplate.MaxLimit = fields[1].
Get<
uint32>();
598
599 ++count;
600 } while (result->NextRow());
601
604 }
605
606
607
608 LOG_INFO(
"server.loading",
"Loading Creatures Pooling Data...");
609 {
611
612
614
615 if (!result)
616 {
617 LOG_WARN(
"server.loading",
">> Loaded 0 creatures in pools. DB table `pool_creature` is empty.");
619 }
620 else
621 {
623 do
624 {
625 Field* fields = result->Fetch();
626
629 float chance = fields[2].
Get<
float>();
630
632 if (!data)
633 {
634 LOG_ERROR(
"sql.sql",
"`pool_creature` has a non existing creature spawn (GUID: {}) defined for pool id ({}), skipped.", guid, pool_id);
635 continue;
636 }
639 {
640 LOG_ERROR(
"sql.sql",
"`pool_creature` pool id ({}) is not in `pool_template`, skipped.", pool_id);
641 continue;
642 }
643 if (chance < 0 || chance > 100)
644 {
645 LOG_ERROR(
"sql.sql",
"`pool_creature` has an invalid chance ({}) for creature guid ({}) in pool id ({}), skipped.", chance, guid, pool_id);
646 continue;
647 }
655
656 ++count;
657 } while (result->NextRow());
658
661 }
662 }
663
664
665
666 LOG_INFO(
"server.loading",
"Loading Gameobjects Pooling Data...");
667 {
669
670
672
673 if (!result)
674 {
675 LOG_WARN(
"server.loading",
">> Loaded 0 gameobjects in pools. DB table `pool_gameobject` is empty.");
677 }
678 else
679 {
681 do
682 {
683 Field* fields = result->Fetch();
684
687 float chance = fields[2].
Get<
float>();
688
690 if (!data)
691 {
692 LOG_ERROR(
"sql.sql",
"`pool_gameobject` has a non existing gameobject spawn (GUID: {}) defined for pool id ({}), skipped.", guid, pool_id);
693 continue;
694 }
695
700 {
701 LOG_ERROR(
"sql.sql",
"`pool_gameobject` has a not lootable gameobject spawn (GUID: {}, type: {}) defined for pool id ({}), skipped.", guid, goinfo->
type, pool_id);
702 continue;
703 }
704
707 {
708 LOG_ERROR(
"sql.sql",
"`pool_gameobject` pool id ({}) is not in `pool_template`, skipped.", pool_id);
709 continue;
710 }
711
712 if (chance < 0 || chance > 100)
713 {
714 LOG_ERROR(
"sql.sql",
"`pool_gameobject` has an invalid chance ({}) for gameobject guid ({}) in pool id ({}), skipped.", chance, guid, pool_id);
715 continue;
716 }
717
725
726 ++count;
727 } while (result->NextRow());
728
731 }
732 }
733
734
735
736 LOG_INFO(
"server.loading",
"Loading Mother Pooling Data...");
737 {
739
740
742
743 if (!result)
744 {
745 LOG_WARN(
"server.loading",
">> Loaded 0 pools in pools");
747 }
748 else
749 {
751 do
752 {
753 Field* fields = result->Fetch();
754
757 float chance = fields[2].
Get<
float>();
758
759 {
762 {
763 LOG_ERROR(
"sql.sql",
"`pool_pool` mother_pool id ({}) is not in `pool_template`, skipped.", mother_pool_id);
764 continue;
765 }
766 }
767 {
770 {
771 LOG_ERROR(
"sql.sql",
"`pool_pool` included pool_id ({}) is not in `pool_template`, skipped.", child_pool_id);
772 continue;
773 }
774 }
775 if (mother_pool_id == child_pool_id)
776 {
777 LOG_ERROR(
"sql.sql",
"`pool_pool` pool_id ({}) includes itself, dead-lock detected, skipped.", child_pool_id);
778 continue;
779 }
780 if (chance < 0 || chance > 100)
781 {
782 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);
783 continue;
784 }
792
793 ++count;
794 } while (result->NextRow());
795
796
797
799 {
800 std::set<uint32> checkedPools;
802 {
803 checkedPools.insert(poolItr->first);
804 if (checkedPools.find(poolItr->second) != checkedPools.end())
805 {
806 std::ostringstream ss;
807 ss << "The pool(s) ";
808 for (std::set<uint32>::const_iterator itr = checkedPools.begin(); itr != checkedPools.end(); ++itr)
809 ss << *itr << ' ';
810 ss << "create(s) a circular reference, which can cause the server to freeze.\nRemoving the last link between mother pool "
811 << poolItr->first << " and child pool " << poolItr->second;
815 --count;
816 break;
817 }
818 }
819 }
820
823 }
824 }
825
826 LOG_INFO(
"server.loading",
"Loading Quest Pooling Data...");
827 {
829
832
833 if (!result)
834 {
835 LOG_WARN(
"server.loading",
">> Loaded 0 quests in pools");
837 }
838 else
839 {
842
843 enum eQuestTypes
844 {
845 QUEST_NONE = 0,
846 QUEST_DAILY = 1,
847 QUEST_WEEKLY = 2
848 };
849
850 std::map<uint32, int32> poolTypeMap;
852 do
853 {
854 Field* fields = result->Fetch();
855
858
860 if (!quest)
861 {
862 LOG_ERROR(
"sql.sql",
"`pool_quest` has a non existing quest template (Entry: {}) defined for pool id ({}), skipped.", entry, pool_id);
863 continue;
864 }
865
868 {
869 LOG_ERROR(
"sql.sql",
"`pool_quest` pool id ({}) is not in `pool_template`, skipped.", pool_id);
870 continue;
871 }
872
873 if (!quest->IsDailyOrWeekly())
874 {
875 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);
876 continue;
877 }
878
879 if (poolTypeMap[pool_id] == QUEST_NONE)
880 poolTypeMap[pool_id] = quest->IsDaily() ? QUEST_DAILY : QUEST_WEEKLY;
881
882 int32 currType = quest->IsDaily() ? QUEST_DAILY : QUEST_WEEKLY;
883
884 if (poolTypeMap[pool_id] != currType)
885 {
886 LOG_ERROR(
"sql.sql",
"`pool_quest` quest {} is {} but pool ({}) is specified for {}, mixing not allowed, skipped.",
887 entry, currType == QUEST_DAILY ? "QUEST_DAILY" : "QUEST_WEEKLY", pool_id, poolTypeMap[pool_id] == QUEST_DAILY ? "QUEST_DAILY" : "QUEST_WEEKLY");
888 continue;
889 }
890
893
894 if (creBounds.first == creBounds.second && goBounds.first == goBounds.second)
895 {
896 LOG_ERROR(
"sql.sql",
"`pool_quest` lists entry ({}) as member of pool ({}) but is not started anywhere, skipped.", entry, pool_id);
897 continue;
898 }
899
907
908 ++count;
909 } while (result->NextRow());
910
913 }
914 }
915
916
917 LOG_INFO(
"server.loading",
"Starting Objects Pooling System...");
918 {
920
921 QueryResult result =
WorldDatabase.Query(
"SELECT DISTINCT pool_template.entry, pool_pool.pool_id, pool_pool.mother_pool FROM pool_template"
922 " LEFT JOIN game_event_pool ON pool_template.entry=game_event_pool.pool_entry"
923 " LEFT JOIN pool_pool ON pool_template.entry=pool_pool.pool_id WHERE game_event_pool.pool_entry IS NULL");
924
925 if (!result)
926 {
927 LOG_INFO(
"server.loading",
">> Pool handling system initialized, 0 pools spawned.");
929 }
930 else
931 {
933 do
934 {
935 Field* fields = result->Fetch();
938
940 {
941 if (pool_pool_id)
942
943
944 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>());
945 else
946 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);
947 continue;
948 }
949
950
951 if (!pool_pool_id)
952 {
954 count++;
955 }
956 } while (result->NextRow());
957
960 }
961 }
962}
std::int32_t int32
Definition: Define.h:104
std::uint32_t uint32
Definition: Define.h:108
#define LOG_INFO(filterType__,...)
Definition: Log.h:167
#define LOG_ERROR(filterType__,...)
Definition: Log.h:159
#define LOG_WARN(filterType__,...)
Definition: Log.h:163
uint32 GetMSTimeDiffToNow(uint32 oldMSTime)
Definition: Timer.h:131
uint32 getMSTime()
Definition: Timer.h:103
DatabaseWorkerPool< WorldDatabaseConnection > WorldDatabase
Accessor to the world database.
Definition: DatabaseEnv.cpp:20
std::shared_ptr< ResultSet > QueryResult
Definition: DatabaseEnvFwd.h:28
std::shared_ptr< PreparedResultSet > PreparedQueryResult
Definition: DatabaseEnvFwd.h:46
@ WORLD_SEL_QUEST_POOLS
Definition: WorldDatabase.h:31
std::pair< PooledQuestRelation::const_iterator, PooledQuestRelation::const_iterator > PooledQuestRelationBounds
Definition: PoolMgr.h:99
const Position SpawnPool[7]
Definition: boss_kelthuzad.cpp:122
@ GAMEOBJECT_TYPE_CHEST
Definition: SharedDefines.h:1535
@ GAMEOBJECT_TYPE_FISHINGHOLE
Definition: SharedDefines.h:1557
@ GAMEOBJECT_TYPE_GOOBER
Definition: SharedDefines.h:1542
Definition: PreparedStatement.h:158
Class used to access individual fields of database query result.
Definition: Field.h:99
std::enable_if_t< std::is_arithmetic_v< T >, T > Get() const
Definition: Field.h:113
Definition: CreatureData.h:359
Definition: GameObjectData.h:32
uint32 type
Definition: GameObjectData.h:34
Definition: GameObjectData.h:697
uint32 LowType
Definition: ObjectGuid.h:124
uint32 MaxLimit
Definition: PoolMgr.h:28
void SetPoolId(uint32 pool_id)
Definition: PoolMgr.h:73
void AddEntry(PoolObject &poolitem, uint32 maxentries)
Definition: PoolMgr.cpp:132
std::pair< uint32, uint32 > SearchPair
Definition: PoolMgr.h:146
bool CheckPool(uint32 pool_id) const
Definition: PoolMgr.cpp:1111
PoolTemplateDataMap mPoolTemplate
Definition: PoolMgr.h:149
PooledQuestRelation mQuestGORelation
Definition: PoolMgr.h:135
PooledQuestRelation mQuestCreatureRelation
Definition: PoolMgr.h:134