[Rules] Add rule to allow players to permanently save chat channels to database, up to a limit. (#2706)

* Initial code

* Tweak

* Rule description tweak

* More channel work

* More adjustments

* Auto-join saved permanent player channels

* Fix UCS crash if player has no channels to load from table.

* Implemented channel blocking feature

* Update database when player channel's owner or password change

* First round of requested changes.

* Logic tweak to ensure player channels are sets to permanent when appropraite

* name_filter table integration and some refactoring

* Use new `reserved_channel_names` table to block specific channel names.

* Remove some legacy channel block code

* Setup required SQL update to create  `reserved_channel_names`  table.

* Update db_update_manifest.txt

* Update db_update_manifest.txt

* Update chatchannel.cpp

* Code review

* Database to UCSDatabase

* Repository SaveChatChannel

* CurrentPlayerChannelCount repository

* Cleanup name filter

* CreateChannel

* Update websocketpp

* Increment CURRENT_BINARY_DATABASE_VERSION

Set to 9216

* Minor tweaks to blocked channel name checks & other related areas.

- Enforce blocked channel names on channel creation.
- Also enforce blocked channel names on channel join.
- Add channel status check to Debug logging.
- Minor formatting adjustments.
- Add single quotes to column name value in query.

* Minor log change

* Increment DB Version

* Formatting Tweaks

- Made formatting adjustments consistent with KinglyKrab's recommended changes.
- This compiles successfully with these changes, but unable to test the changes until this weekend.

Co-authored-by: Akkadius <akkadius1@gmail.com>
This commit is contained in:
Vayle
2023-01-18 23:42:09 -05:00
committed by GitHub
parent 03a27b02ff
commit 29473aa7f5
16 changed files with 1409 additions and 286 deletions
+259 -124
View File
@@ -33,33 +33,33 @@ void ServerToClient50SayLink(std::string& clientSayLink, const std::string& serv
void ServerToClient55SayLink(std::string& clientSayLink, const std::string& serverSayLink);
ChatChannel::ChatChannel(std::string inName, std::string inOwner, std::string inPassword, bool inPermanent, int inMinimumStatus) :
DeleteTimer(0) {
m_delete_timer(0) {
Name = inName;
m_name = inName;
Owner = inOwner;
m_owner = inOwner;
Password = inPassword;
m_password = inPassword;
Permanent = inPermanent;
m_permanent = inPermanent;
MinimumStatus = inMinimumStatus;
m_minimum_status = inMinimumStatus;
Moderated = false;
m_moderated = false;
LogDebug(
"New ChatChannel created: Name: [[{}]], Owner: [[{}]], Password: [[{}]], MinStatus: [{}]",
Name.c_str(),
Owner.c_str(),
Password.c_str(),
MinimumStatus
"New ChatChannel created: Name: [{}], Owner: [{}], Password: [{}], MinStatus: [{}]",
m_name.c_str(),
m_owner.c_str(),
m_password.c_str(),
m_minimum_status
);
}
ChatChannel::~ChatChannel() {
LinkedListIterator<Client*> iterator(ClientsInChannel);
LinkedListIterator<Client*> iterator(m_clients_in_channel);
iterator.Reset();
@@ -67,18 +67,79 @@ ChatChannel::~ChatChannel() {
iterator.RemoveCurrent(false);
}
ChatChannel* ChatChannelList::CreateChannel(std::string Name, std::string Owner, std::string Password, bool Permanent, int MinimumStatus) {
ChatChannel *ChatChannelList::CreateChannel(
const std::string& name,
const std::string& owner,
const std::string& password,
bool permanent,
int minimum_status,
bool save_to_db
)
{
uint8 max_perm_player_channels = RuleI(Chat, MaxPermanentPlayerChannels);
ChatChannel *NewChannel = new ChatChannel(CapitaliseName(Name), Owner, Password, Permanent, MinimumStatus);
if (!database.CheckChannelNameFilter(name)) {
if (!(owner == SYSTEM_OWNER)) {
return nullptr;
}
else {
LogDebug("Ignoring Name Filter as channel is owned by System...");
}
}
ChatChannels.Insert(NewChannel);
if (IsOnChannelBlockList(name)) {
if (!(owner == SYSTEM_OWNER)) {
LogInfo("Channel name [{}] is a reserved/blocked channel name. Channel creation canceled.", name);
return nullptr;
}
else {
LogInfo("Ignoring reserved/blocked channel name [{}] as channel is owned by System...", name);
}
}
else {
LogDebug("Channel name [{}] passed the reserved/blocked channel name check...", name);
}
return NewChannel;
auto *new_channel = new ChatChannel(CapitaliseName(name), owner, password, permanent, minimum_status);
ChatChannels.Insert(new_channel);
if (owner == SYSTEM_OWNER) {
save_to_db = false;
}
// If permanent player channels are enabled (and not a system channel)
// save channel to database if not exceeding limit.
bool can_save_channel = (max_perm_player_channels > 0) && !(owner == SYSTEM_OWNER) && save_to_db;
if (can_save_channel) {
// Ensure there is room to save another chat channel to the database.
bool player_under_channel_limit = database.CurrentPlayerChannelCount(owner) + 1 <= max_perm_player_channels;
if (player_under_channel_limit) {
database.SaveChatChannel(
CapitaliseName(name),
owner,
password,
minimum_status
);
}
else {
LogDebug(
"Maximum number of channels [{}] reached for player [{}], channel [{}] save to database aborted.",
max_perm_player_channels,
owner,
CapitaliseName(name)
);
}
}
return new_channel;
}
ChatChannel* ChatChannelList::FindChannel(std::string Name) {
std::string NormalisedName = CapitaliseName(Name);
std::string normalized_name = CapitaliseName(Name);
LinkedListIterator<ChatChannel*> iterator(ChatChannels);
@@ -86,9 +147,9 @@ ChatChannel* ChatChannelList::FindChannel(std::string Name) {
while(iterator.MoreElements()) {
ChatChannel *CurrentChannel = iterator.GetData();
auto *current_channel = iterator.GetData();
if(CurrentChannel && (CurrentChannel->Name == NormalisedName))
if(current_channel && (current_channel->m_name == normalized_name))
return iterator.GetData();
iterator.Advance();
@@ -159,7 +220,7 @@ void ChatChannelList::SendAllChannels(Client *c) {
void ChatChannelList::RemoveChannel(ChatChannel *Channel) {
LogDebug("RemoveChannel ([{}])", Channel->GetName().c_str());
LogDebug("Remove channel [{}]", Channel->GetName().c_str());
LinkedListIterator<ChatChannel*> iterator(ChatChannels);
@@ -194,7 +255,7 @@ int ChatChannel::MemberCount(int Status) {
int Count = 0;
LinkedListIterator<Client*> iterator(ClientsInChannel);
LinkedListIterator<Client*> iterator(m_clients_in_channel);
iterator.Reset();
@@ -211,30 +272,43 @@ int ChatChannel::MemberCount(int Status) {
return Count;
}
void ChatChannel::SetPassword(std::string inPassword) {
void ChatChannel::SetPassword(const std::string& in_password) {
Password = inPassword;
m_password = in_password;
if(Permanent)
if(m_permanent)
{
RemoveApostrophes(Password);
database.SetChannelPassword(Name, Password);
RemoveApostrophes(m_password);
database.SetChannelPassword(m_name, m_password);
}
}
void ChatChannel::SetOwner(std::string inOwner) {
void ChatChannel::SetOwner(std::string& in_owner) {
Owner = inOwner;
m_owner = in_owner;
if(Permanent)
database.SetChannelOwner(Name, Owner);
if(m_permanent)
database.SetChannelOwner(m_name, m_owner);
}
// Returns the owner's name in type std::string()
std::string& ChatChannel::GetOwnerName() {
return m_owner;
}
void ChatChannel::SetTemporary() {
m_permanent = false;
}
void ChatChannel::SetPermanent() {
m_permanent = true;
}
void ChatChannel::AddClient(Client *c) {
if(!c) return;
DeleteTimer.Disable();
m_delete_timer.Disable();
if(IsClientInChannel(c)) {
@@ -247,9 +321,9 @@ void ChatChannel::AddClient(Client *c) {
int AccountStatus = c->GetAccountStatus();
LogDebug("Adding [{}] to channel [{}]", c->GetName().c_str(), Name.c_str());
LogDebug("Adding [{}] to channel [{}]", c->GetName().c_str(), m_name.c_str());
LinkedListIterator<Client*> iterator(ClientsInChannel);
LinkedListIterator<Client*> iterator(m_clients_in_channel);
iterator.Reset();
@@ -264,7 +338,7 @@ void ChatChannel::AddClient(Client *c) {
iterator.Advance();
}
ClientsInChannel.Insert(c);
m_clients_in_channel.Insert(c);
}
@@ -272,46 +346,46 @@ bool ChatChannel::RemoveClient(Client *c) {
if(!c) return false;
LogDebug("RemoveClient [{}] from channel [{}]", c->GetName().c_str(), GetName().c_str());
LogDebug("Remove client [{}] from channel [{}]", c->GetName().c_str(), GetName().c_str());
bool HideMe = c->GetHideMe();
bool hide_me = c->GetHideMe();
int AccountStatus = c->GetAccountStatus();
int account_status = c->GetAccountStatus();
int PlayersInChannel = 0;
int players_in_channel = 0;
LinkedListIterator<Client*> iterator(ClientsInChannel);
LinkedListIterator<Client*> iterator(m_clients_in_channel);
iterator.Reset();
while(iterator.MoreElements()) {
Client *CurrentClient = iterator.GetData();
auto *current_client = iterator.GetData();
if(CurrentClient == c) {
if(current_client == c) {
iterator.RemoveCurrent(false);
}
else if(CurrentClient) {
else if(current_client) {
PlayersInChannel++;
players_in_channel++;
if(CurrentClient->IsAnnounceOn())
if(!HideMe || (CurrentClient->GetAccountStatus() > AccountStatus))
CurrentClient->AnnounceLeave(this, c);
if(current_client->IsAnnounceOn())
if(!hide_me || (current_client->GetAccountStatus() > account_status))
current_client->AnnounceLeave(this, c);
iterator.Advance();
}
}
if((PlayersInChannel == 0) && !Permanent) {
if((players_in_channel == 0) && !m_permanent) {
if((Password.length() == 0) || (RuleI(Channels, DeleteTimer) == 0))
if((m_password.length() == 0) || (RuleI(Channels, DeleteTimer) == 0))
return false;
LogDebug("Starting delete timer for empty password protected channel [{}]", Name.c_str());
LogDebug("Starting delete timer for empty password protected channel [{}]", m_name.c_str());
DeleteTimer.Start(RuleI(Channels, DeleteTimer) * 60000);
m_delete_timer.Start(RuleI(Channels, DeleteTimer) * 60000);
}
return true;
@@ -322,9 +396,9 @@ void ChatChannel::SendOPList(Client *c)
if (!c)
return;
c->GeneralChannelMessage("Channel " + Name + " op-list: (Owner=" + Owner + ")");
c->GeneralChannelMessage("Channel " + m_name + " op-list: (Owner=" + m_owner + ")");
for (auto &&m : Moderators)
for (auto &&m : m_moderators)
c->GeneralChannelMessage(m);
}
@@ -350,7 +424,7 @@ void ChatChannel::SendChannelMembers(Client *c) {
int MembersInLine = 0;
LinkedListIterator<Client*> iterator(ClientsInChannel);
LinkedListIterator<Client*> iterator(m_clients_in_channel);
iterator.Reset();
@@ -389,7 +463,7 @@ void ChatChannel::SendChannelMembers(Client *c) {
}
void ChatChannel::SendMessageToChannel(std::string Message, Client* Sender) {
void ChatChannel::SendMessageToChannel(const std::string& Message, Client* Sender) {
if(!Sender) return;
@@ -397,40 +471,40 @@ void ChatChannel::SendMessageToChannel(std::string Message, Client* Sender) {
ChatMessagesSent++;
LinkedListIterator<Client*> iterator(ClientsInChannel);
LinkedListIterator<Client*> iterator(m_clients_in_channel);
iterator.Reset();
while(iterator.MoreElements()) {
Client *ChannelClient = iterator.GetData();
auto *channel_client = iterator.GetData();
if(ChannelClient)
if(channel_client)
{
LogDebug("Sending message to [{}] from [{}]",
ChannelClient->GetName().c_str(), Sender->GetName().c_str());
channel_client->GetName().c_str(), Sender->GetName().c_str());
if (cv_messages[static_cast<uint32>(ChannelClient->GetClientVersion())].length() == 0) {
switch (ChannelClient->GetClientVersion()) {
if (cv_messages[static_cast<uint32>(channel_client->GetClientVersion())].length() == 0) {
switch (channel_client->GetClientVersion()) {
case EQ::versions::ClientVersion::Titanium:
ServerToClient45SayLink(cv_messages[static_cast<uint32>(ChannelClient->GetClientVersion())], Message);
ServerToClient45SayLink(cv_messages[static_cast<uint32>(channel_client->GetClientVersion())], Message);
break;
case EQ::versions::ClientVersion::SoF:
case EQ::versions::ClientVersion::SoD:
case EQ::versions::ClientVersion::UF:
ServerToClient50SayLink(cv_messages[static_cast<uint32>(ChannelClient->GetClientVersion())], Message);
ServerToClient50SayLink(cv_messages[static_cast<uint32>(channel_client->GetClientVersion())], Message);
break;
case EQ::versions::ClientVersion::RoF:
ServerToClient55SayLink(cv_messages[static_cast<uint32>(ChannelClient->GetClientVersion())], Message);
ServerToClient55SayLink(cv_messages[static_cast<uint32>(channel_client->GetClientVersion())], Message);
break;
case EQ::versions::ClientVersion::RoF2:
default:
cv_messages[static_cast<uint32>(ChannelClient->GetClientVersion())] = Message;
cv_messages[static_cast<uint32>(channel_client->GetClientVersion())] = Message;
break;
}
}
ChannelClient->SendChannelMessage(Name, cv_messages[static_cast<uint32>(ChannelClient->GetClientVersion())], Sender);
channel_client->SendChannelMessage(m_name, cv_messages[static_cast<uint32>(channel_client->GetClientVersion())], Sender);
}
iterator.Advance();
@@ -439,9 +513,9 @@ void ChatChannel::SendMessageToChannel(std::string Message, Client* Sender) {
void ChatChannel::SetModerated(bool inModerated) {
Moderated = inModerated;
m_moderated = inModerated;
LinkedListIterator<Client*> iterator(ClientsInChannel);
LinkedListIterator<Client*> iterator(m_clients_in_channel);
iterator.Reset();
@@ -451,10 +525,10 @@ void ChatChannel::SetModerated(bool inModerated) {
if(ChannelClient) {
if(Moderated)
ChannelClient->GeneralChannelMessage("Channel " + Name + " is now moderated.");
if(m_moderated)
ChannelClient->GeneralChannelMessage("Channel " + m_name + " is now moderated.");
else
ChannelClient->GeneralChannelMessage("Channel " + Name + " is no longer moderated.");
ChannelClient->GeneralChannelMessage("Channel " + m_name + " is no longer moderated.");
}
iterator.Advance();
@@ -465,7 +539,7 @@ bool ChatChannel::IsClientInChannel(Client *c) {
if(!c) return false;
LinkedListIterator<Client*> iterator(ClientsInChannel);
LinkedListIterator<Client*> iterator(m_clients_in_channel);
iterator.Reset();
@@ -480,54 +554,80 @@ bool ChatChannel::IsClientInChannel(Client *c) {
return false;
}
ChatChannel *ChatChannelList::AddClientToChannel(std::string ChannelName, Client *c) {
ChatChannel *ChatChannelList::AddClientToChannel(std::string channel_name, Client *c, bool command_directed) {
if(!c) return nullptr;
if((ChannelName.length() > 0) && (isdigit(ChannelName[0]))) {
if ((channel_name.length() > 0) && (isdigit(channel_name[0]))) { // Ensure channel name does not start with a number
c->GeneralChannelMessage("The channel name can not begin with a number.");
return nullptr;
}
else if (channel_name.empty()) { // Ensure channel name is not empty
return nullptr;
}
std::string NormalisedName, Password;
std::string normalized_name, password;
std::string::size_type Colon = ChannelName.find_first_of(":");
std::string::size_type Colon = channel_name.find_first_of(":");
if(Colon == std::string::npos)
NormalisedName = CapitaliseName(ChannelName);
normalized_name = CapitaliseName(channel_name);
else {
NormalisedName = CapitaliseName(ChannelName.substr(0, Colon));
normalized_name = CapitaliseName(channel_name.substr(0, Colon));
Password = ChannelName.substr(Colon + 1);
password = channel_name.substr(Colon + 1);
}
if((NormalisedName.length() > 64) || (Password.length() > 64)) {
if((normalized_name.length() > 64) || (password.length() > 64)) {
c->GeneralChannelMessage("The channel name or password cannot exceed 64 characters.");
return nullptr;
}
LogDebug("AddClient to channel [[{}]] with password [[{}]]", NormalisedName.c_str(), Password.c_str());
ChatChannel *RequiredChannel = FindChannel(normalized_name);
ChatChannel *RequiredChannel = FindChannel(NormalisedName);
if (RequiredChannel) {
if (IsOnChannelBlockList(channel_name)) { // Ensure channel name is not blocked
if (!(RequiredChannel->GetOwnerName() == SYSTEM_OWNER)) {
c->GeneralChannelMessage("That channel name is blocked by the server operator.");
return nullptr;
}
else {
LogDebug("Reserved/blocked channel name check for [{}] ignored due to channel being owned by System...", normalized_name);
}
}
}
if(!RequiredChannel)
RequiredChannel = CreateChannel(NormalisedName, c->GetName(), Password, false, 0);
const std::string& channel_owner = c->GetName();
if(RequiredChannel->GetMinStatus() > c->GetAccountStatus()) {
bool permanent = false;
if (command_directed && RuleI(Chat, MaxPermanentPlayerChannels) > 0) {
permanent = true;
}
std::string Message = "You do not have the required account status to join channel " + NormalisedName;
if (!RequiredChannel) {
RequiredChannel = CreateChannel(normalized_name, channel_owner, password, permanent, 0, command_directed);
if (RequiredChannel == nullptr) {
LogDebug("Failed to create new channel with name: {}. Possible blocked or reserved channel name.", normalized_name);
c->GeneralChannelMessage("Failed to create new channel with provided name. Possible blocked or reserved channel name.");
return nullptr;
}
LogDebug("Created and added Client to channel [{}] with password [{}]. Owner: {}. Command Directed: {}", normalized_name.c_str(), password.c_str(), channel_owner, command_directed);
}
LogDebug("Checking status requirement of channel: {}. Channel status required: {}, player status: {}.", normalized_name, std::to_string(RequiredChannel->GetMinStatus()), std::to_string(c->GetAccountStatus()));
if (RequiredChannel->GetMinStatus() > c->GetAccountStatus()) {
std::string Message = "You do not have the required account status to join channel " + normalized_name;
c->GeneralChannelMessage(Message);
LogInfo("Client [{}] connection to channel [{}] refused due to insufficient status.", c->GetName(), normalized_name);
return nullptr;
}
if(RequiredChannel->IsClientInChannel(c))
if (RequiredChannel->IsClientInChannel(c)) {
return nullptr;
}
if(RequiredChannel->IsInvitee(c->GetName())) {
@@ -538,7 +638,7 @@ ChatChannel *ChatChannelList::AddClientToChannel(std::string ChannelName, Client
return RequiredChannel;
}
if(RequiredChannel->CheckPassword(Password) || RequiredChannel->IsOwner(c->GetName()) || RequiredChannel->IsModerator(c->GetName()) ||
if(RequiredChannel->CheckPassword(password) || RequiredChannel->IsOwner(c->GetName()) || RequiredChannel->IsModerator(c->GetName()) ||
c->IsChannelAdmin()) {
RequiredChannel->AddClient(c);
@@ -546,32 +646,42 @@ ChatChannel *ChatChannelList::AddClientToChannel(std::string ChannelName, Client
return RequiredChannel;
}
c->GeneralChannelMessage("Incorrect password for channel " + (NormalisedName));
c->GeneralChannelMessage("Incorrect password for channel " + (normalized_name));
return nullptr;
}
ChatChannel *ChatChannelList::RemoveClientFromChannel(std::string inChannelName, Client *c) {
ChatChannel *ChatChannelList::RemoveClientFromChannel(const std::string& in_channel_name, Client *c, bool command_directed) {
if(!c) return nullptr;
std::string ChannelName = inChannelName;
std::string channel_name = in_channel_name;
if((inChannelName.length() > 0) && isdigit(ChannelName[0]))
ChannelName = c->ChannelSlotName(atoi(inChannelName.c_str()));
if (in_channel_name.length() > 0 && isdigit(channel_name[0])) {
channel_name = c->ChannelSlotName(atoi(in_channel_name.c_str()));
}
ChatChannel *RequiredChannel = FindChannel(ChannelName);
auto *required_channel = FindChannel(channel_name);
if(!RequiredChannel)
if (!required_channel) {
return nullptr;
}
LogDebug("Client [{}] removed from channel [{}]. Channel is owned by {}. Command directed: {}", c->GetName(), channel_name, required_channel->GetOwnerName(), command_directed);
if (c->GetName() == required_channel->GetOwnerName() && command_directed) { // Check if the client that is leaving is the the channel owner
LogDebug("Owner left the channel [{}], removing channel from database...", channel_name);
database.DeleteChatChannel(channel_name); // Remove the channel from the database.
LogDebug("Flagging [{}] channel as temporary...", channel_name);
required_channel->SetTemporary();
}
// RemoveClient will return false if there is no-one left in the channel, and the channel is not permanent and has
// no password.
//
if(!RequiredChannel->RemoveClient(c))
RemoveChannel(RequiredChannel);
if (!required_channel->RemoveClient(c)) {
LogDebug("Noone left in the temporary channel [{}] and no password is set; removing temporary channel.", channel_name);
RemoveChannel(required_channel);
}
return RequiredChannel;
return required_channel;
}
void ChatChannelList::Process() {
@@ -600,76 +710,76 @@ void ChatChannelList::Process() {
void ChatChannel::AddInvitee(const std::string &Invitee)
{
if (!IsInvitee(Invitee)) {
Invitees.push_back(Invitee);
m_invitees.push_back(Invitee);
LogDebug("Added [{}] as invitee to channel [{}]", Invitee.c_str(), Name.c_str());
LogDebug("Added [{}] as invitee to channel [{}]", Invitee.c_str(), m_name.c_str());
}
}
void ChatChannel::RemoveInvitee(std::string Invitee)
{
auto it = std::find(std::begin(Invitees), std::end(Invitees), Invitee);
auto it = std::find(std::begin(m_invitees), std::end(m_invitees), Invitee);
if(it != std::end(Invitees)) {
Invitees.erase(it);
LogDebug("Removed [{}] as invitee to channel [{}]", Invitee.c_str(), Name.c_str());
if(it != std::end(m_invitees)) {
m_invitees.erase(it);
LogDebug("Removed [{}] as invitee to channel [{}]", Invitee.c_str(), m_name.c_str());
}
}
bool ChatChannel::IsInvitee(std::string Invitee)
{
return std::find(std::begin(Invitees), std::end(Invitees), Invitee) != std::end(Invitees);
return std::find(std::begin(m_invitees), std::end(m_invitees), Invitee) != std::end(m_invitees);
}
void ChatChannel::AddModerator(const std::string &Moderator)
{
if (!IsModerator(Moderator)) {
Moderators.push_back(Moderator);
m_moderators.push_back(Moderator);
LogInfo("Added [{}] as moderator to channel [{}]", Moderator.c_str(), Name.c_str());
LogInfo("Added [{}] as moderator to channel [{}]", Moderator.c_str(), m_name.c_str());
}
}
void ChatChannel::RemoveModerator(const std::string &Moderator)
{
auto it = std::find(std::begin(Moderators), std::end(Moderators), Moderator);
auto it = std::find(std::begin(m_moderators), std::end(m_moderators), Moderator);
if (it != std::end(Moderators)) {
Moderators.erase(it);
LogInfo("Removed [{}] as moderator to channel [{}]", Moderator.c_str(), Name.c_str());
if (it != std::end(m_moderators)) {
m_moderators.erase(it);
LogInfo("Removed [{}] as moderator to channel [{}]", Moderator.c_str(), m_name.c_str());
}
}
bool ChatChannel::IsModerator(std::string Moderator)
{
return std::find(std::begin(Moderators), std::end(Moderators), Moderator) != std::end(Moderators);
return std::find(std::begin(m_moderators), std::end(m_moderators), Moderator) != std::end(m_moderators);
}
void ChatChannel::AddVoice(const std::string &inVoiced)
{
if (!HasVoice(inVoiced)) {
Voiced.push_back(inVoiced);
m_voiced.push_back(inVoiced);
LogInfo("Added [{}] as voiced to channel [{}]", inVoiced.c_str(), Name.c_str());
LogInfo("Added [{}] as voiced to channel [{}]", inVoiced.c_str(), m_name.c_str());
}
}
void ChatChannel::RemoveVoice(const std::string &inVoiced)
{
auto it = std::find(std::begin(Voiced), std::end(Voiced), inVoiced);
auto it = std::find(std::begin(m_voiced), std::end(m_voiced), inVoiced);
if (it != std::end(Voiced)) {
Voiced.erase(it);
if (it != std::end(m_voiced)) {
m_voiced.erase(it);
LogInfo("Removed [{}] as voiced to channel [{}]", inVoiced.c_str(), Name.c_str());
LogInfo("Removed [{}] as voiced to channel [{}]", inVoiced.c_str(), m_name.c_str());
}
}
bool ChatChannel::HasVoice(std::string inVoiced)
{
return std::find(std::begin(Voiced), std::end(Voiced), inVoiced) != std::end(Voiced);
return std::find(std::begin(m_voiced), std::end(m_voiced), inVoiced) != std::end(m_voiced);
}
std::string CapitaliseName(std::string inString) {
@@ -687,6 +797,31 @@ std::string CapitaliseName(std::string inString) {
return NormalisedName;
}
bool ChatChannelList::IsOnChannelBlockList(const std::string& channel_name) {
if (channel_name.empty()) {
return false;
}
// Check if channel_name is already in the BlockedChannelNames vector
return Strings::Contains(ChatChannelList::GetBlockedChannelNames(), channel_name);
}
void ChatChannelList::AddToChannelBlockList(const std::string& channel_name) {
if (channel_name.empty()) {
return;
}
// Check if channelName is already in the BlockedChannelNames vector
bool is_found = Strings::Contains(ChatChannelList::GetBlockedChannelNames(), channel_name);
// Add channelName to the BlockedChannelNames vector if it is not already present
if (!is_found) {
auto blocked_channel_names = GetBlockedChannelNames(); // Get current blocked list
blocked_channel_names.push_back(channel_name); // Add new name to local blocked list
SetChannelBlockList(blocked_channel_names); // Set blocked list to match local blocked list
}
}
void ServerToClient45SayLink(std::string& clientSayLink, const std::string& serverSayLink) {
if (serverSayLink.find('\x12') == std::string::npos) {
clientSayLink = serverSayLink;