--- a/QTfrontend/chatwidget.cpp Tue Oct 21 13:39:34 2008 +0000
+++ b/QTfrontend/chatwidget.cpp Tue Oct 21 16:53:34 2008 +0000
@@ -18,6 +18,7 @@
#include <QListWidget>
#include <QLineEdit>
+#include <QAction>
#include "chatwidget.h"
@@ -46,7 +47,12 @@
chatNicks->setMinimumHeight(10);
chatNicks->setMinimumWidth(10);
chatNicks->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+ chatNicks->setContextMenuPolicy(Qt::ActionsContextMenu);
mainLayout.addWidget(chatNicks, 0, 1);
+
+ QAction * acBan = new QAction(QAction::tr("Kick"), chatNicks);
+ connect(acBan, SIGNAL(triggered(bool)), this, SLOT(onKick()));
+ chatNicks->insertAction(0, acBan);
}
void HWChatWidget::returnPressed()
@@ -65,12 +71,13 @@
void HWChatWidget::nickAdded(const QString& nick)
{
- chatNicks->addItem(nick);
+ QListWidgetItem * item = new QListWidgetItem(nick);
+ chatNicks->addItem(item);
}
void HWChatWidget::nickRemoved(const QString& nick)
{
- QList<QListWidgetItem *> items=chatNicks->findItems(nick, Qt::MatchExactly);
+ QList<QListWidgetItem *> items = chatNicks->findItems(nick, Qt::MatchExactly);
for(QList<QListWidgetItem *>::iterator it=items.begin(); it!=items.end();) {
chatNicks->takeItem(chatNicks->row(*it));
++it;
@@ -82,3 +89,10 @@
chatText->clear();
chatNicks->clear();
}
+
+void HWChatWidget::onKick()
+{
+ QListWidgetItem * curritem = chatNicks->currentItem();
+ if (curritem)
+ emit kick(curritem->text());
+}
--- a/QTfrontend/chatwidget.h Tue Oct 21 13:39:34 2008 +0000
+++ b/QTfrontend/chatwidget.h Tue Oct 21 16:53:34 2008 +0000
@@ -41,6 +41,7 @@
signals:
void chatLine(const QString& str);
+ void kick(const QString & str);
private:
QGridLayout mainLayout;
@@ -50,6 +51,7 @@
private slots:
void returnPressed();
+ void onKick();
};
#endif // _CHAT_WIDGET_INCLUDED
--- a/QTfrontend/hwform.cpp Tue Oct 21 13:39:34 2008 +0000
+++ b/QTfrontend/hwform.cpp Tue Oct 21 16:53:34 2008 +0000
@@ -439,6 +439,8 @@
ui.pageNetGame->pChatWidget, SLOT(onChatString(const QString&)));
connect(ui.pageNetGame->pChatWidget, SIGNAL(chatLine(const QString&)),
hwnet, SLOT(chatLineToNet(const QString&)));
+ connect(ui.pageNetGame->pChatWidget, SIGNAL(kick(const QString&)),
+ hwnet, SLOT(kickPlayer(const QString&)));
connect(hwnet, SIGNAL(nickAdded(const QString&)),
ui.pageNetGame->pChatWidget, SLOT(nickAdded(const QString&)));
connect(hwnet, SIGNAL(nickRemoved(const QString&)),
--- a/QTfrontend/newnetclient.cpp Tue Oct 21 13:39:34 2008 +0000
+++ b/QTfrontend/newnetclient.cpp Tue Oct 21 16:53:34 2008 +0000
@@ -524,3 +524,8 @@
else
return QString("%1: %2").arg(nick).arg(msg);
}
+
+void HWNewNet::kickPlayer(const QString & nick)
+{
+ RawSendNet(QString("KICK%1%2").arg(delimeter).arg(nick));
+}
--- a/QTfrontend/newnetclient.h Tue Oct 21 13:39:34 2008 +0000
+++ b/QTfrontend/newnetclient.h Tue Oct 21 16:53:34 2008 +0000
@@ -130,6 +130,7 @@
void CreateRoom(const QString & room);
void askRoomsList();
void gameFinished();
+ void kickPlayer(const QString &);
private slots:
void ClientRead();
--- a/netserver/HWProto.hs Tue Oct 21 13:39:34 2008 +0000
+++ b/netserver/HWProto.hs Tue Oct 21 16:53:34 2008 +0000
@@ -238,4 +238,18 @@
handleCmd_inRoom client _ _ ["GAMEMSG", msg] =
(noChangeClients, noChangeRooms, [(othersInRoom, ["GAMEMSG", msg])])
+handleCmd_inRoom client clients rooms ["KICK", kickNick] =
+ if isMaster client then
+ if noSuchClient || (kickClient == client) then
+ (noChangeClients, noChangeRooms, [])
+ else
+ (modifyClient kickClient{forceQuit = True}, noChangeRooms, [])
+ else
+ (noChangeClients, noChangeRooms, [])
+ where
+ clRoom = roomByName (room client) rooms
+ noSuchClient = isNothing findClient
+ kickClient = fromJust findClient
+ findClient = find (\t -> ((room t) == (room client)) && ((nick t) == kickNick)) $ clients
+
handleCmd_inRoom _ _ _ _ = (noChangeClients, noChangeRooms, answerBadCmd)
--- a/netserver/Miscutils.hs Tue Oct 21 13:39:34 2008 +0000
+++ b/netserver/Miscutils.hs Tue Oct 21 16:53:34 2008 +0000
@@ -16,7 +16,8 @@
nick :: String,
protocol :: Word16,
room :: String,
- isMaster :: Bool
+ isMaster :: Bool,
+ forceQuit :: Bool
}
instance Eq ClientInfo where
--- a/netserver/hedgewars-server.hs Tue Oct 21 13:39:34 2008 +0000
+++ b/netserver/hedgewars-server.hs Tue Oct 21 16:53:34 2008 +0000
@@ -7,7 +7,7 @@
import Control.Concurrent.STM
import Control.Exception (setUncaughtExceptionHandler, handle, finally)
import Control.Monad (forM, forM_, filterM, liftM, when, unless)
-import Maybe (fromMaybe)
+import Maybe (fromMaybe, isJust, fromJust)
import Data.List
import Miscutils
import HWProto
@@ -20,7 +20,7 @@
hFlush cHandle
cChan <- atomically newTChan
forkIO $ clientLoop cHandle cChan
- atomically $ writeTChan acceptChan (ClientInfo cChan cHandle "" 0 "" False)
+ atomically $ writeTChan acceptChan (ClientInfo cChan cHandle "" 0 "" False False)
acceptLoop servSock acceptChan
@@ -61,6 +61,20 @@
remove list rmClHandles = deleteFirstsBy2t (\ a b -> (Miscutils.handle a) == b) list rmClHandles
+reactCmd :: [String] -> ClientInfo -> [ClientInfo] -> [RoomInfo] -> IO ([ClientInfo], [RoomInfo])
+reactCmd cmd client clients rooms = do
+ putStrLn ("> " ++ show cmd)
+
+ let (clientsFunc, roomsFunc, answers) = handleCmd client clients rooms $ cmd
+ let mrooms = roomsFunc rooms
+ let mclients = (clientsFunc clients)
+ let mclient = fromMaybe client $ find (== client) mclients
+
+ clientsIn <- sendAnswers answers mclient mclients mrooms
+ let quitClient = find forceQuit $ clientsIn
+ if isJust quitClient then reactCmd ["QUIT"] (fromJust quitClient) clientsIn mrooms else return (clientsIn, mrooms)
+
+
mainLoop :: Socket -> TChan ClientInfo -> [ClientInfo] -> [RoomInfo] -> IO ()
mainLoop servSock acceptChan clients rooms = do
r <- atomically $ (Left `fmap` readTChan acceptChan) `orElse` (Right `fmap` tselect clients)
@@ -68,14 +82,7 @@
Left ci -> do
mainLoop servSock acceptChan (clients ++ [ci]) rooms
Right (cmd, client) -> do
- putStrLn ("> " ++ show cmd)
-
- let (clientsFunc, roomsFunc, answers) = handleCmd client clients rooms $ cmd
- let mrooms = roomsFunc rooms
- let mclients = (clientsFunc clients)
- let mclient = fromMaybe client $ find (== client) mclients
-
- clientsIn <- sendAnswers answers mclient mclients mrooms
+ (clientsIn, mrooms) <- reactCmd cmd client clients rooms
let hadRooms = (not $ null rooms) && (null mrooms)
in unless ((not $ isDedicated globalOptions) && ((null clientsIn) || hadRooms)) $