Skip to content

Commit 3df7c70

Browse files
committed
notify a list of marked players on join
1 parent 41544c6 commit 3df7c70

File tree

3 files changed

+119
-37
lines changed

3 files changed

+119
-37
lines changed

tf2_bot_detector/Actions/Actions.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,3 +124,34 @@ void tf2_bot_detector::from_json(const nlohmann::json& j, KickReason& d)
124124
else
125125
throw std::invalid_argument(mh::format("{}: unexpected value {}", MH_SOURCE_LOCATION_CURRENT(), std::quoted(value)));
126126
}
127+
128+
129+
PartyChatMessageAction::PartyChatMessageAction(const std::string_view& message) :
130+
GenericCommandAction("tf_party_chat", ScrubMessage(std::string(message)))
131+
{
132+
}
133+
134+
duration_t PartyChatMessageAction::GetMinInterval() const
135+
{
136+
return 0s; // Actual cooldown is 0.66 seconds
137+
}
138+
139+
std::string PartyChatMessageAction::ScrubMessage(std::string msg)
140+
{
141+
msg.erase(std::remove_if(msg.begin(), msg.end(),
142+
[](char c)
143+
{
144+
return
145+
c == '\r' ||
146+
c == '\0' ||
147+
c == '\n';
148+
}), msg.end());
149+
150+
for (auto& c : msg)
151+
{
152+
if (c == '"')
153+
c = '\'';
154+
}
155+
156+
return "\""s << msg << '"';
157+
}

tf2_bot_detector/Actions/Actions.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,19 @@ namespace tf2_bot_detector
100100
static std::string ScrubMessage(std::string msg);
101101
};
102102

103+
class PartyChatMessageAction final : public GenericCommandAction
104+
{
105+
public:
106+
PartyChatMessageAction(const std::string_view& message);
107+
108+
duration_t GetMinInterval() const override;
109+
ActionType GetType() const override { return ActionType::ChatMessage; }
110+
size_t GetMaxQueuedCount() const override { return 24; }
111+
112+
private:
113+
static std::string ScrubMessage(std::string msg);
114+
};
115+
103116
#if 0
104117
class StatusUpdateAction final : public GenericCommandAction
105118
{

tf2_bot_detector/ModeratorLogic.cpp

Lines changed: 75 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,40 @@ namespace
171171
}
172172
}
173173

174+
// lazy and dumb function to convert player marks to string
175+
std::string marksToString(PlayerMarks& marks) {
176+
PlayerAttributesList attribute{ 0 };
177+
178+
// combine all the m_Marks to one attributeList
179+
for (const auto& mark : marks.m_Marks)
180+
{
181+
attribute |= mark.m_Attributes;
182+
}
183+
184+
// only one attrib
185+
if (attribute.count() == 1) {
186+
std::size_t idx = 0;
187+
while (idx < static_cast<std::size_t>(PlayerAttribute::COUNT) && !attribute.HasAttribute(static_cast<PlayerAttribute>(idx))) { ++idx; }
188+
189+
//if (idx == static_cast<std::size_t>(PlayerAttribute::COUNT)) {
190+
// return "#Error!";
191+
//}
192+
193+
return to_string(static_cast<PlayerAttribute>(idx));
194+
}
195+
196+
std::string attrib_summary = "-----";
197+
198+
// loop over the attributes and combine using first character.
199+
for (std::size_t i = 0; i < static_cast<std::size_t>(PlayerAttribute::COUNT); ++i) {
200+
if (attribute.HasAttribute(static_cast<PlayerAttribute>(i))) {
201+
attrib_summary.at(i) = to_string(PlayerAttribute::Cheater).at(0);
202+
}
203+
}
204+
205+
return attrib_summary;
206+
}
207+
174208
std::unique_ptr<IModeratorLogic> IModeratorLogic::Create(IWorldState& world,
175209
const Settings& settings, IRCONActionManager& actionManager)
176210
{
@@ -279,16 +313,54 @@ void ModeratorLogic::OnLocalPlayerInitialized(IWorldState & world, bool initiali
279313
mh::fmtstr<128> chatMsg;
280314

281315
int markedPlayerCount = 0;
316+
std::vector<std::string> players;
317+
282318
for (IPlayer& player : m_World->GetLobbyMembers())
283319
{
284320
if (!m_PlayerList.GetPlayerAttributes(player).empty()) {
321+
mh::fmtstr<128> message;
322+
323+
auto marks = GetPlayerAttributes(player);
324+
325+
std::string username = player.GetNameSafe();
326+
327+
// if username is none try getting data from steamapi
328+
if (username == "") {
329+
auto summary = player.GetPlayerSummary();
330+
331+
332+
if (summary.has_value()) {
333+
username = summary.value().m_Nickname;
334+
}
335+
else {
336+
// steamapi didn't get the name either so gg
337+
username = player.GetSteamID().str();
338+
}
339+
}
340+
341+
players.push_back(
342+
message.fmt(
343+
"{}: {} - {} ({})",
344+
markedPlayerCount,
345+
username,
346+
marksToString(marks),
347+
marks.m_Marks.front().m_FileName
348+
).c_str()
349+
);
285350
++markedPlayerCount;
351+
352+
// don't warn again, we're gona warn here.
353+
player.GetOrCreateData<PlayerExtraData>().m_PartyWarned = true;
286354
}
287355
}
288356

289357
chatMsg.fmt("[tf2bd] Currently {} players are marked in this lobby.", markedPlayerCount);
290358

291-
m_ActionManager->QueueAction<ChatMessageAction>(chatMsg.str(), ChatMessageType::PartyChat);
359+
m_ActionManager->QueueAction<PartyChatMessageAction>(chatMsg.str());
360+
361+
for (std::string player : players) {
362+
m_ActionManager->QueueAction<PartyChatMessageAction>(player);
363+
}
292364
}
293365
}
294366

@@ -568,40 +640,6 @@ void ModeratorLogic::HandleConnectingEnemyCheaters(const std::vector<Cheater>& c
568640
}
569641
}
570642

571-
// lazy and dumb function to convert player marks to string
572-
std::string marksToString(PlayerMarks& marks) {
573-
PlayerAttributesList attribute{ 0 };
574-
575-
// combine all the m_Marks to one attributeList
576-
for (const auto& mark : marks.m_Marks)
577-
{
578-
attribute |= mark.m_Attributes;
579-
}
580-
581-
// only one attrib
582-
if (attribute.count() == 1) {
583-
std::size_t idx = 0;
584-
while (idx < static_cast<std::size_t>(PlayerAttribute::COUNT) && !attribute.HasAttribute(static_cast<PlayerAttribute>(idx))) ++idx;
585-
586-
//if (idx == static_cast<std::size_t>(PlayerAttribute::COUNT)) {
587-
// return "#Error!";
588-
//}
589-
590-
return to_string(static_cast<PlayerAttribute>(idx));
591-
}
592-
593-
std::string attrib_summary = "-----";
594-
595-
// loop over the attributes and combine using first character.
596-
for (std::size_t i = 0; i < static_cast<std::size_t>(PlayerAttribute::COUNT); ++i) {
597-
if (attribute.HasAttribute(static_cast<PlayerAttribute>(i))) {
598-
attrib_summary.at(i) = to_string(PlayerAttribute::Cheater).at(0);
599-
}
600-
}
601-
602-
return attrib_summary;
603-
}
604-
605643
void ModeratorLogic::HandleConnectingMarkedPlayers(const std::vector<Cheater>& connectingEnemyCheaters)
606644
{
607645
if (!m_Settings->m_AutoChatWarningsConnectingParty || connectingEnemyCheaters.size() < 1) {
@@ -648,7 +686,7 @@ void ModeratorLogic::HandleConnectingMarkedPlayers(const std::vector<Cheater>& c
648686
username.replace(pos, 1, "");
649687
}
650688

651-
chatMsg.fmt("[tf2bd] WARN: Marked Player ({}) Joining. ({}).", username, marksToString(marks));
689+
chatMsg.fmt("[tf2bd] WARN: Marked Player ({}) Joining ({} - {}).", username, marksToString(marks), marks.m_Marks.front().m_FileName);
652690
}
653691
else
654692
{
@@ -684,7 +722,7 @@ void ModeratorLogic::HandleConnectingMarkedPlayers(const std::vector<Cheater>& c
684722
name += "..";
685723
}
686724

687-
msg += mh::format("{} - {}, ", name, marksToString(marks));
725+
msg += mh::format("{} - {}, ", name, marksToString(marks), marks.m_Marks.front().m_FileName);
688726
}
689727

690728
msg.pop_back();

0 commit comments

Comments
 (0)