diff --git a/docs/JSON-RPC.md b/docs/JSON-RPC.md
index cfe8dfbe3e..bff0bfc92e 100644
--- a/docs/JSON-RPC.md
+++ b/docs/JSON-RPC.md
@@ -291,6 +291,23 @@ Results:
| result | string | Always "ok". |
+### jamulusclient/setMuted
+
+Mutes or unmutes the client.
+
+Parameters:
+
+| Name | Type | Description |
+| --- | --- | --- |
+| params.muted | boolean | muted (true or false). |
+
+Results:
+
+| Name | Type | Description |
+| --- | --- | --- |
+| result | string | Always "ok". |
+
+
### jamulusclient/setName
Sets your name.
@@ -325,6 +342,23 @@ Results:
| result | string | Always "ok". |
+### 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).
+
+Parameters:
+
+| Name | Type | Description |
+| --- | --- | --- |
+| params.chatMessage | string | The chat message text. |
+
+Results:
+
+| Name | Type | Description |
+| --- | --- | --- |
+| result | string | Always "ok". |
+
+
### jamulusserver/getClients
Returns the list of connected clients along with details about them.
@@ -621,3 +655,38 @@ Parameters:
| params.servers[*].city | string | Server city. |
+### jamulusserver/chatMessageReceived
+
+Emitted when a chat message is received from either a Jamulus or RPC client and to be broadcast to all connected clients.
+
+Parameters:
+
+| Name | Type | Description |
+| --- | --- | --- |
+| params.chatMessage | string | Chat message text. |
+
+
+### jamulusserver/clientConnected
+
+Emitted when a client has connected to the server.
+
+Parameters:
+
+| Name | Type | Description |
+| --- | --- | --- |
+| params.id | number | The channel ID assigned to the client. |
+| params.address | string | The client's address. |
+| params.totalChannels | number | Number of total channels connected to the server. |
+
+
+### jamulusserver/clientDisconnected
+
+Emitted when a client has disconnected from the server.
+
+Parameters:
+
+| Name | Type | Description |
+| --- | --- | --- |
+| params.id | number | The channel ID assigned to the client. |
+
+
diff --git a/src/client.h b/src/client.h
index 27c78cdf3d..b3a160be5b 100644
--- a/src/client.h
+++ b/src/client.h
@@ -329,6 +329,7 @@ class CClient : public QObject
// settings
CChannelCoreInfo ChannelInfo;
QString strClientName;
+ void OnRPCInMuteMyself ( bool bMute ) { OnControllerInMuteMyself ( bMute ); }
public:
void SetSettings ( CClientSettings* settings );
diff --git a/src/clientrpc.cpp b/src/clientrpc.cpp
index 02324121e3..9ba7060a1d 100644
--- a/src/clientrpc.cpp
+++ b/src/clientrpc.cpp
@@ -497,6 +497,23 @@ CClientRpc::CClientRpc ( CClient* pClient, CClientSettings* pSettings, CRpcServe
response["result"] = jsonDevices;
Q_UNUSED ( params );
} );
+
+ /// @rpc_method jamulusclient/setMuted
+ /// @brief Mutes or unmutes the client.
+ /// @param {boolean} params.muted - muted (true or false).
+ /// @result {string} result - Always "ok".
+ pRpcServer->HandleMethod ( "jamulusclient/setMuted", [=] ( const QJsonObject& params, QJsonObject& response ) {
+ auto muted = params["muted"];
+ if ( !muted.isBool() )
+ {
+ response["error"] = CRpcServer::CreateJsonRpcError ( CRpcServer::iErrInvalidParams, "Invalid params: muted is not a boolean" );
+ return;
+ }
+
+ pClient->OnRPCInMuteMyself ( muted.toBool() );
+
+ response["result"] = "ok";
+ } );
}
QJsonValue CClientRpc::SerializeSkillLevel ( ESkillLevel eSkillLevel )
diff --git a/src/server.cpp b/src/server.cpp
index 67274965bc..15f3d74e3f 100644
--- a/src/server.cpp
+++ b/src/server.cpp
@@ -470,6 +470,8 @@ void CServer::OnNewConnection ( int iChID, int iTotChans, CHostAddress RecHostAd
// logging of new connected channel
Logging.AddNewConnection ( RecHostAddr.InetAddr, iTotChans );
+
+ emit ClientConnected ( iChID, RecHostAddr.InetAddr, iTotChans );
}
void CServer::OnServerFull ( CHostAddress RecHostAddr )
@@ -872,10 +874,7 @@ void CServer::DecodeReceiveData ( const int iChanCnt, const int iNumClients )
// and emit the client disconnected signal
if ( eGetStat == GS_CHAN_NOW_DISCONNECTED )
{
- if ( JamController.GetRecordingEnabled() )
- {
- emit ClientDisconnected ( iCurChanID ); // TODO do this outside the mutex lock?
- }
+ emit ClientDisconnected ( iCurChanID ); // TODO do this outside the mutex lock?
FreeChannel ( iCurChanID ); // note that the channel is now not in use
@@ -1296,15 +1295,26 @@ void CServer::CreateAndSendChatTextForAllConChannels ( const int iCurChanID, con
const QString strActualMessageText = "(" + QTime::currentTime().toString ( "hh:mm:ss AP" ) + ") " +
ChanName.toHtmlEscaped() + " " + strChatText.toHtmlEscaped();
+ SendChatTextToAllChannels ( strActualMessageText );
+}
- // Send chat text to all connected clients ---------------------------------
+void CServer::SendChatTextToAllChannels ( const QString& strChatText )
+{
+ // Send chat text to all channels -------------------------------------------
for ( int i = 0; i < iMaxNumChannels; i++ )
{
- if ( vecChannels[i].IsConnected() )
- {
- // send message
- vecChannels[i].CreateChatTextMes ( strActualMessageText );
- }
+ SendChatTextToConChannel ( i, strChatText );
+ }
+ emit sentChatMessage ( strChatText );
+}
+
+void CServer::SendChatTextToConChannel ( const int iCurChanID, const QString& strChatText )
+{
+ // Only send chat text if channel is connected ------------------------------
+ if ( vecChannels[iCurChanID].IsConnected() )
+ {
+ // send message
+ vecChannels[iCurChanID].CreateChatTextMes ( strChatText );
}
}
diff --git a/src/server.h b/src/server.h
index 2e6b13e835..c87baba95c 100644
--- a/src/server.h
+++ b/src/server.h
@@ -191,6 +191,8 @@ class CServer : public QObject, public CServerSlots
void SetEnableDelayPanning ( bool bDelayPanningOn ) { bDelayPan = bDelayPanningOn; }
bool IsDelayPanningEnabled() { return bDelayPan; }
+ void SendChatTextToAllChannels ( const QString& strChatText );
+
protected:
// access functions for actual channels
bool IsConnected ( const int iChanNum ) { return vecChannels[iChanNum].IsConnected(); }
@@ -205,6 +207,7 @@ class CServer : public QObject, public CServerSlots
virtual void CreateAndSendChanListForThisChan ( const int iCurChanID );
virtual void CreateAndSendChatTextForAllConChannels ( const int iCurChanID, const QString& strChatText );
+ void SendChatTextToConChannel ( const int iCurChanID, const QString& strChatText );
virtual void CreateOtherMuteStateChanged ( const int iCurChanID, const int iOtherChanID, const bool bIsMuted );
@@ -328,6 +331,8 @@ class CServer : public QObject, public CServerSlots
void Started();
void Stopped();
void ClientDisconnected ( const int iChID );
+ void ClientConnected ( const int iChID, const QHostAddress RecHostAddr, const int iTotChans );
+ void sentChatMessage ( const QString& strChatText );
void SvrRegStatusChanged();
void AudioFrame ( const int iChID,
const QString stChName,
diff --git a/src/serverrpc.cpp b/src/serverrpc.cpp
index 315a3e262c..d1bf12f02f 100644
--- a/src/serverrpc.cpp
+++ b/src/serverrpc.cpp
@@ -56,6 +56,57 @@ CServerRpc::CServerRpc ( CServer* pServer, CRpcServer* pRpcServer, QObject* pare
Q_UNUSED ( params );
} );
+ /// @rpc_notification jamulusserver/clientConnected
+ /// @brief Emitted when a client has connected to the server.
+ /// @param {number} params.id - The channel ID assigned to the client.
+ /// @param {string} params.address - The client's address.
+ /// @param {number} params.totalChannels - Number of total channels connected to the server.
+ connect ( pServer, &CServer::ClientConnected, [=] ( const int iChanID, const QHostAddress RecHostAddr, const int iTotChans ) {
+ pRpcServer->BroadcastNotification ( "jamulusserver/clientConnected",
+ QJsonObject{
+ { "id", iChanID },
+ { "address", RecHostAddr.toString() },
+ { "totalChannels", iTotChans },
+ } );
+ } );
+
+ /// @rpc_notification jamulusserver/clientDisconnected
+ /// @brief Emitted when a client has disconnected from the server.
+ /// @param {number} params.id - The channel ID assigned to the client.
+ connect ( pServer, &CServer::ClientDisconnected, [=] ( const int iChanID ) {
+ pRpcServer->BroadcastNotification ( "jamulusserver/clientDisconnected",
+ QJsonObject{
+ { "id", iChanID },
+ } );
+ } );
+
+ /// @rpc_notification jamulusserver/chatMessageReceived
+ /// @brief Emitted when a chat message is received from either a Jamulus or RPC client and to be broadcast to all connected clients.
+ /// @param {string} params.chatMessage - Chat message text.
+ connect ( pServer, &CServer::sentChatMessage, [=] ( const QString& strChatText ) {
+ pRpcServer->BroadcastNotification ( "jamulusserver/chatMessageReceived",
+ QJsonObject{
+ { "chatMessage", strChatText },
+ } );
+ } );
+
+ /// @rpc_method jamulusserver/broadcastChatMessage
+ /// @brief 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).
+ /// @param {string} params.chatMessage - The chat message text.
+ /// @result {string} result - Always "ok".
+ pRpcServer->HandleMethod ( "jamulusserver/broadcastChatMessage", [=] ( const QJsonObject& params, QJsonObject& response ) {
+ auto jsonChatMessage = params["chatMessage"];
+ if ( !jsonChatMessage.isString() )
+ {
+ response["error"] = CRpcServer::CreateJsonRpcError ( CRpcServer::iErrInvalidParams, "Invalid params: chatMessage is not a string" );
+ return;
+ }
+
+ pServer->SendChatTextToAllChannels ( jsonChatMessage.toString() );
+ response["result"] = "ok";
+ } );
+
/// @rpc_method jamulusserver/getRecorderStatus
/// @brief Returns the recorder state.
/// @param {object} params - No parameters (empty object).