AzerothCore 3.3.5a
OpenSource WoW Emulator
Loading...
Searching...
No Matches
pooltools_commandscript Class Reference
Inheritance diagram for pooltools_commandscript:
CommandScript ScriptObject

Public Member Functions

 pooltools_commandscript ()
 
ChatCommandTable GetCommands () const override
 
- Public Member Functions inherited from ScriptObject
virtual bool IsDatabaseBound () const
 
virtual bool isAfterLoadScript () const
 
virtual void checkValidity ()
 
const std::string & GetName () const
 
uint16 GetTotalAvailableHooks ()
 

Static Public Member Functions

static bool HandlePoolStart (ChatHandler *handler, std::string description)
 
static bool HandlePoolDef (ChatHandler *handler, Tail args)
 
static bool HandlePoolAdd (ChatHandler *handler, Optional< float > radiusArg)
 
static bool HandlePoolRemove (ChatHandler *handler)
 
static bool HandlePoolEnd (ChatHandler *handler)
 
static bool HandlePoolClear (ChatHandler *handler)
 

Additional Inherited Members

- Protected Member Functions inherited from CommandScript
 CommandScript (const char *name)
 
- Protected Member Functions inherited from ScriptObject
 ScriptObject (const char *name, uint16 totalAvailableHooks=0)
 
virtual ~ScriptObject ()=default
 

Detailed Description

Constructor & Destructor Documentation

◆ pooltools_commandscript()

pooltools_commandscript::pooltools_commandscript ( )
inline
61: CommandScript("pooltools_commandscript") {}
Definition CommandScript.h:25

Member Function Documentation

◆ GetCommands()

ChatCommandTable pooltools_commandscript::GetCommands ( ) const
inlineoverridevirtual

Implements CommandScript.

64 {
65 static ChatCommandTable poolToolsCommandTable =
66 {
67 { "start", HandlePoolStart, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No },
68 { "def", HandlePoolDef, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No },
69 { "add", HandlePoolAdd, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No },
70 { "remove", HandlePoolRemove, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No },
71 { "end", HandlePoolEnd, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No },
72 { "clear", HandlePoolClear, rbac::RBAC_PERM_COMMAND_DEBUG, Console::No }
73 };
74
75 static ChatCommandTable commandTable =
76 {
77 { "pooltools", poolToolsCommandTable }
78 };
79 return commandTable;
80 }
static bool HandlePoolEnd(ChatHandler *handler)
Definition cs_pooltools.cpp:280
static bool HandlePoolDef(ChatHandler *handler, Tail args)
Definition cs_pooltools.cpp:101
static bool HandlePoolStart(ChatHandler *handler, std::string description)
Definition cs_pooltools.cpp:82
static bool HandlePoolRemove(ChatHandler *handler)
Definition cs_pooltools.cpp:256
static bool HandlePoolClear(ChatHandler *handler)
Definition cs_pooltools.cpp:410
static bool HandlePoolAdd(ChatHandler *handler, Optional< float > radiusArg)
Definition cs_pooltools.cpp:135
std::vector< ChatCommandBuilder > ChatCommandTable
Definition ChatCommand.h:46
@ RBAC_PERM_COMMAND_DEBUG
Definition RBAC.h:193

References HandlePoolAdd(), HandlePoolClear(), HandlePoolDef(), HandlePoolEnd(), HandlePoolRemove(), HandlePoolStart(), and rbac::RBAC_PERM_COMMAND_DEBUG.

◆ HandlePoolAdd()

static bool pooltools_commandscript::HandlePoolAdd ( ChatHandler handler,
Optional< float >  radiusArg 
)
inlinestatic
136 {
137 ObjectGuid playerGuid = handler->GetPlayer()->GetGUID();
138 if (PoolSessions.find(playerGuid) == PoolSessions.end())
139 return false;
140
141 PoolSession& session = PoolSessions[playerGuid];
142 if (session.CurrentTemplate.empty())
143 {
144 handler->SendErrorMessage("Define a template first with .pooltools def");
145 return false;
146 }
147
148 Player* player = handler->GetPlayer();
149 float const radius = radiusArg.value_or(5.0f);
150
151 float searchX = player->GetPositionX();
152 float searchY = player->GetPositionY();
153 float searchZ = player->GetPositionZ();
154
155 GameObject* target = handler->GetNearbyGameObject();
156 if (radius <= 10.0f && target)
157 {
158 searchX = target->GetPositionX();
159 searchY = target->GetPositionY();
160 searchZ = target->GetPositionZ();
161 }
162
163 std::list<GameObject*> nearbyGOs;
164 Acore::GameObjectInRangeCheck check(searchX, searchY, searchZ, radius);
165 Acore::GameObjectListSearcher<Acore::GameObjectInRangeCheck> searcher(player, nearbyGOs, check);
166 Cell::VisitObjects(player, searcher, radius);
167
168 int addedCount = 0;
169 int newGroupsCount = 0;
170
171 for (GameObject* go : nearbyGOs)
172 {
173 if (go->GetDistance(searchX, searchY, searchZ) > radius)
174 continue;
175
176 bool isTemplateMatch = false;
177 for (auto const& tpl : session.CurrentTemplate)
178 {
179 if (go->GetEntry() == tpl.Entry)
180 {
181 isTemplateMatch = true;
182 break;
183 }
184 }
185 if (!isTemplateMatch)
186 continue;
187
188 uint32 const spawnId = go->GetSpawnId();
189
190 bool alreadyCaptured = false;
191 for (auto const& group : session.CapturedGroups)
192 {
193 for (auto const& obj : group.FoundObjects)
194 {
195 if (obj.second == spawnId)
196 {
197 alreadyCaptured = true;
198 break;
199 }
200 }
201 if (alreadyCaptured)
202 break;
203 }
204 if (alreadyCaptured)
205 continue;
206
207 // Clustering
208 NodeGroup* existingGroup = nullptr;
209 for (auto& group : session.CapturedGroups)
210 {
211 if (go->GetDistance(group.X, group.Y, group.Z) < 0.1f)
212 {
213 existingGroup = &group;
214 break;
215 }
216 }
217
218 if (existingGroup)
219 {
220 existingGroup->FoundObjects.push_back({ go->GetEntry(), spawnId });
221 addedCount++;
222 }
223 else
224 {
225 NodeGroup newGroup;
226 newGroup.X = go->GetPositionX();
227 newGroup.Y = go->GetPositionY();
228 newGroup.Z = go->GetPositionZ();
229 newGroup.FoundObjects.push_back({ go->GetEntry(), spawnId });
230
231 session.CapturedGroups.push_back(newGroup);
232 newGroupsCount++;
233 addedCount++;
234 }
235 }
236
237 if (addedCount == 0)
238 {
239 handler->SendErrorMessage("No new matching objects found in {}y radius.", radius);
240 return false;
241 }
242
243 handler->PSendSysMessage("|cff00ff00Scan Complete.|r Added {} objects into {} new groups.", addedCount, newGroupsCount);
244
245 if (!session.CapturedGroups.empty())
246 {
247 NodeGroup& lastGroup = session.CapturedGroups.back();
248 for (auto& p : lastGroup.FoundObjects)
249 {
250 handler->PSendSysMessage(" - Entry {} (GUID: {})", p.first, p.second);
251 }
252 }
253 return true;
254 }
std::uint32_t uint32
Definition Define.h:107
Definition GridNotifiers.h:1600
void PSendSysMessage(std::string_view str, bool escapeCharacters=false)
Definition Chat.cpp:219
void SendErrorMessage(uint32 entry)
Definition Chat.cpp:224
Player * GetPlayer() const
Definition Chat.cpp:37
GameObject * GetNearbyGameObject() const
Definition Chat.cpp:573
Definition GameObject.h:120
Definition ObjectGuid.h:118
static ObjectGuid GetGUID(Object const *o)
Definition Object.h:114
Definition Player.h:1084
static std::map< ObjectGuid, PoolSession > PoolSessions
Definition cs_pooltools.cpp:56
Definition GridNotifiers.h:341
static void VisitObjects(WorldObject const *obj, T &visitor, float radius)
Definition CellImpl.h:165
Definition cs_pooltools.cpp:42
std::vector< std::pair< uint32, uint32 > > FoundObjects
Definition cs_pooltools.cpp:46
float Z
Definition cs_pooltools.cpp:45
float Y
Definition cs_pooltools.cpp:44
float X
Definition cs_pooltools.cpp:43
Definition cs_pooltools.cpp:50
std::vector< NodeGroup > CapturedGroups
Definition cs_pooltools.cpp:53
std::vector< PoolTemplateItem > CurrentTemplate
Definition cs_pooltools.cpp:52
float GetPositionZ() const
Definition Position.h:123
float GetPositionX() const
Definition Position.h:121
float GetPositionY() const
Definition Position.h:122

References PoolSession::CapturedGroups, PoolSession::CurrentTemplate, NodeGroup::FoundObjects, Object::GetGUID(), ChatHandler::GetNearbyGameObject(), ChatHandler::GetPlayer(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), PoolSessions, ChatHandler::PSendSysMessage(), ChatHandler::SendErrorMessage(), Cell::VisitObjects(), NodeGroup::X, NodeGroup::Y, and NodeGroup::Z.

Referenced by GetCommands().

◆ HandlePoolClear()

static bool pooltools_commandscript::HandlePoolClear ( ChatHandler handler)
inlinestatic
411 {
412 PoolSessions.erase(handler->GetPlayer()->GetGUID());
413 handler->PSendSysMessage("Session cleared.");
414 return true;
415 }

References Object::GetGUID(), ChatHandler::GetPlayer(), PoolSessions, and ChatHandler::PSendSysMessage().

Referenced by GetCommands().

◆ HandlePoolDef()

static bool pooltools_commandscript::HandlePoolDef ( ChatHandler handler,
Tail  args 
)
inlinestatic
102 {
103 ObjectGuid playerGuid = handler->GetPlayer()->GetGUID();
104 if (PoolSessions.find(playerGuid) == PoolSessions.end())
105 {
106 handler->SendErrorMessage("No active session.");
107 return false;
108 }
109
110 std::vector<std::string_view> tokens = Acore::Tokenize(args, ' ', false);
111
112 if (tokens.empty() || tokens.size() % 2 != 0)
113 {
114 handler->SendErrorMessage("Invalid syntax. Usage: .pooltools def [ID] [Chance] [ID] [Chance]...");
115 return false;
116 }
117
118 std::vector<PoolTemplateItem> newTemplate;
119 for (size_t i = 0; i < tokens.size(); i += 2)
120 {
121 uint32 const entry = Acore::StringTo<uint32>(tokens[i]).value_or(0);
122 uint32 const chance = Acore::StringTo<uint32>(tokens[i + 1]).value_or(0);
123
124 if (entry == 0)
125 continue;
126
127 newTemplate.push_back({ entry, chance });
128 }
129
130 PoolSessions[playerGuid].CurrentTemplate = newTemplate;
131 handler->PSendSysMessage("Template Defined ({} items).", newTemplate.size());
132 return true;
133 }
std::vector< std::string_view > Tokenize(std::string_view str, char sep, bool keepEmpty)
Definition Tokenize.cpp:20

References Object::GetGUID(), ChatHandler::GetPlayer(), PoolSessions, ChatHandler::PSendSysMessage(), ChatHandler::SendErrorMessage(), and Acore::Tokenize().

Referenced by GetCommands().

◆ HandlePoolEnd()

static bool pooltools_commandscript::HandlePoolEnd ( ChatHandler handler)
inlinestatic
281 {
282 ObjectGuid playerGuid = handler->GetPlayer()->GetGUID();
283 auto it = PoolSessions.find(playerGuid);
284 if (it == PoolSessions.end())
285 return false;
286
287 PoolSession& session = it->second; // Use reference from iterator
288
289 auto EscapeSQL = [](std::string_view input) -> std::string {
290 std::string safe;
291 safe.reserve(input.size());
292 for (char c : input)
293 {
294 if (c == '\'')
295 safe += "\\'";
296 else
297 safe += c;
298 }
299 return safe;
300 };
301
302 bool const complexPool = (session.CurrentTemplate.size() > 1);
303
304 // SQL Variables and Header
305 LOG_DEBUG("sql.dev", "-- Pool Dump: {}", session.ZoneName);
306 LOG_DEBUG("sql.dev", "SET @mother_pool := @mother_pool+1;");
307
308 if (complexPool)
309 LOG_DEBUG("sql.dev", "SET @pool_node := @pool_node+1;");
310
311 LOG_DEBUG("sql.dev", "SET @max_limit := {};", (session.CapturedGroups.size() + 3) / 4);
312
313 // DELETEs section
314 if (!session.CapturedGroups.empty())
315 {
316 LOG_DEBUG("sql.dev", "-- Cleanup specific object links");
317 LOG_DEBUG("sql.dev", "DELETE FROM `pool_gameobject` WHERE `guid` IN (");
318
319 std::vector<std::string> guidList;
320 for (auto const& group : session.CapturedGroups)
321 for (auto const& obj : group.FoundObjects)
322 guidList.push_back(std::to_string(obj.second));
323
324 LOG_DEBUG("sql.dev", fmt::format("{}", fmt::join(guidList, ", ")));
325 LOG_DEBUG("sql.dev", ");\n");
326 }
327
328 LOG_DEBUG("sql.dev", "DELETE FROM `pool_template` WHERE `entry`=@mother_pool;");
329 LOG_DEBUG("sql.dev", "INSERT INTO `pool_template` (`entry`, `max_limit`, `description`) VALUES (@mother_pool, @max_limit, '{} - Mother Pool');", EscapeSQL(session.ZoneName));
330
331 int groupCounter = 0;
332
333 // We can buffer the simple bulk inserts here
334 std::vector<std::string> bulkInserts;
335
336 for (auto const& group : session.CapturedGroups)
337 {
338 groupCounter++;
339
340 // Generate Description
341 std::set<std::string> uniqueNames;
342 for (auto const& obj : group.FoundObjects)
343 {
344 GameObjectTemplate const* goInfo = sObjectMgr->GetGameObjectTemplate(obj.first);
345 uniqueNames.insert(goInfo ? goInfo->name : std::to_string(obj.first));
346 }
347
348 std::string groupDesc = fmt::format("{}", fmt::join(uniqueNames, " / "));
349 std::string safeGroupDesc = EscapeSQL(groupDesc);
350
351 // Simple pooling
352 if (!complexPool)
353 {
354 for (auto const& obj : group.FoundObjects)
355 {
356 float chance = 0.0f;
357 for (auto const& tpl : session.CurrentTemplate)
358 if (tpl.Entry == obj.first)
359 chance = (float)tpl.Chance;
360
361 bulkInserts.push_back(fmt::format("({}, @mother_pool, {}, '{} - {}')",
362 obj.second, chance, EscapeSQL(session.ZoneName), safeGroupDesc));
363 }
364 }
365 // Pool_pool integration
366 else
367 {
368 LOG_DEBUG("sql.dev", "-- Group {}", groupCounter);
369 LOG_DEBUG("sql.dev", "SET @pool_node := @pool_node + 1;");
370
371 // Create the Sub-Pool Node
372 LOG_DEBUG("sql.dev", "INSERT INTO `pool_template` (`entry`, `max_limit`, `description`) VALUES (@pool_node, 1, '{} - Node {}');", EscapeSQL(session.ZoneName), groupCounter);
373
374 // Link Node to Mother Pool
375 LOG_DEBUG("sql.dev", "INSERT INTO `pool_pool` (`pool_id`, `mother_pool`, `chance`, `description`) VALUES (@pool_node, @mother_pool, 0, '{} - {}');", EscapeSQL(session.ZoneName), safeGroupDesc);
376
377 // Link Objects to Sub-Pool Node
378 LOG_DEBUG("sql.dev", "INSERT INTO `pool_gameobject` (`guid`, `pool_entry`, `chance`, `description`) VALUES");
379
380 std::vector<std::string> nodeInserts;
381 for (auto const& obj : group.FoundObjects)
382 {
383 GameObjectTemplate const* goInfo = sObjectMgr->GetGameObjectTemplate(obj.first);
384 std::string objName = goInfo ? goInfo->name : "Unknown";
385
386 float chance = 0.0f;
387 for (auto const& tpl : session.CurrentTemplate)
388 if (tpl.Entry == obj.first) chance = (float)tpl.Chance;
389
390 nodeInserts.push_back(fmt::format("({}, @pool_node, {}, '{} - {}')",
391 obj.second, chance, EscapeSQL(session.ZoneName), EscapeSQL(objName)));
392 }
393 LOG_DEBUG("sql.dev", "{};", fmt::join(nodeInserts, ",\n"));
394 }
395 }
396
397 if (!complexPool && !bulkInserts.empty())
398 {
399 LOG_DEBUG("sql.dev", "INSERT INTO `pool_gameobject` (`guid`, `pool_entry`, `chance`, `description`) VALUES");
400 LOG_DEBUG("sql.dev", "{};", fmt::join(bulkInserts, ",\n"));
401 }
402
403 handler->PSendSysMessage("Dumped {} groups.", groupCounter);
404
405 // Cleanup
406 PoolSessions.erase(it);
407 return true;
408 }
#define LOG_DEBUG(filterType__,...)
Definition Log.h:157
#define sObjectMgr
Definition ObjectMgr.h:1723
uint32 const Entry[3]
Definition instance_blackwing_lair.cpp:73
STL namespace.
Definition GameObjectData.h:32
std::string name
Definition GameObjectData.h:36
std::string ZoneName
Definition cs_pooltools.cpp:51

References PoolSession::CapturedGroups, PoolSession::CurrentTemplate, Object::GetGUID(), ChatHandler::GetPlayer(), LOG_DEBUG, GameObjectTemplate::name, PoolSessions, ChatHandler::PSendSysMessage(), sObjectMgr, and PoolSession::ZoneName.

Referenced by GetCommands().

◆ HandlePoolRemove()

static bool pooltools_commandscript::HandlePoolRemove ( ChatHandler handler)
inlinestatic
257 {
258 ObjectGuid const playerGuid = handler->GetPlayer()->GetGUID();
259 if (PoolSessions.find(playerGuid) == PoolSessions.end())
260 {
261 handler->SendErrorMessage("No active session.");
262 return false;
263 }
264
265 PoolSession& session = PoolSessions[playerGuid];
266
267 if (session.CapturedGroups.empty())
268 {
269 handler->SendErrorMessage("No groups captured.");
270 return false;
271 }
272
273 NodeGroup removed = session.CapturedGroups.back();
274 session.CapturedGroups.pop_back();
275
276 handler->PSendSysMessage("|cffff0000Undo Successful.|r Removed last group containing {} objects.", removed.FoundObjects.size());
277 return true;
278 }

References PoolSession::CapturedGroups, NodeGroup::FoundObjects, Object::GetGUID(), ChatHandler::GetPlayer(), PoolSessions, ChatHandler::PSendSysMessage(), and ChatHandler::SendErrorMessage().

Referenced by GetCommands().

◆ HandlePoolStart()

static bool pooltools_commandscript::HandlePoolStart ( ChatHandler handler,
std::string  description 
)
inlinestatic
83 {
84 ObjectGuid const playerGuid = handler->GetPlayer()->GetGUID();
85
86 if (PoolSessions.find(playerGuid) != PoolSessions.end())
87 {
88 handler->SendErrorMessage("Session already active. Use .pooltools clear first.");
89 return false;
90 }
91
92 PoolSession session;
93 session.ZoneName = description;
94
95 PoolSessions[playerGuid] = session;
96
97 handler->PSendSysMessage("|cff00ff00Pool Session Started.|r Description: {}", description);
98 return true;
99 }

References Object::GetGUID(), ChatHandler::GetPlayer(), PoolSessions, ChatHandler::PSendSysMessage(), ChatHandler::SendErrorMessage(), and PoolSession::ZoneName.

Referenced by GetCommands().


The documentation for this class was generated from the following file: