public Stream Open(string path, OpenMode mode)
        {
            var cMount = _clientMounts.FirstOrDefault(x => x.Path.StartsWith(path));

            if (cMount != null)
            {
                string mPath = path.Remove(0, cMount.Path.Length);
                if (!cMount.GetFiles().Contains(mPath))
                {
                    if (mode == OpenMode.OpenOrCreate)
                    {
                        throw new IOException("Read-only filesystem.");
                    }
                    else
                    {
                        throw new IOException("File not found.");
                    }
                }
                return(new MemoryStream(cMount.GetFileContents(mPath)));
            }
            var err = new Exception("Unknown error.");
            var ret = -1;

            _server.SendMessage(ServerMessageType.FS_OPENSTREAM, writePathData(path, null).Concat(BitConverter.GetBytes((int)mode)).ToArray(), (res, reader) =>
            {
                if (res == ServerResponseType.REQ_SUCCESS)
                {
                    ret = reader.ReadInt32();
                    return;
                }
                if (res == ServerResponseType.REQ_ERROR && reader.BaseStream.Length > 0)
                {
                    err = new Exception(reader.ReadString());
                    return;
                }
            }).Wait();
            if (ret < 0)
            {
                throw err;
            }
            return(_rstreams.Open(ret));
        }
示例#2
0
        public void Run(ConsoleContext console, Dictionary <string, object> arguments)
        {
            int id = -1;

            Task.WaitAll(man.SendMessage(ServerMessageType.STREAM_TEST, new byte[] { }, (resp, read) => id = read.ReadInt32()));
            console.WriteLine("That's the message that I sent.  (DAVID BOWIE IS NOT MC RIDE)");
            using (var fobj = rstreams.Open(id))
            {
                console.WriteLine("Remote Stream opened.");
                console.WriteLine($"CanRead = {fobj.CanRead}");
                console.WriteLine($"CanWrite = {fobj.CanWrite}");
                console.WriteLine($"CanSeek = {fobj.CanSeek}");
                console.WriteLine($"Buffered = {fobj is BufferedStream}");
                console.WriteLine($"Length = {fobj.Length}");
                using (var read = new BinaryReader(fobj, Encoding.UTF8, true))
                {
                    console.WriteLine(Encoding.UTF8.GetString(read.ReadBytes((int)fobj.Length)));
                    fobj.Seek(0, SeekOrigin.Begin);
                    console.WriteLine(Encoding.UTF8.GetString(read.ReadBytes((int)fobj.Length).Reverse().ToArray()));
                }
            }
        }
示例#3
0
        /// <summary>
        /// Runs a command with the given console context.
        /// </summary>
        /// <param name="command">The command (including raw arguments) to parse and run.</param>
        /// <param name="console">The <see cref="ConsoleContext"/> to run the command in.</param>
        /// <returns>Whether the command was actually found.</returns>
        public bool RunCommand(string command, ConsoleContext console)
        {
            //First we need to parse the command string into something we can actually use as a query.
            var query = ParseCommand(command);

            //If query is null, don't try to run a command. There was no command.
            if (query == null)
            {
                return(false);
            }
            //If we get to this stage, the query is OK. Let's find a local command.
            var local = _localCommands.FirstOrDefault(x => x.Name == query.Name);

            //If this is null we'll send it off to the server. Well, I haven't implemented the server yet so we'll just return false.
            if (local == null)
            {
                if (!_server.Connected)
                {
                    return(false);
                }
                using (var memstr = new MemoryStream())
                {
                    using (var writer = new BinaryWriter(memstr, Encoding.UTF8))
                    {
                        writer.Write(query.Name);
                        writer.Write(query.ArgumentTokens.Length);
                        foreach (var token in query.ArgumentTokens)
                        {
                            writer.Write(token);
                        }
                        writer.Flush();
                        ManualResetEvent commandDone = new ManualResetEvent(false);

                        Action <ServerBroadcastType, BinaryReader> terminalOutput = (req, r) =>
                        {
                            if (req != ServerBroadcastType.TerminalOutput)
                            {
                                return;
                            }
                            int    count = r.ReadInt32();
                            byte[] data  = r.ReadBytes(count);
                            string str   = Encoding.UTF8.GetString(data);
                            console.Write(str);
                            if (str.ToCharArray().Contains((char)0x02))
                            {
                                commandDone.Set();
                            }
                        };
                        _server.BroadcastReceived += terminalOutput;

                        Stream remoteSlave = null;
                        Thread t           = null;

                        _server.SendMessage(ServerMessageType.TRM_INVOKE, memstr.ToArray(), (res, reader) =>
                        {
                            if (res != ServerResponseType.REQ_SUCCESS)
                            {
                                console.WriteLine("Unexpected, unknown error.");
                                return;
                            }
                            int remoteSlaveId = reader.ReadInt32();

                            remoteSlave = _remoteStreams.Open(remoteSlaveId);

                            t = new Thread(() =>
                            {
                                while (true)
                                {
                                    try
                                    {
                                        char input = (char)console.StandardInput.BaseStream.ReadByte();
                                        remoteSlave.WriteByte((byte)input);
                                    }
                                    catch (TerminationRequestException)
                                    {
                                        remoteSlave.WriteByte(0x02);
                                        remoteSlave.WriteByte((byte)'\n');
                                    }
                                }
                            });

                            t.Start();
                        }).Wait();

                        commandDone.WaitOne();

                        CommandSucceeded?.Invoke(query.Name);

                        _server.BroadcastReceived -= terminalOutput;

                        t.Abort();
                        remoteSlave.Close();
                    }
                }
                return(true);
            }
            else
            {
                //So we have a command query, a console context, and a command.
                //What do we need next? Well, we need our argument dictionary.
                //We can use Docopt.Net and the ITerminalCommand.Usages property to get that.
                //First let's create a Dictionary<string, object> to store our arguments.
                var argumentStore = new Dictionary <string, object>();

                //Next, we retrieve the usage string from the command.
                //The engine creates usage strings during initialization.
                var usage = _usages[local.Name];

                //Then we pass it off to Docopt.
                var docoptArgs = new DocoptNet.Docopt().Apply(usage, query.ArgumentTokens, true, local.Name, false, false);
                //Now we just CTRL+C and CTRL+V from the debug console.
                foreach (var arg in docoptArgs)
                {
                    if (arg.Value != null)
                    {
                        argumentStore.Add(arg.Key, arg.Value.Value);
                    }
                    else
                    {
                        argumentStore.Add(arg.Key, null);
                    }
                }
                //Now we run the command - check for errors!
                try
                {
                    local.Run(console, argumentStore);
                    CommandSucceeded?.Invoke(query.Name);
                }
                catch (TerminationRequestException)
                {
                    console.WriteLine("Killed.");
                    return(true);
                }
                return(true);
            }
        }