1 /** 2 Copyright: Copyright (c) 2015-2018 Andrey Penechko. 3 License: $(WEB boost.org/LICENSE_1_0.txt, Boost License 1.0). 4 Authors: Andrey Penechko. 5 */ 6 module voxelman.remotecontrol.plugin; 7 8 import std.stdio; 9 import voxelman.log; 10 import std.traits : Select; 11 12 import pluginlib; 13 import voxelman.core.events; 14 import voxelman.eventdispatcher.plugin; 15 import voxelman.command.plugin; 16 import voxelman.server.plugin; 17 18 19 final class RemoteControl(bool clientSide) : IPlugin 20 { 21 alias CommandPlugin = Select!(clientSide, CommandPluginClient, CommandPluginServer); 22 23 // IPlugin stuff 24 mixin IdAndSemverFrom!"voxelman.remotecontrol.plugininfo"; 25 private EventDispatcherPlugin evDispatcher; 26 private CommandPlugin commandPlugin; 27 private char[] buf; 28 29 override void preInit() { 30 buf = new char[](2048); 31 } 32 33 override void init(IPluginManager pluginman) 34 { 35 evDispatcher = pluginman.getPlugin!EventDispatcherPlugin; 36 commandPlugin = pluginman.getPlugin!CommandPlugin; 37 bool enable = true; 38 39 static if (!clientSide) 40 { 41 ServerPlugin serverPlugin = pluginman.findPlugin!ServerPlugin; 42 bool serverPresent = serverPlugin !is null; 43 enable = serverPresent && (serverPlugin.mode == ServerMode.standalone); 44 } 45 46 if (enable) 47 evDispatcher.subscribeToEvent(&onPreUpdateEvent); 48 } 49 50 void onPreUpdateEvent(ref PreUpdateEvent event) 51 { 52 try readStdin(); 53 catch (Exception e) { 54 //warningf("Exception while reading stdin: %s", e); 55 } 56 } 57 58 void readStdin() 59 { 60 if (!stdin.isOpen || stdin.eof || stdin.error) return; 61 62 auto size = stdin.size; 63 if (size > 0 && size != ulong.max) 64 { 65 import std.regex : regex, splitter; 66 import std.algorithm : min; 67 import std.array : array; 68 69 size_t charsToRead = min(size, buf.length); 70 char[] data = stdin.rawRead(buf[0..charsToRead]); 71 auto splittedLines = splitter(data, regex("(\r\n|\r|\n|\v|\f)")).array; 72 73 while (splittedLines.length > 1) 74 { 75 char[] command = splittedLines[0]; 76 splittedLines = splittedLines[1..$]; 77 78 commandPlugin.execute(command, CommandSourceType.localLauncher, SessionId(0)); 79 info(commandPlugin.commandTextOutput.text); 80 } 81 82 if (splittedLines.length == 1) 83 stdin.seek(-cast(long)splittedLines[0].length); 84 } 85 } 86 }