.[ ČeskéHry.cz ].
RedirectStandardInput u Torque3D dedicated serveru

 
odeslat nové téma   Odpovědět na téma    Obsah fóra České-Hry.cz -> .NET
Zobrazit předchozí téma :: Zobrazit následující téma  
Autor Zpráva
Gork



Založen: 25. 06. 2015
Příspěvky: 8

PříspěvekZaslal: 25. červen 2015, 11:43:10    Předmět: RedirectStandardInput u Torque3D dedicated serveru Odpovědět s citátem

Ahoj!
Pracuju na "remote console multiple-dedicated server" manageru pro Torque3D hru a trochu jsem se zasekl na psaní do StandardInput(stdin) streamu.

Psal jsem prakticky identický program pro Open Transport Tycoon, kde vše fungovalo perfektně. Nutno dodat, že outputy mi fungují. Server má na input reagovat minimálně errorem, na můj input(skrze můj manager) nereaguje vůbec nijak. Zapisuji přes StreamWriter, zkoušel jsem však i BinaryWriter.

Viz pár důležitých řádek kódu:

kód:

sessionProc = new Process();
sessionProc.StartInfo.FileName = Config.ExecPath;
sessionProc.StartInfo.UseShellExecute = false;
sessionProc.StartInfo.RedirectStandardInput = true;
sessionProc.StartInfo.RedirectStandardOutput = true;
sessionProc.StartInfo.RedirectStandardError = true;


kód:

...
StreamWriter writer = sessionProc.StandardInput;
public void Write(string input)
{
    if (writer != null)
    {
        writer.Write(input);
        writer.Flush();
    }
}


Jako bonus mám ještě v kódu úpravu binárky tak, aby se její okno dalo úplně schovat:
kód:
FileStream file = new FileStream(Config.ExecPath, FileMode.Open, FileAccess.ReadWrite);
byte[] buffer = new byte[file.Length];
file.Read(buffer, 0, buffer.Length);

int offset = (((buffer[0x3f] << 8 | buffer[0x3e]) << 8 | buffer[0x3d]) << 8 | buffer[0x3c]) + 92;

if (buffer[offset] == 2)
{
    buffer[offset] = 3;
    file.Seek(0, SeekOrigin.Begin);
    file.Write(buffer, 0, buffer.Length);
}

Ovšem input nefunguje i bez upravené binárky, takže v tom problém nebude. Uvádím jen preventivně.

Nemá někdo tušení, co můžu mít špatně? Server označuje začátek inputu znakem '%', ale to bude předpokládám jen grafické znázornění. Pokud by měl někdo alespoň nápad, co bych měl zkusit, budu si toho velmi vážit. Už třetí den si s tím nevím rady. Díky!

PS: Postřeh na závěr. Ptát se na StackOverflow asi nemá smysl, než si toho někdo všimne, zmizí to v záplavě dalších dotazů. Na oficiálním fóru se k tomu taky nikdo nevyjadřuje... Snad se na mě nevykašlete alespoň vy Very Happy
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
mar



Založen: 16. 06. 2012
Příspěvky: 608

PříspěvekZaslal: 25. červen 2015, 21:27:09    Předmět: Re: RedirectStandardInput u Torque3D dedicated serveru Odpovědět s citátem

kód:

int offset = (((buffer[0x3f] << 8 | buffer[0x3e]) << 8 | buffer[0x3d]) << 8 | buffer[0x3c]) + 92;

Tohle je typo, ne? Ať už patchuješ cokoliv Smile Pokud je offset do 64k, tak to ale bude jedno.
(Jinak s SO mám celkem dobré zkušenosti, jednou jsem se ptal na něco velmi specifického a po třech měsících mi někdo odpověděl a opravdu to můj problém vyřešilo)
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Gork



Založen: 25. 06. 2015
Příspěvky: 8

PříspěvekZaslal: 25. červen 2015, 21:36:30    Předmět: Odpovědět s citátem

Abych pravdu řekl, kód jsem převzal od nějakého chlapce z OTTD scény. Používalo se to na skrytí konzole. Neznám teorii za tím, ale funguje to. Takže místo prázdného okna původní aplikace(prázdné je, protože mám vše redirectnuté) mám jen okno své aplikace. Zkusím to ještě dohledat a pak to rozvedu Smile

UPDATE: Někde jsem našel, že je problém se zápisem do stdin, když C++ appka používá k čtení konzole f-ci ReadConsoleInput(což Torque3D využívá). Bohužel příliš kódu C++ nerozumím...
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
mar



Založen: 16. 06. 2012
Příspěvky: 608

PříspěvekZaslal: 25. červen 2015, 22:08:31    Předmět: Odpovědět s citátem

No na 0x3c je offset na PE header.
Vzhledem k tomu, že je vždycky blízko (používá se většinou jenom LSByte), tak to problém není. Teoreticky by ale být mohl.
Správně je
kód:

int offset = (((buffer[0x3f] << 24 | buffer[0x3e]) << 16 | buffer[0x3d]) << 8 | buffer[0x3c])

Na tom offsetu je typ subsystému. 3 je GUI (tj. vytváří si okno sám) a 2 je konzole.
Nicméně to tvůj problém bohužel neřeší.

EDIT: Jinak pokud se dá věřit ReactOSu, že to mají stejně jako windows,
tak WriteFile pokud je to console handle tak automaticky volá WriteConsole, jinak volá NtWriteFile, takže teoreticky by to fungovat mělo.
EDIT2: Nevšiml jsem si těch závorek, ten kód byl správně Smile


Naposledy upravil mar dne 26. červen 2015, 19:32:23, celkově upraveno 1 krát
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Gork



Založen: 25. 06. 2015
Příspěvky: 8

PříspěvekZaslal: 25. červen 2015, 23:54:44    Předmět: Odpovědět s citátem

Našel jsem o tom nějakou teorii. Pokud jsem správně pochopil, musím využít low-level zápis do input bufferu(CONIN$?). Všechno je to pro mě španělská vesnice, doufal jsem, že nikdy nebudu muset do WinAPI zabředávat(nejsem programátor, studuju medicínu).

Dokázal bys mě trochu nasměrovat? Jak zjistit handle, do kterého zapisovat? Chápu to tak, že využívají(TGE) f-ci, která "obchází" high-level redirect. Nějak jsem došel k API f-cím na CreateFile(google mě směruje na ten CONIN$) a WriteFile. Nějak mi ale nejde do hlavy, jak zjistit handle toho inputu. Asi míchám jablka s hruškama. Fakt mě z toho bolí hlava Very Happy
Díky za odpovědi a trpělivost!

EDIT: http://pastebin.com/D1g3Lx7J
Funkce konzole u TGE.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Radis



Založen: 29. 03. 2014
Příspěvky: 235

PříspěvekZaslal: 26. červen 2015, 06:52:26    Předmět: Odpovědět s citátem

Zkusil bych kombinaci FindWindow + SetForegroundWindow (WinAPI) + .NET SendKeys. Kdyz nechces, aby to okno bylo videt, tak pouzij SetWindowPos (WinAPI) a nastav oknu souradnice mimo obrazovku treba na (-2000,-2000) nebo neco takoveho. (Protoze ProcStartInfo.CreateNoWindow pouzit nemuzes, jinak bys mu nemohl posilat SendKeys). Exe soubor bych nepatchoval, je to zbytecne Smile
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Gork



Založen: 25. 06. 2015
Příspěvky: 8

PříspěvekZaslal: 26. červen 2015, 11:54:34    Předmět: Odpovědět s citátem

Chtěl jsem se co nejvíce vyhnout volání API funkcí. Z osobní zkušenosti ale můžu říct, že daleko víc vadí omylem vypnout prázdné okno serveru, než patchování exe souboru. Každopádně se o tom můžeme později pobavit, byla to spíše záležitost estetiky, kterou si mohl kdokoliv vypnout. Teď ale prosím všechny: vyjadřujte se jen k mému dotazu. Přesto si cením všech reakcí(né těch biochemických, za pár dní mě čeká zkouška Very Happy).
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Radis



Založen: 29. 03. 2014
Příspěvky: 235

PříspěvekZaslal: 26. červen 2015, 12:34:15    Předmět: Odpovědět s citátem

citace:
vyjadřujte se jen k mému dotazu

To nebylo na me, ze ne? Protoze jsem si nevsiml, ze bych mluvil nejak mimo tema Smile


Zkus to takhle nejak (FindWindow nakonec ani neni potreba, protoze handle okna se da ziskat primo z Processu):
kód:

void TestSendKeys()
{
   var procInfo = new ProcessStartInfo {
         FileName = "program.exe",
         RedirectStandardOutput = true,
         UseShellExecute = false,
      };
   var process = Process.Start(procInfo);
   IntPtr handle = IntPtr.Zero;
   while ((handle = process.MainWindowHandle) == IntPtr.Zero) {
            Thread.Sleep(10);
   }
   SetWindowPos(handle, IntPtr.Zero, -2000, -2000, 1, 1, 0);
   SetForegroundWindow(handle);
   System.Windows.Forms.SendKeys.Send("ahoj");
      
}
      
[DllImport("user32.dll", ExactSpelling = true, CharSet = CharSet.Auto)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool SetForegroundWindow(IntPtr hWnd);
      
[DllImport("user32.dll", SetLastError=true)]
static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, int flags);
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Gork



Založen: 25. 06. 2015
Příspěvky: 8

PříspěvekZaslal: 26. červen 2015, 21:59:00    Předmět: Odpovědět s citátem

Promiň, viděl jsem něco o SetWindowPos a už jsem tak nějak tušil, že se bude řešit pozice okna a jeho skrytí Very Happy

Tvé řešení bohužel nefunguje. Aplikace je bez reakce.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Zobrazit příspěvky z předchozích:   
odeslat nové téma   Odpovědět na téma    Obsah fóra České-Hry.cz -> .NET Časy uváděny v GMT + 1 hodina
Strana 1 z 1

 
Přejdi na:  
Nemůžete odesílat nové téma do tohoto fóra
Nemůžete odpovídat na témata v tomto fóru
Nemůžete upravovat své příspěvky v tomto fóru
Nemůžete mazat své příspěvky v tomto fóru
Nemůžete hlasovat v tomto fóru


Powered by phpBB © 2001, 2005 phpBB Group


Vzhled udelal powermac
Styl "vykraden" z phpBB stylu MonkiDream - upraveno by rezna