summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/configreader.h4
-rw-r--r--include/users.h4
-rw-r--r--src/configreader.cpp1
-rw-r--r--src/modes/cmode_v.cpp4
-rw-r--r--src/users.cpp11
5 files changed, 23 insertions, 1 deletions
diff --git a/include/configreader.h b/include/configreader.h
index fb187048b..3759e909f 100644
--- a/include/configreader.h
+++ b/include/configreader.h
@@ -429,6 +429,10 @@ class CoreExport ServerConfig : public Extensible
*/
bool AllowHalfop;
+ /** If this value is true, users are allowed to devoice themselves.
+ */
+ bool AllowDevoiceSelf;
+
/** If this is set to true, then mode lists (e.g
* MODE #chan b) are hidden from unprivileged
* users.
diff --git a/include/users.h b/include/users.h
index 3d98f9632..b9b23eaef 100644
--- a/include/users.h
+++ b/include/users.h
@@ -655,6 +655,10 @@ class CoreExport User : public connection
* GetIPString/GetPort to obtain its values.
*/
sockaddr* ip;
+
+ /** Set by GetIPString() to avoid constantly re-grabbing IP via sockets voodoo.
+ */
+ std::string cachedip;
/** Initialize the clients sockaddr
* @param protocol_family The protocol family of the IP address, AF_INET or AF_INET6
diff --git a/src/configreader.cpp b/src/configreader.cpp
index 945780a54..dea6a7a7d 100644
--- a/src/configreader.cpp
+++ b/src/configreader.cpp
@@ -830,6 +830,7 @@ void ServerConfig::Read(bool bail, User* user, int pass)
{"options", "netbuffersize","10240", new ValueContainerInt (&this->NetBufferSize), DT_INTEGER, ValidateNetBufferSize},
{"options", "maxwho", "128", new ValueContainerInt (&this->MaxWhoResults), DT_INTEGER, ValidateMaxWho},
{"options", "allowhalfop", "0", new ValueContainerBool (&this->AllowHalfop), DT_BOOLEAN, NoValidation},
+ {"options", "allowdevoiceself", "0", new ValueContainerBool (&this->AllowDevoiceSelf), DT_BOOLEAN, NoValidation},
{"dns", "server", "", new ValueContainerChar (this->DNSServer), DT_IPADDRESS,DNSServerValidator},
{"dns", "timeout", "5", new ValueContainerInt (&this->dns_timeout), DT_INTEGER, NoValidation},
{"options", "moduledir", MOD_PATH, new ValueContainerChar (this->ModPath), DT_CHARPTR, NoValidation},
diff --git a/src/modes/cmode_v.cpp b/src/modes/cmode_v.cpp
index 66e58a479..8b94caf08 100644
--- a/src/modes/cmode_v.cpp
+++ b/src/modes/cmode_v.cpp
@@ -136,7 +136,9 @@ std::string ModeChannelVoice::DelVoice(User *user,const char *dest,Channel *chan
return "";
if (MOD_RESULT == ACR_DEFAULT)
{
- if ((status < STATUS_HOP) && (!ServerInstance->ULine(user->server)))
+ if ((status < STATUS_HOP) && (!ServerInstance->ULine(user->server)) ||
+ user == d && ServerInstance->Config->AllowDevoiceSelf
+ )
{
user->WriteServ("482 %s %s :You are not a channel (half)operator",user->nick, chan->name);
return "";
diff --git a/src/users.cpp b/src/users.cpp
index 6b2aebfc7..7847d8281 100644
--- a/src/users.cpp
+++ b/src/users.cpp
@@ -926,6 +926,8 @@ bool User::ForceNickChange(const char* newnick)
void User::SetSockAddr(int protocol_family, const char* ip, int port)
{
+ this->cachedip = "";
+
switch (protocol_family)
{
#ifdef SUPPORT_IP6LINKS
@@ -1001,6 +1003,9 @@ const char* User::GetIPString()
if (this->ip == NULL)
return "";
+ if (!this->cachedip.empty())
+ return this->cachedip.c_str();
+
switch (this->GetProtocolFamily())
{
#ifdef SUPPORT_IP6LINKS
@@ -1015,8 +1020,11 @@ const char* User::GetIPString()
{
strlcpy(&temp[1], buf, sizeof(temp) - 1);
*temp = '0';
+ this->cachedip = temp;
return temp;
}
+
+ this->cachedip = buf;
return buf;
}
break;
@@ -1025,12 +1033,15 @@ const char* User::GetIPString()
{
sockaddr_in* sin = (sockaddr_in*)this->ip;
inet_ntop(sin->sin_family, &sin->sin_addr, buf, sizeof(buf));
+ this->cachedip = buf;
return buf;
}
break;
default:
break;
}
+
+ // Unreachable, probably
return "";
}