diff --git a/docs/JSON-RPC.md b/docs/JSON-RPC.md index 276ffed470..e9111187f4 100644 --- a/docs/JSON-RPC.md +++ b/docs/JSON-RPC.md @@ -344,7 +344,7 @@ Results: ### jamulusserver/broadcastChatMessage -Sends a message (as the server) to all connected clients. This can be used to broadcast messages from external sources (e.g. scripts or monitoring tools). +Sends a message (as the server) to all connected clients. This can be used to broadcast messages from external sources (e.g. scripts or monitoring tools). Parameters: @@ -430,6 +430,24 @@ Results: | result.registrationStatus | string | The server registration status as string (see ESvrRegStatus and SerializeRegistrationStatus). | +### jamulusserver/privateChatMessage + +Sends a chat message to a single connected client. + +Parameters: + +| Name | Type | Description | +| --- | --- | --- | +| params.chatMessage | string | The chat message text. | +| params.id | number | The client's channel id. | + +Results: + +| Name | Type | Description | +| --- | --- | --- | +| result | string | "ok" or "error" if bad arguments. | + + ### jamulusserver/restartRecording Restarts the recording into a new directory. diff --git a/src/server.cpp b/src/server.cpp index e44940c37d..ce2669cbf7 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -1379,13 +1379,15 @@ void CServer::SendChatTextToAllConChannels ( const int iSendingChanID, const QSt emit sentChatMessage ( iSendingChanID, strChatText ); } -void CServer::SendChatTextToConChannel ( const int iCurChanID, const QString& strChatText ) +bool CServer::SendChatTextToConChannel ( const int iCurChanID, const QString& strChatText ) { - if ( MathUtils::InRange ( iCurChanID, 0, iMaxNumChannels - 1 ) && vecChannels[iCurChanID].IsConnected() ) + if ( !MathUtils::InRange ( iCurChanID, 0, iMaxNumChannels - 1 ) || !vecChannels[iCurChanID].IsConnected() ) { - // send message - vecChannels[iCurChanID].CreateChatTextMes ( strChatText ); + return false; } + // send message + vecChannels[iCurChanID].CreateChatTextMes ( strChatText ); + return true; } void CServer::CreateAndSendRecorderStateForAllConChannels() diff --git a/src/server.h b/src/server.h index 1d828c86f5..b92f3f2656 100644 --- a/src/server.h +++ b/src/server.h @@ -192,7 +192,7 @@ class CServer : public QObject, public CServerSlots bool IsDelayPanningEnabled() { return bDelayPan; } void SendChatTextToAllConChannels ( const int iSendingChanID, const QString& strChatText ); - void SendChatTextToConChannel ( const int iCurChanID, const QString& strChatText ); + bool SendChatTextToConChannel ( const int iCurChanID, const QString& strChatText ); protected: // access functions for actual channels diff --git a/src/serverrpc.cpp b/src/serverrpc.cpp index 2511a88549..26db5257bb 100644 --- a/src/serverrpc.cpp +++ b/src/serverrpc.cpp @@ -113,6 +113,30 @@ CServerRpc::CServerRpc ( CServer* pServer, CRpcServer* pRpcServer, QObject* pare response["result"] = "ok"; } ); + /// @rpc_method jamulusserver/privateChatMessage + /// @brief Sends a chat message to a single connected client. + /// @param {string} params.chatMessage - The chat message text. + /// @param {number} params.id - The client's channel id. + /// @result {string} result - "ok" or "error" if bad arguments. + pRpcServer->HandleMethod ( "jamulusserver/privateChatMessage", [=] ( const QJsonObject& params, QJsonObject& response ) { + auto jsonChatMessage = params["chatMessage"]; + const int id = params["id"].toInt ( INVALID_CLIENT_ID ); + const QString chatMessage = jsonChatMessage.toString(); + if ( chatMessage.isEmpty() || chatMessage.size() > MAX_LEN_CHAT_TEXT ) + { + response["error"] = + CRpcServer::CreateJsonRpcError ( CRpcServer::iErrInvalidParams, "Invalid params: chatMessage is not a string or malformed" ); + return; + } + + if ( !pServer->SendChatTextToConChannel ( id, chatMessage ) ) + { + response["error"] = "invalid channel ID"; + return; + } + response["result"] = "ok"; + } ); + /// @rpc_method jamulusserver/getRecorderStatus /// @brief Returns the recorder state. /// @param {object} params - No parameters (empty object).