Alex King 3335cacac1
[Bots] Cleanup and remove preprocessors. (#2757)
* [Bots] Cleanup and remove preprocessors.

- Removes every `#ifdef BOTS` we have and locks bots behind `Bots:AllowBots` rule.
- Bot updates are now done by default similar to regular database updates.
- Modify `CMakeLists.txt`, `.drone.yml`, and `BUILD.md` to match the removal of `EQEMU_ENABLE_BOTS`.

* Cleanup

- Add SQL for enabling bots for servers with bots.
- Add message that tells players/operators bots are disabled.

* Suggested changes.

* Bot injection stuff

* Change SQL to bot SQL.

* Tweaks

* Remove `is_bot`

* Update version.h

* Update main.cpp

* Update database.cpp

* Fix name availability crash

* Remove bots from update script

Co-authored-by: Akkadius <akkadius1@gmail.com>
2023-01-20 12:35:33 -06:00

201 lines
4.7 KiB
C++
Executable File

#include "../client.h"
#include "../../common/http/httplib.h"
#include "../../common/content/world_content_service.h"
#include "../bot.h"
void command_gearup(Client *c, const Seperator *sep)
{
Mob* t = c;
if (
c->GetTarget() &&
(
(c->GetTarget()->IsClient() && c->GetGM()) ||
c->GetTarget()->IsBot()
)
) {
t = c->GetTarget();
}
const std::string tool_table_name = "tool_gearup_armor_sets";
if (!database.DoesTableExist(tool_table_name)) {
c->Message(
Chat::Yellow,
fmt::format(
"Table [{}] does not exist. Downloading from Github and installing...",
tool_table_name
).c_str()
);
// http get request
httplib::Client cli("https://raw.githubusercontent.com");
cli.set_connection_timeout(0, 15000000); // 15 sec
cli.set_read_timeout(15, 0); // 15 seconds
cli.set_write_timeout(15, 0); // 15 seconds
int sourced_queries = 0;
std::string url = "/EQEmu/Server/master/utils/sql/git/optional/2020_07_20_tool_gearup_armor_sets.sql";
if (auto res = cli.Get(url.c_str())) {
if (res->status == 200) {
for (auto &s: Strings::Split(res->body, ';')) {
if (!Strings::Trim(s).empty()) {
auto results = database.QueryDatabase(s);
if (!results.ErrorMessage().empty()) {
c->Message(
Chat::Yellow,
fmt::format(
"Error sourcing SQL [{}]", results.ErrorMessage()
).c_str()
);
return;
}
sourced_queries++;
}
}
}
} else {
c->Message(
Chat::Yellow,
fmt::format(
"Error retrieving URL [{}]",
url
).c_str()
);
}
c->Message(
Chat::Yellow,
fmt::format(
"Table [{}] installed. Sourced [{}] quer{}",
tool_table_name,
sourced_queries,
sourced_queries != 1 ? "ies" : "y"
).c_str()
);
}
const std::string expansion_arg = sep->arg[1];
std::string expansion_filter;
if (!expansion_arg.empty()) {
expansion_filter = fmt::format(" AND `expansion` = {}", expansion_arg);
}
auto query = fmt::format(
"SELECT item_id, slot FROM {} WHERE "
"`class` = {} AND `level` = {}{} "
"ORDER BY score DESC, expansion DESC",
tool_table_name,
t->GetClass(),
t->GetLevel(),
expansion_filter
);
auto results = database.QueryDatabase(query);
int items_equipped = 0;
int items_already_have = 0;
std::set<int> equipped;
for (auto row : results) {
auto item_id = std::stoul(row[0]);
auto slot_id = static_cast<uint16>(std::stoul(row[1]));
if (equipped.find(slot_id) != equipped.end()) {
if (slot_id == EQ::invslot::slotEar1) {
slot_id = EQ::invslot::slotEar2;
} else if (slot_id == EQ::invslot::slotFinger1) {
slot_id = EQ::invslot::slotFinger2;
} else if (slot_id == EQ::invslot::slotWrist1) {
slot_id = EQ::invslot::slotWrist2;
}
}
if (equipped.find(slot_id) == equipped.end()) {
const auto *item = database.GetItem(item_id);
bool has_item = false;
if (t->IsClient()) {
has_item = t->CastToClient()->GetInv().HasItem(item_id, 1, invWhereWorn) != INVALID_INDEX;
} else if (t->IsBot()) {
has_item = t->CastToBot()->HasBotItem(item_id);
}
bool can_wear_item = false;
if (t->IsClient()) {
can_wear_item = !t->CastToClient()->CheckLoreConflict(item) && !has_item;
} else if (t->IsBot()) {
can_wear_item = !t->CastToBot()->CheckLoreConflict(item) && !has_item;
}
if (!can_wear_item) {
items_already_have++;
}
if (
can_wear_item &&
t->CanClassEquipItem(item_id) &&
(
t->CanRaceEquipItem(item_id) ||
(t->IsBot() && !t->CanRaceEquipItem(item_id) && RuleB(Bots, AllowBotEquipAnyRaceGear))
)
) {
equipped.insert(slot_id);
if (t->IsClient()) {
t->CastToClient()->SummonItem(
item_id,
0, 0, 0, 0, 0, 0, 0, 0,
slot_id
);
} else if (t->IsBot()) {
t->CastToBot()->AddBotItem(slot_id, item_id);
}
items_equipped++;
}
}
}
c->Message(
Chat::White,
fmt::format(
"Equipped items [{}] already had [{}] items equipped",
items_equipped,
items_already_have
).c_str()
);
if (expansion_arg.empty()) {
query = fmt::format(
"SELECT expansion FROM {} WHERE "
"class = {} AND level = {} "
"GROUP BY expansion",
tool_table_name,
t->GetClass(),
t->GetLevel()
);
results = database.QueryDatabase(query);
c->Message(Chat::White, "Choose Armor by Expansion:");
std::string message;
for (auto row : results) {
const auto expansion = std::stoi(row[0]);
message += fmt::format(
"[{}] ",
Saylink::Silent(
fmt::format("#gearup {}", expansion),
Expansion::ExpansionName[expansion]
)
);
if (message.length() > 2000) {
c->Message(Chat::White, message.c_str());
message = std::string();
}
}
if (!message.empty()) {
c->Message(Chat::White, message.c_str());
}
}
}