Author Topic: Parenting the echo() function  (Read 3935 times)

Recently, I've had an idea for an add-on which sends live console input to another program. It lets you view the remote console as text is being echo()'d. This was, originally, my code:
Code: [Select]
function echo(%text)
{
%file = new FileObject();
%file.openForAppend("config/server/rcconsole.txt");
%file.writeLine(%text);
%file.close();

Parent::echo(%text);
}
Then, after asking several players, I've learned that you can't parent the echo() or eval() functions. And, of course, using the console.log won't work (since it's not accessible while the server is running) and it would be horribly inefficient to skip 500,000 lines or so.
So does anybody know if there's any kind of workaround to get live input from the Blockland console? I was thinking that you may need to interfere with the command shell of the host OS whenever it prints a line into command prompt, terminal, etc. This console streaming program must be able to access the console while the server is running.

You could make another program separate from Blockland which reads the console output and then writes it to a file using something like C++ or Java.

Kalphiter provided this Java snippet before :

Code: [Select]
    public void run()
    {
String consoleLine = null;
    try
{
    String lastTwoChars = "";
    String lastChar_0 = "";
    String lastChar_1 = "";

    Runtime rt = Runtime.getRuntime();

    proc = rt.exec(cmd);
    proc_in = proc.getInputStream();
    proc_out = proc.getOutputStream();
    proc_err = proc.getErrorStream();
    BufferedReader input = new BufferedReader(new InputStreamReader(proc.getInputStream()));
    output = new BufferedWriter(new OutputStreamWriter(proc.getOutputStream()));
    String currentChar;
    int lineInt;
    while ((lineInt = input.read()) >= 0 && lineInt < 256)
    {
currentChar = new String(new byte[] { new Integer(lineInt).byteValue() });
lastChar_0 = lastChar_1;
lastChar_1 = currentChar;
lastTwoChars = lastChar_0 + lastChar_1;

if(lineInt == 10)
{
    addConsole(consoleLine);
    consoleLine = "";
}
else if(lineInt != 13)
    consoleLine += currentChar;
    }
    running = false;
}
catch(Exception g)
{
    addConsole("Exception: "+ g);
    running = false;
}
running = false;
onStop();
    }
Of course, there are many methods that aren't there, and I was just having fun with reading character by character
And you could access the process and read the output from the memory

But yes, you can't use echo(); , eval(); , or read the console.log file. You'd have to make a separate wrapper program which does it. Since you know Java, hopefully you can work off of this code.
« Last Edit: July 15, 2013, 04:25:12 PM by Pacnet2012³ »

Have the other program directly read it from memory.

Have the other program directly read it from memory.
requires administrative privileges

If you're on Linux you can read the console.log I think

The foolproof method is to capture the stdout of the blockland process. However, this won't work under wine in Linux.

I wonder if you can use file objects to read the console log on Linux?

I wonder if you can use file objects to read the console log on Linux?

Not while the server is running, because blockland writes to it frequently, its left open in Blockland until the game closes or quits. So you cant read/write from/to the file.

I wonder if you can use file objects to read the console log on Linux?

It's actually funny because you can open it in gedit (it constantly asks you to reload the file)


Thank you for the code snippet, Kalphiter and Pacnet. I've written the console streaming part of the program.
For a while, I thought this topic would get moved to the Off-topic section, especially since this doesn't deal with TorqueScript.

Actually, use setLogMode(1); and you can then open the log using file objects. It's pretty inefficient though.

You can't read/write files in the root directory.

Ded.

Could you get around that by using setModPaths() to include it?

Could you get around that by using setModPaths() to include it?
Unfortunately setModPaths() appears to only accept certain arguments. If you try creating a new directory and including it, it won't work.

The foolproof method is to capture the stdout of the blockland process. However, this won't work under wine in Linux.

How come it works for me then?

How come it works for me then?
Works fine on my end, although you have to bypass the launcher. Unless I'm dumb and there's some launcher argument you can use.


I don't see why you owuld use the default launcher anyway, though.