summaryrefslogtreecommitdiff
path: root/indra/newview/llscripteditorws.h
diff options
context:
space:
mode:
authorRider Linden <rider@lindenlab.com>2025-08-26 21:29:41 -0700
committerRider Linden <rider@lindenlab.com>2025-10-07 09:19:36 -0700
commitf31c194b8674df295edf74693a2f843ca314ca92 (patch)
tree936a587328d122e0bd12f811a2c310d23ec872b8 /indra/newview/llscripteditorws.h
parent7b174ab2a7c54d3e25a56530a2179848db2d46c0 (diff)
Expand the websocket implementation a bit. Added JSONRPC specialization.
Diffstat (limited to 'indra/newview/llscripteditorws.h')
-rw-r--r--indra/newview/llscripteditorws.h148
1 files changed, 97 insertions, 51 deletions
diff --git a/indra/newview/llscripteditorws.h b/indra/newview/llscripteditorws.h
index 73efb1a65f..78c675a1f4 100644
--- a/indra/newview/llscripteditorws.h
+++ b/indra/newview/llscripteditorws.h
@@ -26,7 +26,7 @@
#pragma once
-#include "llwebsocketmgr.h"
+#include "lljsonrpcws.h"
#include "llsd.h"
#include "lluuid.h"
#include "llhandle.h"
@@ -39,48 +39,43 @@
// Forward declarations
class LLLiveLSLEditor;
-class LLScriptEdCore;
+class LLScriptEdContainer;
+class LLScriptEditorWSServer;
/**
* @class LLScriptEditorWSConnection
- * @brief WebSocket connection specialized for external script editor communication
+ * @brief JSON-RPC WebSocket connection specialized for external script editor communication
*
- * This class handles WebSocket communication between the Second Life viewer
- * and external script editors. It manages script content synchronization,
- * compilation status updates, and editor metadata exchange.
+ * This class handles JSON-RPC 2.0 communication between the Second Life viewer
+ * and external script editors. It provides a clean base for implementing
+ * script editor integration using the standard JSON-RPC 2.0 protocol.
*
- * ## Message Protocol
- *
- * The connection uses JSON messages with the following structure:
- * - `type`: Message type identifier
- * - `data`: Message payload (varies by type)
- * - `timestamp`: Message timestamp for ordering
- * - `id`: Optional message ID for request/response correlation
- *
- * ### Supported Message Types:
+ * ## Usage
*
- * #### From Editor to Viewer:
- * - `script_updated`: Script content has been modified
- * - `save_request`: Request to save script to SL servers
- * - `compile_request`: Request to compile script
- * - `editor_ready`: Editor initialization complete
- * - `ping`: Connection health check
+ * @code
+ * // Create server and let base JSON-RPC handle method registration
+ * auto server = std::make_shared<LLScriptEditorWSServer>("script_editor_server", 9020);
*
- * #### From Viewer to Editor:
- * - `script_content`: Full script content
- * - `compile_result`: Compilation success/failure with errors
- * - `save_result`: Save operation result
- * - `metadata`: Script and object metadata
- * - `pong`: Response to ping
+ * // Register custom methods as needed
+ * connection->registerMethod("custom.method", handler);
+ * @endcode
*/
-class LLScriptEditorWSConnection : public LLWebsocketMgr::WSConnection
+class LLScriptEditorWSConnection : public LLJSONRPCConnection,
+ public std::enable_shared_from_this<LLScriptEditorWSConnection>
{
public:
+ enum DisconnectReason
+ {
+ REASON_NORMAL = 0,
+ REASON_EDITOR_CLOSED = 1,
+ REASON_PROTOCOL_ERROR = 2,
+ REASON_TIMEOUT = 3,
+ REASON_INTERNAL_ERROR = 4
+ };
LLScriptEditorWSConnection(const LLWebsocketMgr::WSServer::ptr_t server,
- const LLWebsocketMgr::connection_h& handle):
- LLWebsocketMgr::WSConnection(server, handle),
- mMessageSequence(0)
+ const LLWebsocketMgr::connection_h& handle)
+ : LLJSONRPCConnection(server, handle)
{ }
~LLScriptEditorWSConnection() override = default;
@@ -89,32 +84,57 @@ public:
// Connection lifecycle overrides
void onOpen() override;
void onClose() override;
- void onMessage(const std::string& message) override;
+
+ /**
+ * @brief Send session disconnect message to the external editor
+ * @param reason Numeric reason code for the disconnect (default 0 for normal closure)
+ * @param message Human-readable disconnect message (default "Goodbye")
+ */
+ void sendDisconnect(S32 reason = 0, const std::string& message = "Goodbye");
private:
+ using string_set_t = std::set<std::string>;
/**
- * @brief Handle connect/connection messages from editor
- * @param message Parsed LLSD message
+ * @brief Handle the handshake response from the client
+ * @param result The response data from the client containing client information
*/
- void processConnectMessage(const LLSD& message);
+ void handleHandshakeResponse(const LLSD& result);
+
+ bool connectToEditor(const std::string& script_id);
+ void cleanupConnection();
+
+ LLScriptEdContainer* getEditor() const;
+ std::shared_ptr<LLScriptEditorWSServer> getServer() const;
std::string mEditorId; ///< Unique identifier for this editor session
LLSD mEditorCapabilities; ///< Editor capabilities metadata
- U32 mMessageSequence; ///< Message sequence counter
std::string mScriptId; ///< Unique identifier for the script being edited
+ bool mEditorReady; ///< Whether editor has completed initialization
+ LLHandle<LLPanel> mEditorPanel; ///< Handle to the associated LSL editor panel
+
+ // Client handshake response data
+ std::string mClientName; ///< Name of the external editor client
+ std::string mClientVersion; ///< Version of the external editor client
+ std::string mProtocolVersion; ///< JSON-RPC protocol version supported by client
+ std::string mScriptName; ///< Name of the script being edited
+ std::string mScriptLanguage; ///< Programming language of the script (lsl, luau, etc.)
+ string_set_t mLanguages; ///< Set of supported scripting languages
+ string_set_t mFeatures; ///< Active client features (live_sync, compilation, etc.)
};
/**
* @class LLScriptEditorWSServer
- * @brief WebSocket server for external script editor integration
+ * @brief JSON-RPC 2.0 WebSocket server for external script editor integration
*
- * This server manages WebSocket connections from external script editors,
- * providing a bridge between the Second Life viewer's script editing
- * functionality and external development tools.
+ * This server extends the JSON-RPC server to provide specialized functionality
+ * for external script editor integration. It manages WebSocket connections from
+ * external script editors and provides a structured JSON-RPC 2.0 interface
+ * between the Second Life viewer's script editing functionality and external
+ * development tools.
*
* ## Architecture
*
- * The server acts as a communication hub between:
+ * The server acts as a JSON-RPC communication hub between:
* - LLLiveLSLEditor instances (in-world script editing)
* - External script editors (VS Code, Atom, Sublime Text, etc.)
* - Script compilation and save services
@@ -122,8 +142,8 @@ private:
* ## Usage
*
* @code
- * // Create and start the server
- * auto server = std::make_shared<LLScriptEditorWSServer>("script_editor_server", 8080);
+ * // Create and start the JSON-RPC server
+ * auto server = std::make_shared<LLScriptEditorWSServer>("script_editor_server", 9020);
* LLWebsocketMgr::getInstance()->addServer(server);
* LLWebsocketMgr::getInstance()->startServer("script_editor_server");
*
@@ -134,11 +154,11 @@ private:
* ## Security Considerations
*
* - Server binds to localhost only by default for security
- * - Editor authentication via connection handshake
- * - Script content encryption for sensitive projects
- * - Rate limiting to prevent abuse
+ * - JSON-RPC 2.0 structured protocol with validation
+ * - Rate limiting handled by base JSON-RPC server
+ * - Error handling with standardized JSON-RPC error codes
*/
-class LLScriptEditorWSServer : public LLWebsocketMgr::WSServer
+class LLScriptEditorWSServer : public LLJSONRPCServer
{
public:
static constexpr char const* DEFAULT_SERVER_NAME = "script_editor_server";
@@ -146,7 +166,7 @@ public:
using ptr_t = std::shared_ptr<LLScriptEditorWSServer>;
- LLScriptEditorWSServer(const std::string_view name, U16 port, bool local_only = true);
+ LLScriptEditorWSServer(const std::string& name, U16 port, bool local_only = true);
virtual ~LLScriptEditorWSServer() = default;
@@ -166,14 +186,40 @@ public:
*/
std::set<std::string> getActiveScripts() const;
+ /**
+ * @brief Send script content to all connected editors for a specific script
+ * @param script_id The script identifier
+ * @param content The script content
+ * @param metadata Optional metadata about the script
+ */
+ void broadcastScriptUpdate(const std::string& script_id, const std::string& content, const LLSD& metadata = LLSD());
+
+ /**
+ * @brief Send compilation results to all connected editors for a specific script
+ * @param script_id The script identifier
+ * @param success Whether compilation succeeded
+ * @param errors Array of compilation errors/warnings
+ */
+ void broadcastCompilationResult(const std::string& script_id, bool success, const LLSD& errors = LLSD());
+
protected:
- LLWebsocketMgr::WSConnection::ptr_t connectionFactory(WSServer::ptr_t server, LLWebsocketMgr::connection_h handle) override;
+ LLWebsocketMgr::WSConnection::ptr_t connectionFactory(LLWebsocketMgr::WSServer::ptr_t server,
+ LLWebsocketMgr::connection_h handle) override;
+
+ /**
+ * @brief Apply global method handlers to a new connection
+ * @param connection The connection to configure
+ *
+ * Override this method to customize which methods are registered on
+ * new connections. The base implementation registers all global methods,
+ * but derived classes can add additional script-specific methods.
+ */
+ virtual void setupConnectionMethods(LLJSONRPCConnection::ptr_t connection) override;
private:
- using map_id_to_editor_t = std::unordered_map<std::string, LLHandle<LLPanel> >;
+ using map_id_to_editor_t = std::unordered_map<std::string, LLHandle<LLPanel>>;
map_id_to_editor_t mScriptEditors;
-
std::set<std::shared_ptr<LLScriptEditorWSConnection>> mActiveConnections;
/**