- Proper /team command implementation
authorunc0rr
Sat, 03 Oct 2009 09:35:14 +0000
changeset 2403 6c5d504af2ba
parent 2402 edd12b259e7c
child 2404 8281eea32196
- Proper /team command implementation - Many fixes for chat bugs in engine, frontend and server
QTfrontend/game.cpp
QTfrontend/game.h
QTfrontend/hwform.cpp
QTfrontend/newnetclient.cpp
QTfrontend/newnetclient.h
gameServer/Actions.hs
gameServer/CoreTypes.hs
gameServer/HWProtoInRoomState.hs
gameServer/NetRoutines.hs
gameServer/Utils.hs
hedgewars/CCHandlers.inc
hedgewars/uChat.pas
hedgewars/uIO.pas
--- a/QTfrontend/game.cpp	Fri Oct 02 18:56:54 2009 +0000
+++ b/QTfrontend/game.cpp	Sat Oct 03 09:35:14 2009 +0000
@@ -224,9 +224,16 @@
 			int size = msg.size();
 			QString msgbody = QString::fromUtf8(msg.mid(2).left(size - 4));
 			emit SendChat(msgbody);
-			QByteArray buf;
-			HWProto::addStringToBuffer(buf, QString("s%1: %2\x20\x20").arg(config->netNick()).arg(msgbody));
-			demo.append(buf);
+			// FIXME: /me command doesn't work here
+			//QByteArray buf;
+			//HWProto::addStringToBuffer(buf, QString("s\x01%1: %2\x20\x20").arg(config->netNick()).arg(msgbody));
+			//demo.append(buf);
+			break;
+		}
+		case 'b': {
+			int size = msg.size();
+			QString msgbody = QString::fromUtf8(msg.mid(2).left(size - 4));
+			emit SendTeamMessage(msgbody);
 			break;
 		}
 		default: {
--- a/QTfrontend/game.h	Fri Oct 02 18:56:54 2009 +0000
+++ b/QTfrontend/game.h	Sat Oct 03 09:35:14 2009 +0000
@@ -60,6 +60,7 @@
 signals:
 	void SendNet(const QByteArray & msg);
 	void SendChat(const QString & msg);
+	void SendTeamMessage(const QString & msg);
 	void GameStateChanged(GameState gameState);
 	void GameStats(char type, const QString & info);
 	void HaveRecord(bool isDemo, const QByteArray & record);
--- a/QTfrontend/hwform.cpp	Fri Oct 02 18:56:54 2009 +0000
+++ b/QTfrontend/hwform.cpp	Sat Oct 03 09:35:14 2009 +0000
@@ -873,6 +873,7 @@
 
 	connect(game, SIGNAL(SendNet(const QByteArray &)), hwnet, SLOT(SendNet(const QByteArray &)));
 	connect(game, SIGNAL(SendChat(const QString &)), hwnet, SLOT(chatLineToNet(const QString &)));
+	connect(game, SIGNAL(SendTeamMessage(const QString &)), hwnet, SLOT(SendTeamMessage(const QString &)));
 	connect(hwnet, SIGNAL(FromNet(const QByteArray &)), game, SLOT(FromNet(const QByteArray &)));
 	connect(hwnet, SIGNAL(chatStringFromNet(const QString &)), game, SLOT(FromNetChat(const QString &)));
 
--- a/QTfrontend/newnetclient.cpp	Fri Oct 02 18:56:54 2009 +0000
+++ b/QTfrontend/newnetclient.cpp	Sat Oct 03 09:35:14 2009 +0000
@@ -605,6 +605,11 @@
 	}
 }
 
+void HWNewNet::SendTeamMessage(const QString& str)
+{
+	RawSendNet(QString("TEAMCHAT") + delimeter + str);
+}
+
 void HWNewNet::askRoomsList()
 {
 	if(netClientState != 2)
--- a/QTfrontend/newnetclient.h	Fri Oct 02 18:56:54 2009 +0000
+++ b/QTfrontend/newnetclient.h	Sat Oct 03 09:35:14 2009 +0000
@@ -122,6 +122,7 @@
   void ToggleReady();
   void chatLineToNet(const QString& str);
   void chatLineToLobby(const QString& str);
+  void SendTeamMessage(const QString& str);
   void SendNet(const QByteArray & buf);
   void AddTeam(const HWTeam & team);
   void RemoveTeam(const HWTeam& team);
--- a/gameServer/Actions.hs	Fri Oct 02 18:56:54 2009 +0000
+++ b/gameServer/Actions.hs	Sat Oct 03 09:35:14 2009 +0000
@@ -19,6 +19,7 @@
 	| AnswerAllOthers [String]
 	| AnswerThisRoom [String]
 	| AnswerOthersInRoom [String]
+	| AnswerSameClan [String]
 	| AnswerLobby [String]
 	| SendServerMessage
 	| RoomAddThisClient Int -- roomID
@@ -35,6 +36,7 @@
 	| BanClient String -- nick
 	| RemoveClientTeams Int -- clID
 	| ModifyClient (ClientInfo -> ClientInfo)
+	| ModifyClient2 Int (ClientInfo -> ClientInfo)
 	| ModifyRoom (RoomInfo -> RoomInfo)
 	| ModifyServerInfo (ServerInfo -> ServerInfo)
 	| AddRoom String String
@@ -64,13 +66,13 @@
 
 
 processAction (clID, serverInfo, clients, rooms) (AnswerAllOthers msg) = do
-	mapM_ (\id -> writeChan (sendChan $ clients ! id) msg) $
+	mapM_ (\id' -> writeChan (sendChan $ clients ! id') msg) $
 		Prelude.filter (\id' -> (id' /= clID) && logonPassed (clients ! id')) (keys clients)
 	return (clID, serverInfo, clients, rooms)
 
 
 processAction (clID, serverInfo, clients, rooms) (AnswerThisRoom msg) = do
-	mapM_ (\id -> writeChan (sendChan $ clients ! id) msg) roomClients
+	mapM_ (\id' -> writeChan (sendChan $ clients ! id') msg) roomClients
 	return (clID, serverInfo, clients, rooms)
 	where
 		roomClients = IntSet.elems $ playersIDs room
@@ -80,7 +82,7 @@
 
 
 processAction (clID, serverInfo, clients, rooms) (AnswerOthersInRoom msg) = do
-	mapM_ (\id -> writeChan (sendChan $ clients ! id) msg) $ Prelude.filter (/= clID) roomClients
+	mapM_ (\id' -> writeChan (sendChan $ clients ! id') msg) $ Prelude.filter (/= clID) roomClients
 	return (clID, serverInfo, clients, rooms)
 	where
 		roomClients = IntSet.elems $ playersIDs room
@@ -90,13 +92,25 @@
 
 
 processAction (clID, serverInfo, clients, rooms) (AnswerLobby msg) = do
-	mapM_ (\id -> writeChan (sendChan $ clients ! id) msg) roomClients
+	mapM_ (\id' -> writeChan (sendChan $ clients ! id') msg) roomClients
 	return (clID, serverInfo, clients, rooms)
 	where
 		roomClients = IntSet.elems $ playersIDs room
 		room = rooms ! 0
 
 
+processAction (clID, serverInfo, clients, rooms) (AnswerSameClan msg) = do
+	mapM_ (\cl -> writeChan (sendChan cl) msg) sameClanClients
+	return (clID, serverInfo, clients, rooms)
+	where
+		otherRoomClients = Prelude.map ((!) clients) $ IntSet.elems $ clID `IntSet.delete` (playersIDs room)
+		sameClanClients = Prelude.filter (\cl -> teamsInGame cl > 0 && clientClan cl == thisClan) otherRoomClients
+		thisClan = clientClan client
+		room = rooms ! rID
+		rID = roomID client
+		client = clients ! clID
+
+
 processAction (clID, serverInfo, clients, rooms) SendServerMessage = do
 	writeChan (sendChan $ clients ! clID) ["SERVER_MESSAGE", message serverInfo]
 	return (clID, serverInfo, clients, rooms)
@@ -163,6 +177,10 @@
 	return (clID, serverInfo, adjust func clID clients, rooms)
 
 
+processAction (clID, serverInfo, clients, rooms) (ModifyClient2 cl2ID func) =
+	return (clID, serverInfo, adjust func cl2ID clients, rooms)
+
+
 processAction (clID, serverInfo, clients, rooms) (ModifyRoom func) =
 	return (clID, serverInfo, clients, adjust func rID rooms)
 	where
--- a/gameServer/CoreTypes.hs	Fri Oct 02 18:56:54 2009 +0000
+++ b/gameServer/CoreTypes.hs	Sat Oct 03 09:35:14 2009 +0000
@@ -30,6 +30,7 @@
 		isMaster :: Bool,
 		isReady :: Bool,
 		isAdministrator :: Bool,
+		clientClan :: String,
 		teamsInGame :: Word
 	}
 
@@ -47,6 +48,7 @@
 data TeamInfo =
 	TeamInfo
 	{
+		teamownerId :: !Int,
 		teamowner :: String,
 		teamname :: String,
 		teamcolor :: String,
--- a/gameServer/HWProtoInRoomState.hs	Fri Oct 02 18:56:54 2009 +0000
+++ b/gameServer/HWProtoInRoomState.hs	Sat Oct 03 09:35:14 2009 +0000
@@ -6,6 +6,7 @@
 import Data.Sequence(Seq, (|>), (><), fromList, empty)
 import Data.List
 import Maybe
+import qualified Codec.Binary.UTF8.String as UTF8
 --------------------------------------
 import CoreTypes
 import Actions
@@ -49,7 +50,7 @@
 	| isRestrictedTeams room = [Warning "restricted"]
 	| otherwise =
 		[ModifyRoom (\r -> r{teams = teams r ++ [newTeam]}),
-		ModifyClient (\c -> c{teamsInGame = teamsInGame c + 1}),
+		ModifyClient (\c -> c{teamsInGame = teamsInGame c + 1, clientClan = color}),
 		AnswerThisClient ["TEAM_ACCEPTED", name],
 		AnswerOthersInRoom $ teamToNet newTeam,
 		AnswerOthersInRoom ["TEAM_COLOR", name, color]
@@ -59,7 +60,7 @@
 		room = rooms IntMap.! (roomID client)
 		canAddNumber = 48 - (sum . map hhnum $ teams room)
 		findTeam = find (\t -> name == teamname t) $ teams room
-		newTeam = (TeamInfo (nick client) name color grave fort voicepack difficulty newTeamHHNum (hhsList hhsInfo))
+		newTeam = (TeamInfo clID (nick client) name color grave fort voicepack difficulty newTeamHHNum (hhsList hhsInfo))
 		difficulty = fromMaybe 0 (maybeRead difStr :: Maybe Int)
 		hhsList [] = []
 		hhsList (n:h:hhs) = HedgehogInfo n h : hhsList hhs
@@ -101,7 +102,8 @@
 	| not $ isMaster client = [ProtocolError "Not room master"]
 	| noSuchTeam = []
 	| otherwise = [ModifyRoom $ modifyTeam team{teamcolor = newColor},
-			AnswerOthersInRoom ["TEAM_COLOR", teamName, newColor]]
+			AnswerOthersInRoom ["TEAM_COLOR", teamName, newColor],
+			ModifyClient2 (teamownerId team) (\c -> c{clientClan = newColor})]
 	where
 		noSuchTeam = isNothing findTeam
 		team = fromJust findTeam
@@ -191,4 +193,14 @@
 		kickID = clientUID kickClient
 
 
+handleCmd_inRoom clID clients _ ["TEAMCHAT", msg] =
+	if (teamsInGame client > 0) then
+		[AnswerSameClan ["EM", engineMsg]]
+	else
+		[]
+	where
+		client = clients IntMap.! clID
+		engineMsg = toEngineMsg $ 'b' : (nick client ++ "(team): " ++ decodedMsg ++ "\x20\x20")
+		decodedMsg = UTF8.decodeString msg
+
 handleCmd_inRoom clID _ _ _ = [ProtocolError "Incorrect command (state: in room)"]
--- a/gameServer/NetRoutines.hs	Fri Oct 02 18:56:54 2009 +0000
+++ b/gameServer/NetRoutines.hs	Sat Oct 03 09:35:14 2009 +0000
@@ -46,6 +46,7 @@
 					False
 					False
 					undefined
+					undefined
 					)
 
 		writeChan coreChan $ Accept newClient
--- a/gameServer/Utils.hs	Fri Oct 02 18:56:54 2009 +0000
+++ b/gameServer/Utils.hs	Sat Oct 03 09:35:14 2009 +0000
@@ -28,7 +28,9 @@
 		$ concatMap (\n -> (\(a, b) -> [showHex a, showHex b]) $ divMod n 65536) [a, b, c, d]) []
 
 toEngineMsg :: String -> String
-toEngineMsg msg = Base64.encode (fromIntegral (length msg) : (UTF8.encode msg))
+toEngineMsg msg = Base64.encode (fromIntegral (length encodedMsg) : encodedMsg)
+	where
+	encodedMsg = UTF8.encode msg
 
 fromEngineMsg :: String -> Maybe String
 fromEngineMsg msg = liftM (map w2c) (Base64.decode msg >>= removeLength)
--- a/hedgewars/CCHandlers.inc	Fri Oct 02 18:56:54 2009 +0000
+++ b/hedgewars/CCHandlers.inc	Sat Oct 03 09:35:14 2009 +0000
@@ -347,7 +347,7 @@
 begin
 SendIPC('b' + s);
 
-s[1]:= #4;
+s:= #4 + UserNick + '(team): ' + s;
 
 AddChatString(s)
 end;
--- a/hedgewars/uChat.pas	Fri Oct 02 18:56:54 2009 +0000
+++ b/hedgewars/uChat.pas	Sat Oct 03 09:35:14 2009 +0000
@@ -206,7 +206,7 @@
 
 if copy(s, 1, 6) = '/team ' then
     begin
-    ParseCommand('/team ' + char(LocalClan) + UserNick + '(team): '+copy(s, 7, Length(s)-6), true);
+    ParseCommand(s, true);
     exit
     end;
 if (s[1] = '/') and (copy(s, 1, 4) <> '/me ') then
--- a/hedgewars/uIO.pas	Fri Oct 02 18:56:54 2009 +0000
+++ b/hedgewars/uIO.pas	Sat Oct 03 09:35:14 2009 +0000
@@ -294,6 +294,11 @@
 			AddChatString(s);
 			WriteLnToConsole(s)
 			end;
+		'b': begin
+			s:= copy(headcmd^.str, 2, Pred(headcmd^.len));
+			AddChatString(#4 + s);
+			WriteLnToConsole(s)
+			end;
 		'F': TeamGone(copy(headcmd^.str, 2, Pred(headcmd^.len)));
 		'N': begin
 			tmpflag:= false;
@@ -312,12 +317,6 @@
 		't': ParseCommand('taunt ' + headcmd^.str[2], true);
 		'g': ParseCommand('newgrave', true);
 		'h': ParseCommand('hogsay ' + copy(headcmd^.str, 2, Pred(headcmd^.len)), true);
-		'b': if LocalClan = byte(headcmd^.str[2]) then
-               begin
-               s:= copy(headcmd^.str, 3, Pred(headcmd^.len));
-               AddChatString(#4 + s);
-               WriteLnToConsole(s)
-               end;
 		'1'..'5': ParseCommand('timer ' + headcmd^.cmd, true);
 		#128..char(128 + cMaxSlotIndex): ParseCommand('slot ' + char(byte(headcmd^.cmd) - 79), true)
 		else