Implement kick
authorunc0rr
Tue, 21 Oct 2008 16:53:34 +0000
changeset 1391 735f6d43780b
parent 1390 914fa66aec05
child 1392 dc6a772ea385
Implement kick
QTfrontend/chatwidget.cpp
QTfrontend/chatwidget.h
QTfrontend/hwform.cpp
QTfrontend/newnetclient.cpp
QTfrontend/newnetclient.h
netserver/HWProto.hs
netserver/Miscutils.hs
netserver/hedgewars-server.hs
--- 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)) $