コード例 #1
0
        public CommandResult RunCommand(IDFStream output, string cmd, List <string> args)
        {
            if (!_active || Socket == null)
            {
                output.PrintErr("In RunCommand: client connection not valid.\n");
                return(CommandResult.CrFailure);
            }

            _runcmdCall.Reset();

            _runcmdCall.Input.command = cmd;
            foreach (var t in args)
            {
                _runcmdCall.Input.arguments.Add(t);
            }

            return(_runcmdCall.TryExecute(output));
        }
コード例 #2
0
        public bool Bind(IDFStream output,
                         RemoteClient client, string name,
                         string proto = "")
        {
            if (IsValid())
            {
                if (PClient == client && Name == name && Proto == proto)
                {
                    return(true);
                }

                output.PrintErr("Function already bound to %s::%s\n",
                                Proto, Name);
                return(false);
            }

            Name    = name;
            Proto   = proto;
            PClient = client;

            return(client.Bind(output, this, name, proto));
        }
コード例 #3
0
        protected CommandResult TryExecute <TInput, TOutput>(IDFStream outString, TInput input, out TOutput output)
            where TInput : class, IExtensible, new()
            where TOutput : class, IExtensible, new()
        {
            if (!IsValid())
            {
                outString.PrintErr("Calling an unbound RPC function %s::%s.\n",
                                   Proto, Name);
                output = default(TOutput);
                return(CommandResult.CrNotImplemented);
            }

            if (PClient.Socket == null)
            {
                outString.PrintErr("In call to %s::%s: invalid socket.\n",
                                   Proto, Name);
                output = default(TOutput);
                return(CommandResult.CrLinkFailure);
            }

            MemoryStream sendStream = new MemoryStream();

            Serializer.Serialize(sendStream, input);

            long sendSize = sendStream.Length;

            if (sendSize > RpcMessageHeader.MaxMessageSize)
            {
                outString.PrintErr("In call to %s::%s: message too large: %d.\n",
                                   Proto, Name, sendSize);
                output = default(TOutput);
                return(CommandResult.CrLinkFailure);
            }

            if (!SendRemoteMessage(PClient.Socket, Id, sendStream))
            {
                outString.PrintErr("In call to %s::%s: I/O error in send.\n",
                                   Proto, Name);
                output = default(TOutput);
                return(CommandResult.CrLinkFailure);
            }

            ColorOstreamProxy textDecoder = new ColorOstreamProxy(outString);

            //output = new Output();
            //return command_result.CR_OK;

            while (true)
            {
                RpcMessageHeader header = new RpcMessageHeader();
                byte[]           buffer = new byte[8];

                if (!RemoteClient.ReadFullBuffer(PClient.Socket, buffer, 8))
                {
                    outString.PrintErr("In call to %s::%s: I/O error in receive header.\n",
                                       Proto, Name);
                    output = default(TOutput);
                    return(CommandResult.CrLinkFailure);
                }

                header.Id   = BitConverter.ToInt16(buffer, 0);
                header.Size = BitConverter.ToInt32(buffer, 4); //because something, somewhere, is f*****g retarded

                //outString.print("Received %d:%d.\n", header.id, header.size);


                if ((DfHackReplyCode)header.Id == DfHackReplyCode.RpcReplyFail)
                {
                    output = default(TOutput);
                    if (header.Size == (int)CommandResult.CrOk)
                    {
                        return(CommandResult.CrFailure);
                    }
                    else
                    {
                        return((CommandResult)header.Size);
                    }
                }

                if (header.Size < 0 || header.Size > RpcMessageHeader.MaxMessageSize)
                {
                    outString.PrintErr("In call to %s::%s: invalid received size %d.\n",
                                       Proto, Name, header.Size);
                    output = default(TOutput);
                    return(CommandResult.CrLinkFailure);
                }

                byte[] buf = new byte[header.Size];
                if (!RemoteClient.ReadFullBuffer(PClient.Socket, buf, header.Size))
                {
                    outString.PrintErr("In call to %s::%s: I/O error in receive %d bytes of data.\n",
                                       Proto, Name, header.Size);
                    output = default(TOutput);
                    return(CommandResult.CrLinkFailure);
                }

                switch ((DfHackReplyCode)header.Id)
                {
                case DfHackReplyCode.RpcReplyResult:
                    output = Serializer.Deserialize <TOutput>(new MemoryStream(buf));
                    if (output != null)
                    {
                        return(CommandResult.CrOk);
                    }
                    outString.PrintErr("In call to %s::%s: error parsing received result.\n",
                                       Proto, Name);
                    return(CommandResult.CrLinkFailure);

                case DfHackReplyCode.RpcReplyText:
                    var textData = Serializer.Deserialize <CoreTextNotification>(new MemoryStream(buf));

                    if (textData != null)
                    {
                        textDecoder.Decode(textData);
                    }
                    else
                    {
                        outString.PrintErr("In call to %s::%s: received invalid text data.\n",
                                           Proto, Name);
                    }
                    break;
                }
            }
        }