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
601 pPoolTemplate.Description = fields[2].
Get<std::string>();
602
603 ++count;
604 } while (result->NextRow());
605
608 }
609
610
611
612 LOG_INFO(
"server.loading",
"Loading Creatures Pooling Data...");
613 {
615
616
618
619 if (!result)
620 {
621 LOG_WARN(
"server.loading",
">> Loaded 0 creatures in pools. DB table `pool_creature` is empty.");
623 }
624 else
625 {
627 do
628 {
629 Field* fields = result->Fetch();
630
633 float chance = fields[2].
Get<
float>();
634
636 if (!data)
637 {
638 LOG_ERROR(
"sql.sql",
"`pool_creature` has a non existing creature spawn (GUID: {}) defined for pool id ({}), skipped.", guid, pool_id);
639 continue;
640 }
643 {
644 LOG_ERROR(
"sql.sql",
"`pool_creature` pool id ({}) is not in `pool_template`, skipped.", pool_id);
645 continue;
646 }
647 if (chance < 0 || chance > 100)
648 {
649 LOG_ERROR(
"sql.sql",
"`pool_creature` has an invalid chance ({}) for creature guid ({}) in pool id ({}), skipped.", chance, guid, pool_id);
650 continue;
651 }
659
660 ++count;
661 } while (result->NextRow());
662
665 }
666 }
667
668
669
670 LOG_INFO(
"server.loading",
"Loading Gameobjects Pooling Data...");
671 {
673
674
676
677 if (!result)
678 {
679 LOG_WARN(
"server.loading",
">> Loaded 0 gameobjects in pools. DB table `pool_gameobject` is empty.");
681 }
682 else
683 {
685 do
686 {
687 Field* fields = result->Fetch();
688
691 float chance = fields[2].
Get<
float>();
692
694 if (!data)
695 {
696 LOG_ERROR(
"sql.sql",
"`pool_gameobject` has a non existing gameobject spawn (GUID: {}) defined for pool id ({}), skipped.", guid, pool_id);
697 continue;
698 }
699
704 {
705 LOG_ERROR(
"sql.sql",
"`pool_gameobject` has a not lootable gameobject spawn (GUID: {}, type: {}) defined for pool id ({}), skipped.", guid, goinfo->
type, pool_id);
706 continue;
707 }
708
711 {
712 LOG_ERROR(
"sql.sql",
"`pool_gameobject` pool id ({}) is not in `pool_template`, skipped.", pool_id);
713 continue;
714 }
715
716 if (chance < 0 || chance > 100)
717 {
718 LOG_ERROR(
"sql.sql",
"`pool_gameobject` has an invalid chance ({}) for gameobject guid ({}) in pool id ({}), skipped.", chance, guid, pool_id);
719 continue;
720 }
721
729
730 ++count;
731 } while (result->NextRow());
732
735 }
736 }
737
738
739
740 LOG_INFO(
"server.loading",
"Loading Mother Pooling Data...");
741 {
743
744
746
747 if (!result)
748 {
749 LOG_WARN(
"server.loading",
">> Loaded 0 pools in pools");
751 }
752 else
753 {
755 do
756 {
757 Field* fields = result->Fetch();
758
761 float chance = fields[2].
Get<
float>();
762
763 {
766 {
767 LOG_ERROR(
"sql.sql",
"`pool_pool` mother_pool id ({}) is not in `pool_template`, skipped.", mother_pool_id);
768 continue;
769 }
770 }
771 {
774 {
775 LOG_ERROR(
"sql.sql",
"`pool_pool` included pool_id ({}) is not in `pool_template`, skipped.", child_pool_id);
776 continue;
777 }
778 }
779 if (mother_pool_id == child_pool_id)
780 {
781 LOG_ERROR(
"sql.sql",
"`pool_pool` pool_id ({}) includes itself, dead-lock detected, skipped.", child_pool_id);
782 continue;
783 }
784 if (chance < 0 || chance > 100)
785 {
786 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);
787 continue;
788 }
796
797 ++count;
798 } while (result->NextRow());
799
800
801
803 {
804 std::set<uint32> checkedPools;
806 {
807 checkedPools.insert(poolItr->first);
808 if (checkedPools.find(poolItr->second) != checkedPools.end())
809 {
810 std::ostringstream ss;
811 ss << "The pool(s) ";
812 for (std::set<uint32>::const_iterator itr = checkedPools.begin(); itr != checkedPools.end(); ++itr)
813 ss << *itr << ' ';
814 ss << "create(s) a circular reference, which can cause the server to freeze.\nRemoving the last link between mother pool "
815 << poolItr->first << " and child pool " << poolItr->second;
819 --count;
820 break;
821 }
822 }
823 }
824
827 }
828 }
829
830 LOG_INFO(
"server.loading",
"Loading Quest Pooling Data...");
831 {
833
836
837 if (!result)
838 {
839 LOG_WARN(
"server.loading",
">> Loaded 0 quests in pools");
841 }
842 else
843 {
846
847 enum eQuestTypes
848 {
849 QUEST_NONE = 0,
850 QUEST_DAILY = 1,
851 QUEST_WEEKLY = 2
852 };
853
854 std::map<uint32, int32> poolTypeMap;
856 do
857 {
858 Field* fields = result->Fetch();
859
862
864 if (!quest)
865 {
866 LOG_ERROR(
"sql.sql",
"`pool_quest` has a non existing quest template (Entry: {}) defined for pool id ({}), skipped.", entry, pool_id);
867 continue;
868 }
869
872 {
873 LOG_ERROR(
"sql.sql",
"`pool_quest` pool id ({}) is not in `pool_template`, skipped.", pool_id);
874 continue;
875 }
876
877 if (!quest->IsDailyOrWeekly())
878 {
879 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);
880 continue;
881 }
882
883 if (poolTypeMap[pool_id] == QUEST_NONE)
884 poolTypeMap[pool_id] = quest->IsDaily() ? QUEST_DAILY : QUEST_WEEKLY;
885
886 int32 currType = quest->IsDaily() ? QUEST_DAILY : QUEST_WEEKLY;
887
888 if (poolTypeMap[pool_id] != currType)
889 {
890 LOG_ERROR(
"sql.sql",
"`pool_quest` quest {} is {} but pool ({}) is specified for {}, mixing not allowed, skipped.",
891 entry, currType == QUEST_DAILY ? "QUEST_DAILY" : "QUEST_WEEKLY", pool_id, poolTypeMap[pool_id] == QUEST_DAILY ? "QUEST_DAILY" : "QUEST_WEEKLY");
892 continue;
893 }
894
897
898 if (creBounds.first == creBounds.second && goBounds.first == goBounds.second)
899 {
900 LOG_ERROR(
"sql.sql",
"`pool_quest` lists entry ({}) as member of pool ({}) but is not started anywhere, skipped.", entry, pool_id);
901 continue;
902 }
903
911
912 ++count;
913 } while (result->NextRow());
914
917 }
918 }
919
920
921 LOG_INFO(
"server.loading",
"Starting Objects Pooling System...");
922 {
924
925 QueryResult result =
WorldDatabase.Query(
"SELECT DISTINCT pool_template.entry, pool_pool.pool_id, pool_pool.mother_pool FROM pool_template"
926 " LEFT JOIN game_event_pool ON pool_template.entry=game_event_pool.pool_entry"
927 " LEFT JOIN pool_pool ON pool_template.entry=pool_pool.pool_id WHERE game_event_pool.pool_entry IS NULL");
928
929 if (!result)
930 {
931 LOG_INFO(
"server.loading",
">> Pool handling system initialized, 0 pools spawned.");
933 }
934 else
935 {
937 do
938 {
939 Field* fields = result->Fetch();
942
944 {
945 if (pool_pool_id)
946
947
948 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>());
949 else
950 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);
951 continue;
952 }
953
954
955 if (!pool_pool_id)
956 {
958 count++;
959 }
960 } while (result->NextRow());
961
964 }
965 }
966}
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
std::int32_t int32
Definition Define.h:103
std::uint32_t uint32
Definition Define.h:107
#define LOG_INFO(filterType__,...)
Definition Log.h:153
#define LOG_ERROR(filterType__,...)
Definition Log.h:145
#define LOG_WARN(filterType__,...)
Definition Log.h:149
std::pair< PooledQuestRelation::const_iterator, PooledQuestRelation::const_iterator > PooledQuestRelationBounds
Definition PoolMgr.h:102
@ GAMEOBJECT_TYPE_CHEST
Definition SharedDefines.h:1567
@ GAMEOBJECT_TYPE_FISHINGHOLE
Definition SharedDefines.h:1589
@ GAMEOBJECT_TYPE_GOOBER
Definition SharedDefines.h:1574
uint32 GetMSTimeDiffToNow(uint32 oldMSTime)
Definition Timer.h:131
uint32 getMSTime()
Definition Timer.h:103
@ WORLD_SEL_QUEST_POOLS
Definition WorldDatabase.h:31
const Position SpawnPool[7]
Definition boss_kelthuzad.cpp:121
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
uint32 LowType
Definition ObjectGuid.h:122
void SetPoolId(uint32 pool_id)
Definition PoolMgr.h:74
void AddEntry(PoolObject &poolitem, uint32 maxentries)
Definition PoolMgr.cpp:133
std::pair< uint32, uint32 > SearchPair
Definition PoolMgr.h:160
bool CheckPool(uint32 pool_id) const
Definition PoolMgr.cpp:1129
PooledQuestRelation mQuestGORelation
Definition PoolMgr.h:139
PooledQuestRelation mQuestCreatureRelation
Definition PoolMgr.h:138
Definition PreparedStatement.h:157
Definition CreatureData.h:370
Definition GameObjectData.h:715
Definition GameObjectData.h:32
uint32 type
Definition GameObjectData.h:34
uint32 MaxLimit
Definition PoolMgr.h:28