2
0
Эх сурвалжийг харах

RemoteConsole: add server auto-start, fix n message 1 onData

Yuxiao Mao 7 сар өмнө
parent
commit
e306748bec

+ 68 - 68
hide/view/RemoteConsoleView.hx

@@ -4,8 +4,9 @@ package hide.view;
 	props.json configuration (all champs are optional):
 	```json
 	"remoteconsole": {
-		"host": "127.0.0.2",
-		"port": 40002,
+		"host": "127.0.0.1",
+		"port": 40001,
+		"disableAutoStartServer": false,
 		"commands": [
 			"dump",
 			"custom"
@@ -16,16 +17,15 @@ package hide.view;
 class RemoteConsoleView extends hide.ui.View<{}> {
 	static var rcmd : hrt.impl.RemoteConsole;
 	static var statusBarIcon : Element;
+	static var inst : RemoteConsoleView;
 	var panels : Array<RemoteConsolePanel>;
 	var panelsView : Element;
-	var logsView : Element;
 	var newPanelBtn : Element;
 
 	public function new( ?state ) {
 		super(state);
 		panels = [];
-		if( statusBarIcon == null )
-			statusBarIcon = new Element('<div class="ico ico-dot-circle-o" style="color: darkgray; cursor:default;" title="[Remote Console]"></div>');
+		inst = this;
 	}
 
 	override function onDisplay() {
@@ -39,42 +39,27 @@ class RemoteConsoleView extends hide.ui.View<{}> {
 				<input type="button" id="stopServerBtn" value="Stop Server"/>
 				<label for="connectHost">Host IP</label>
 				<input type="text" id="connectHost" value="$host:$port" disabled/>
-				<div class="logs">
-				</div>
 			</div>
 		</div>').appendTo(element);
-		hide.Ide.inst.addStatusIcon(statusBarIcon);
 		element.find("#startServerBtn").on('click', function(e) {
-			if( rcmd != null )
-				rcmd.close();
-			rcmd = new hrt.impl.RemoteConsole(port, host);
-			rcmd.onClose = () -> refreshStatusIcon();
-			rcmd.log = (msg) -> log(msg);
-			rcmd.logError = (msg) -> log(msg, true);
-			rcmd.startServer(function(c) {
-				addPanel(c);
-			});
-			refreshStatusIcon();
+			startServer(port, host);
 		});
 		element.find("#stopServerBtn").on('click', function(e) {
-			if( rcmd != null )
-				rcmd.close();
-			log("Server stopped");
+			stopServer();
 		});
-
 		panelsView = element.find(".remoteconsole");
-		logsView = element.find(".logs");
-		addPanel();
+		if( rcmd != null ) {
+			for( c in rcmd.connections ) {
+				addPanel(c);
+			}
+		}
+		if( panels.length <= 0 )
+			addPanel();
+		if( pconfig?.disableAutoStartServer != true )
+			haxe.Timer.delay(() -> startServer(port, host), 1);
 	}
 
 	override function onBeforeClose():Bool {
-		var active = 0;
-		for( p in panels ) {
-			if( p.isConnected() )
-				active++;
-		}
-		if( active > 0 && !hide.Ide.inst.confirm('Close console ($active connection(s) will be closed)?') )
-			return false;
 		forceClear();
 		return super.onBeforeClose();
 	}
@@ -91,33 +76,7 @@ class RemoteConsoleView extends hide.ui.View<{}> {
 		if( panelsView != null )
 			panelsView.remove();
 		panelsView = null;
-		logsView = null;
-	}
-
-	public function log( msg : String, error : Bool = false ) {
-		var el = new Element('<p>${StringTools.htmlEscape(msg)}</p>').appendTo(logsView);
-		if( error )
-			el.addClass("error");
-		logsView.scrollTop(logsView.get(0).scrollHeight);
-	}
-
-	public function refreshStatusIcon() {
-		if( statusBarIcon == null || rcmd == null )
-			return;
-		if( rcmd.isConnected() ) {
-			statusBarIcon.css("color", "#009500");
-			statusBarIcon.prop("title", "[Remote Console] Server active");
-		} else {
-			statusBarIcon.css("color", "#c10000");
-			statusBarIcon.prop("title", "[Remote Console] Server stopped");
-		}
-		var active = 0;
-		for( p in panels ) {
-			if( p.isConnected() )
-				active++;
-		}
-		statusBarIcon.empty();
-		statusBarIcon.append(new Element('<span> $active</span>'));
+		inst = null;
 	}
 
 	function refreshNewPanelButton() {
@@ -154,21 +113,52 @@ class RemoteConsoleView extends hide.ui.View<{}> {
 	}
 
 	public function removePanel( p : RemoteConsolePanel ) {
-		if( p.isConnected() ) {
-			if( !hide.Ide.inst.confirm('Close console (connection will be closed)?') ) {
-				return;
-			}
-		}
 		panels.remove(p);
 		p.element.remove();
 		p.close();
 	}
 
-	public static function onBeforeReload() {
+	public static function refreshStatusIcon() {
+		if( statusBarIcon == null ) {
+			statusBarIcon = new Element('<div class="ico ico-dot-circle-o" style="cursor:default;"></div>');
+			hide.Ide.inst.addStatusIcon(statusBarIcon);
+		}
+		if( rcmd == null ) {
+			statusBarIcon.css("color", "darkgray");
+			statusBarIcon.prop("title", "[Remote Console] Server not started");
+		} else if( rcmd.isConnected() ) {
+			statusBarIcon.css("color", "#009500");
+			statusBarIcon.prop("title", "[Remote Console] Server active");
+		} else {
+			statusBarIcon.css("color", "#c10000");
+			statusBarIcon.prop("title", "[Remote Console] Server stopped");
+		}
+		statusBarIcon.empty();
+		statusBarIcon.append(new Element('<span> ${rcmd.connections.length}</span>'));
+	}
+
+	static function startServer( port, host ) {
+		if( rcmd != null && rcmd.isConnected() )
+			return;
+		rcmd = new hrt.impl.RemoteConsole(port, host);
+		rcmd.onClose = () -> refreshStatusIcon();
+		rcmd.startServer(function(c) {
+			if( inst != null )
+				inst.addPanel(c);
+			refreshStatusIcon();
+		});
+		refreshStatusIcon();
+	}
+
+	static function stopServer() {
 		if( rcmd != null )
 			rcmd.close();
 	}
 
+	public static function onBeforeReload() {
+		stopServer();
+	}
+
 	// allow hide-plugin to add/modify game-specific hide command control
 	public static var commandViews = new Map<String, Class<RemoteConsoleCommand>>();
 	public static function registerCommandView( name : String, cl : Class<RemoteConsoleCommand> ) {
@@ -186,11 +176,10 @@ class RemoteConsolePanel extends hide.comp.Component {
 	public function new( view : RemoteConsoleView, connection : Null<hrt.impl.RemoteConsole.RemoteConsoleConnection>, commands : Null<Array<String>> ) {
 		super(null, null);
 		this.view = view;
-		this.connection = connection;
 		element = new Element('
 		<div class="remoteconsole-panel">
 			<div class="controls">
-				<div class="ico ico-dot-circle-o" id="statusIcon" style="color: darkgray; cursor:default;" title="Not connected"></div>
+				<div class="ico ico-dot-circle-o" id="statusIcon" style="cursor:default;"></div>
 				<div class="ico ico-close" id="closeBtn" title="Close panel"></div>
 			</div>
 			<div class="logs">
@@ -200,6 +189,7 @@ class RemoteConsolePanel extends hide.comp.Component {
 		</div>
 		');
 		this.statusIcon = element.find("#statusIcon");
+		this.connection = connection;
 		element.find("#closeBtn").on('click', function(e) {
 			view.removePanel(this);
 		});
@@ -208,11 +198,18 @@ class RemoteConsolePanel extends hide.comp.Component {
 			addCommandElement(name);
 	}
 	function set_connection( c ) {
+		if( connection == c )
+			return connection;
 		if( c != null ) {
 			c.onClose = () -> refreshStatusIcon();
 			c.log = (msg) -> log(msg);
 			c.logError = (msg) -> log(msg, true);
 		}
+		if( connection != null ) {
+			connection.onClose = () -> {};
+			connection.log = (msg) -> {};
+			connection.logError = (msg) -> {};
+		}
 		connection = c;
 		refreshStatusIcon();
 		return connection;
@@ -227,10 +224,13 @@ class RemoteConsolePanel extends hide.comp.Component {
 		comp.element.appendTo(element.find(".commands"));
 	}
 	function refreshStatusIcon() {
-		view.refreshStatusIcon();
+		RemoteConsoleView.refreshStatusIcon();
 		if( statusIcon == null )
 			return;
-		if( isConnected() ) {
+		if( connection == null ) {
+			statusIcon.css("color", "darkgray");
+			statusIcon.prop("title", "Not connected");
+		} else if( connection.isConnected() ) {
 			statusIcon.css("color", "#009500");
 			statusIcon.prop("title", "Connected");
 		} else {

+ 27 - 26
hrt/impl/RemoteConsole.hx

@@ -22,7 +22,7 @@ class RemoteConsole {
 	public var host : String;
 	public var port : Int;
 	var sock : hxd.net.Socket;
-	var cSocks : Array<RemoteConsoleConnection>;
+	public var connections : Array<RemoteConsoleConnection>;
 
 	public function new( ?port : Int, ?host : String ) {
 		this.host = host ?? DEFAULT_HOST;
@@ -38,13 +38,11 @@ class RemoteConsole {
 		}
 		sock.bind(host, port, function(s) {
 			var connection = new RemoteConsoleConnection(this, s);
-			cSocks.push(connection);
+			connections.push(connection);
 			s.onError = function(msg) {
 				connection.logError("Client error: " + msg);
+				connections.remove(connection);
 				connection.close();
-				if( cSocks != null ) {
-					cSocks.remove(connection);
-				}
 				connection = null;
 			}
 			s.onData = () -> connection.handleOnData();
@@ -58,15 +56,16 @@ class RemoteConsole {
 	public function connect( ?onConnected : Bool -> Void ) {
 		close();
 		sock = new hxd.net.Socket();
+		var connection = new RemoteConsoleConnection(this, sock);
+		connections.push(connection);
 		sock.onError = function(msg) {
 			if( !SILENT_CONNECT )
 				logError("Socket Error: " + msg);
+			connections.remove(connection);
 			close();
 			if( onConnected != null )
 				onConnected(false);
 		}
-		var connection = new RemoteConsoleConnection(this, sock);
-		cSocks.push(connection);
 		sock.onData = () -> connection.handleOnData();
 		sock.connect(host, port, function() {
 			log("Connected to server");
@@ -82,11 +81,11 @@ class RemoteConsole {
 			sock.close();
 			sock = null;
 		}
-		if( cSocks != null ) {
-			for( s in cSocks )
+		if( connections != null ) {
+			for( s in connections )
 				s.close();
 		}
-		cSocks = [];
+		connections = [];
 		onClose();
 	}
 
@@ -106,10 +105,10 @@ class RemoteConsole {
 	}
 
 	public function sendCommand( cmd : String, ?args : Dynamic, ?onResult : Dynamic -> Void ) {
-		if( cSocks.length == 0 ) {
+		if( connections.length == 0 ) {
 			// Ignore send when not really connected
-		} else if( cSocks.length == 1 ) {
-			cSocks[0].sendCommand(cmd, args, onResult);
+		} else if( connections.length == 1 ) {
+			connections[0].sendCommand(cmd, args, onResult);
 		} else {
 			logError("Send to multiple target not implemented");
 		}
@@ -169,20 +168,22 @@ class RemoteConsoleConnection {
 	}
 
 	public function handleOnData() {
-		var str = sock.input.readLine().toString();
-		var obj = try { haxe.Json.parse(str); } catch (e) { logError("Parse error: " + e); null; };
-		if( obj == null || obj.id == null ) {
-			return;
-		}
-		var id : Int = obj.id;
-		if( id <= 0 ) {
-			var onResult = waitReply.get(-id);
-			waitReply.remove(-id);
-			if( onResult != null ) {
-				onResult(obj.args);
+		while( sock.input.available > 0 ) {
+			var str = sock.input.readLine().toString();
+			var obj = try { haxe.Json.parse(str); } catch (e) { logError("Parse error: " + e); null; };
+			if( obj == null || obj.id == null ) {
+				continue;
+			}
+			var id : Int = obj.id;
+			if( id <= 0 ) {
+				var onResult = waitReply.get(-id);
+				waitReply.remove(-id);
+				if( onResult != null ) {
+					onResult(obj.args);
+				}
+			} else {
+				onCommand(obj.cmd, obj.args, (result) -> sendData(null, result, -id));
 			}
-		} else {
-			onCommand(obj.cmd, obj.args, (result) -> sendData(null, result, -id));
 		}
 	}