summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bouncer/core.h1
-rw-r--r--bouncer/ircserver.cpp15
-rw-r--r--bouncer/window.cpp30
-rw-r--r--python_client.py66
4 files changed, 74 insertions, 38 deletions
diff --git a/bouncer/core.h b/bouncer/core.h
index b5d3164..7236ff7 100644
--- a/bouncer/core.h
+++ b/bouncer/core.h
@@ -302,6 +302,7 @@ public:
uint32_t getUserFlagByPrefix(char prefix) const;
uint32_t getUserFlagByMode(char mode) const;
int getChannelModeType(char mode) const;
+ char getEffectivePrefixChar(uint32_t modes) const;
IRCServer(Bouncer *_bouncer);
~IRCServer();
diff --git a/bouncer/ircserver.cpp b/bouncer/ircserver.cpp
index 31cbd6d..f13a481 100644
--- a/bouncer/ircserver.cpp
+++ b/bouncer/ircserver.cpp
@@ -391,3 +391,18 @@ int IRCServer::getChannelModeType(char mode) const {
return 0;
}
+
+char IRCServer::getEffectivePrefixChar(uint32_t modes) const {
+ uint32_t flag = 1;
+ const char *prefixes = serverPrefix;
+
+ while (*prefixes != 0) {
+ if (modes & flag)
+ return *prefixes;
+
+ ++prefixes;
+ flag <<= 1;
+ }
+
+ return 0;
+}
diff --git a/bouncer/window.cpp b/bouncer/window.cpp
index c971046..bf50325 100644
--- a/bouncer/window.cpp
+++ b/bouncer/window.cpp
@@ -152,6 +152,7 @@ void Channel::syncStateForClient(Buffer &output) {
for (auto &i : users) {
output.writeStr(i.first.c_str());
output.writeU32(i.second);
+ output.writeU8(server->getEffectivePrefixChar(i.second));
}
output.writeStr(topic.c_str());
@@ -196,9 +197,9 @@ void Channel::handleNameReply(const char *str) {
users[name] = modes;
nameCount++;
- //packet.writeU8(getEffectivePrefixChar(name));
packet.writeStr(name);
packet.writeU32(modes);
+ packet.writeU8(server->getEffectivePrefixChar(modes));
// Get the next name
name = strtok_r(NULL, " ", &strtok_var);
@@ -233,6 +234,7 @@ void Channel::handleJoin(const UserRef &user) {
packet.writeU32(1);
packet.writeStr(user.nick.c_str());
packet.writeU32(0);
+ packet.writeU8(0);
server->bouncer->sendToClients(
Packet::B2C_CHANNEL_USER_ADD, packet);
@@ -372,13 +374,21 @@ void Channel::handleMode(const UserRef &user, const char *str) {
// Oops? Spit out an error...
oops = true;
} else {
- // TODO: push mode change to clients
uint32_t flags = i->second;
if (addFlag)
flags |= flag;
else
flags &= ~flag;
users[target] = flags;
+
+ Buffer packet;
+ packet.writeU32(id);
+ packet.writeStr(target);
+ packet.writeU32(flags);
+ packet.writeU8(server->getEffectivePrefixChar(flags));
+
+ server->bouncer->sendToClients(
+ Packet::B2C_CHANNEL_USER_MODES, packet);
}
char buf[1024];
@@ -442,21 +452,7 @@ char Channel::getEffectivePrefixChar(const char *nick) const {
if (i == users.end())
return 0;
- // Maybe this bit would work best as an IRCServer method?
-
- uint32_t modes = i->second;
- uint32_t flag = 1;
- char *prefixes = server->serverPrefix;
-
- while (*prefixes != 0) {
- if (modes & flag)
- return *prefixes;
-
- ++prefixes;
- flag <<= 1;
- }
-
- return 0;
+ return server->getEffectivePrefixChar(i->second);
}
diff --git a/python_client.py b/python_client.py
index 39411c5..11c4a50 100644
--- a/python_client.py
+++ b/python_client.py
@@ -162,10 +162,25 @@ class WindowTab(QtWidgets.QWidget):
self.output.setTextCursor(cursor)
class ChannelTab(WindowTab):
+ class UserEntry:
+ def __init__(self, nick, prefix, modes, listwidget):
+ self.nick = nick
+ self.prefix = prefix
+ self.modes = modes
+ self.item = QtWidgets.QListWidgetItem('', listwidget)
+ self.syncItemText()
+
+ def syncItemText(self):
+ if self.prefix == 0:
+ self.item.setText(self.nick)
+ else:
+ self.item.setText(chr(self.prefix) + self.nick)
+
def __init__(self, parent=None):
WindowTab.__init__(self, parent)
self.userList = QtWidgets.QListWidget(self)
+ self.users = {}
def makeLayout(self):
sublayout = QtWidgets.QVBoxLayout()
@@ -180,7 +195,7 @@ class ChannelTab(WindowTab):
userCount = u32.unpack_from(pdata, pos)[0]
pos += 4
- users = []
+ users = {}
for i in range(userCount):
#prefix = pdata[pos]
#pos += 1
@@ -190,9 +205,10 @@ class ChannelTab(WindowTab):
pos += nicklen
modes = u32.unpack_from(pdata, pos)[0]
pos += 4
- users.append(nick)
- #self.userList.addItem(chr(prefix)+nick)
- self.userList.addItem(nick)
+ prefix = pdata[pos]
+ pos += 1
+
+ users[nick] = self.UserEntry(nick, prefix, modes, self.userList)
self.users = users
@@ -214,14 +230,16 @@ class ChannelTab(WindowTab):
pos += nicklen
modes = u32.unpack_from(pdata, pos)[0]
pos += 4
- self.users.append(nick)
- self.userList.addItem(nick)
+ prefix = pdata[pos]
+ pos += 1
+
+ self.users[nick] = self.UserEntry(nick, prefix, modes, self.userList)
def removeUsers(self, pdata):
userCount = u32.unpack_from(pdata, 4)[0]
pos = 8
if userCount == 0:
- self.users = []
+ self.users = {}
self.userList.clear()
else:
for i in range(userCount):
@@ -231,9 +249,10 @@ class ChannelTab(WindowTab):
pos += nicklen
print('Removing [%s]' % repr(nick))
- self.users.remove(nick)
- items = self.userList.findItems(nick, QtCore.Qt.MatchExactly)
- self.userList.takeItem(self.userList.row(items[0]))
+ uo = self.users[nick]
+ self.userList.takeItem(self.userList.row(uo.item))
+
+ del self.users[nick]
def renameUser(self, pdata):
pos = 4
@@ -245,20 +264,25 @@ class ChannelTab(WindowTab):
pos += 4
tonick = pdata[pos:pos+nicklen].decode('utf-8', 'replace')
- try:
- idx = self.users.index(fromnick)
- except ValueError:
- self.pushMessage('Crap, [%s] was not found in the users list!' % fromnick)
- return
-
- self.users[idx] = tonick
+ uo = self.users[fromnick]
+ del self.users[fromnick]
+ self.users[tonick] = uo
- items = self.userList.findItems(fromnick, QtCore.Qt.MatchExactly)
- items[0].setText(tonick)
+ uo.nick = tonick
+ uo.syncItemText()
def changeUserMode(self, pdata):
- # boop
- pass
+ pos = 4
+ nicklen = u32.unpack_from(pdata, pos)[0]
+ pos += 4
+ nick = pdata[pos:pos+nicklen].decode('utf-8', 'replace')
+ pos += nicklen
+ modes, prefix = struct.unpack_from('<IB', pdata, pos)
+
+ uo = self.users[nick]
+ uo.modes = modes
+ uo.prefix = prefix
+ uo.syncItemText()
class MainWindow(QtWidgets.QMainWindow):