(Linux) Programm zum Starten eines Spiels



  • Hallo !

    Ich habe da ein Problem...
    und zwar möchte ich aus dem Root meines
    Linux Servers ein Half-Life Server starten...
    und auch wieder beenden können.

    Der Half-Life Server liegt dort:
    /usr/local/games/hlds_new/
    Die Datei welche ausgeführt werden soll ist
    hlds_run

    Ich weiss, dass es mit Fork und execl funktionieren sollte,
    nur leider steig ich da nicht so ganz durch
    Wenn ich das Spiel so starte:
    execl("/usr/local/games/hlds_new/hlds_run2", "HLDS", "-game", "cstrike", NULL);

    Findet er den Mod Cstrike nicht doch wenn ich es dan so starte:
    execl("/usr/local/games/hlds_new/hlds_run2", "HLDS", "-game", "/usr/local/games/hlds_new/cstrike", NULL);
    Dann wird das Script so ausgeführt, als wenn es im selben verzeichniss wie mein Programm liegt ausgeführt (im Root) weil dann die hlds_i686.so im root gesucht wird

    Ich hoffe ihr versteht mein Problem !

    Kann mir jemand helfen, wie ich das Spiel Starten und auch wieder Stoppen kann ?



  • Warum machst Du das nicht einfach mit einem Shellskript?



  • hi,
    warum fragst du das nicht im Linuxforum?

    Ich würde soetwas auch mit einem Shellscript machen, z.B.:

    > cat > script
    #!/bin/bash
    #
    cd /usr/local/games/hlds_new && ./hlds_run # noch gewünschte Parameter anhängen
    [STRG+C]
    > chmod a+x script
    > ./script
    

    Tschau Gartenzwerg



  • Dieser Thread wurde von Moderator/in Gerard aus dem Forum C++ in das Forum Linux/Unix verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • Nein mit einem Script ist das nicht lösbahr glaub ich...

    Es soll eine Art Webinterface werden...

    Erklären wir es mal so:

    Ich habe 10 Half-Life Game Server auf einem Linux Rechner laufen...

    Und nun möchte ich an mein C++ Programm nur die IP und den Port des Servers übergeben.
    So dann guckt mein Programm in einer Datei nach, welche PID der dazu passende Prozess hat. Wenn keine PID für den passenden Game-Server vorhanden ist, wird er gestartet und die PID in die Datei gespeichert (mit ip und port)

    So wenn nun die selbe IP und Port wieder übergeben wird, so soll der Game Server gestoppt werden...

    Wenn ich es mit nem Shell Script machen würde, könnte ich es gleich bei dem hlds_run Script belassen aber genau das will ich ja nicht 🙂

    Ich hoffe ihr könnt mir helfen !



  • argv[0] muss enthalten, wie dass Programm aufgerufen wurde. Also

    execl("/usr/local/games/hlds_new/hlds_run2", "/usr/local/games/hlds_new/hlds_run2", "HLDS", "-game", "cstrike", NULL);
    

    Die frage gibts so oft, steht das nicht in der FAQ?



  • nö, weil ich dachte, dass die Leute in der Lage sind die Manpage zu lesen

    man: execl(3)

    execl(3) Manpage schrieb:

    The first argument, by convention, should point to the file
    name associated with the file being executed.

    🙄



  • ich denke ihr habt mein Problem nicht verstanden...
    Wenn ich mein Game-Server so starte wie ihr sagt:

    execl("/usr/local/games/hlds_new/hlds_run", "/usr/local/games/hlds_new/hlds_run", "HLDS", "-game", "cstrike", NULL);
    

    Dann bekomme ich folgenden fehler:

    Invalid game type 'cstrike' sepecified.
    

    Wenn ich nun aber folgendes verwende:

    execl("/usr/local/games/hlds_new/hlds_run", "/usr/local/games/hlds_new/hlds_run", "HLDS", "-game", "/usr/local/games/hlds_new/cstrike", NULL);
    

    Dann hab ich nur noch das Problem, dass das Script hlds_run was ich aufruffe auch die Game *.so Datei im verzeichniss meines Programmes (in diesem Fall im Root) sucht was nicht sein dürfte... denn es soll ja in "/usr/local/games/hlds_new/ ausgeführt werden



  • 1. Warum liegt Dein Programm im Root? Da hat es doch nun garnichts zu suchen!
    2. Auf allen POSIX-konformen Platformen gibt es man: chdir. Du musst es nur noch benutzen.
    3. Ich sehe noch immer keinen Sinn darin, hier ein Extra-Programm zu schreiben. All das, was Du bisher an Anforderungen spezifiziert hast, lassen es so erscheinen, als ob das genau in die Domäne der Shell-Skripte fällt.

    Gruß Jens



  • Es geht ganz einfach darum auf einem Rechner ca 10 game Server starten zu können...

    Und diese auch gezielt wieder zu stoppen... mehr nicht



  • Ich weiss nicht ob ich zu dumm bin oder ob das normal ist...
    Wie gesagt hab nicht die besonders grosse Ahnung von Linux

    Aber...

    Nun Starte ich mein Programm
    und Forke eine PID

    ForkPID = fork();
    

    Danach gebe ich meine ForkID aus und im Child starte ich dan meinen Game Server...

    chdir("/usr/local/games/hlds_new");
    		execl("hlds_run", "hlds_run", "HLDS", "-game", "cstrike", "+map", "fy_iceworld", "+maxplayers", "16", "+sys_ticrate", "10000", "+sv_maxupdaterate", "100", NULL);
    

    So das funktioniert nun auch schon klasse...

    Die ForkID stimmt auch überein mit meinem Child...

    Nun aber das Problem... Der Child Prozess legt nen eigenes Child an (Macht HLDS automatisch)

    Wenn ich nun die von meinem Programm ausgegebene ForkID kille, bleibt aber leider der Server an, da ich nicht das Child des Childes gekillt habe 😞

    Gibt es da eine möglichkeit alle Childs vom dazu gehörigen Programm mit zu töten ? Oder das zu erkennen ?

    Was ich momentan festgestellt habe ist, dass das 2te Child immer eine ForkID + 8 hatte...

    Also wenn meine ForkID
    28102 war, ist die ID vom zweiten Child Prozess 28110
    Kann man sagen, dass das immer so ist oder muss ich irgent wie den Prozess finden ?



  • Das erzaehlst Du da von ForkID? Den Begriff gibts nicht.

    Die PID des Child-Prozesses kriegst Du im Parent als Rueckgabewert von fork().



  • Ich glaube nicht, dass er die PID des Child's kriegt die er braucht, weil er ja gerade beschrieben hat, dass der von ihm erzeuigte Child Prozess nochmal selbst ein Child erstellt, und darauf hat er keinen Zugriff mehr.
    Ich denke auch nicht, dass die +8 Regel immer gilt, denn was macht den der Server wenn die PID schon belegt ist? Gibt's nicht nen Parameter für kill, der sagt alle Child's sollen auch gekillt werden? War des nicht des mit den Zombie-Prozessen, hab ich irgendwie so im Kopf?



  • CGI-BIN schrieb:

    Ich glaube nicht, dass er die PID des Child's kriegt die er braucht, weil er ja gerade beschrieben hat, dass der von ihm erzeuigte Child Prozess nochmal selbst ein Child erstellt, und darauf hat er keinen Zugriff mehr.

    Achso, dann laesst man eben den Grossvater eine pipe erstellen, der Vater schreibt dann die PID von Sohn/Enkel da rein.

    Ich denke auch nicht, dass die +8 Regel immer gilt,

    Das sowieso nicht

    Gibt's nicht nen Parameter für kill, der sagt alle Child's sollen auch gekillt werden? War des nicht des mit den Zombie-Prozessen, hab ich irgendwie so im Kopf?

    Hmm... mein man kill kennt nichts dergleichen.



  • OK, ein Zombie ist was anderes. Des mit der Pipe dürfte auch net gehn, weil er ja nicht den Code des Vaters ändern wollen wird, oder? Aber wie ist denn der normale Vorgang um den Server zu stoppen, da wird es doch irgendwo ein shell-script dazu geben, wo man sich was abschauen kann?



  • Karigos schrieb:

    Nun aber das Problem... Der Child Prozess legt nen eigenes Child an (Macht HLDS automatisch)

    Achso, das hatte ich ueberlesen. Ich dachte, das erste Child waere auch noch von Dir. Da fallen mir jetzt so spontan 2 Moeglichkeiten ein:

    - Schau Dir alle Eintraege in /proc/*/status an, ob sie ein Child vom hlds-Prozess sind.

    - Verbinde Dich mit Deinem Programm mit dem rcon-Interface, und lass den Server sich selber beenden.



  • CGI-BIN schrieb:

    Aber wie ist denn der normale Vorgang um den Server zu stoppen, da wird es doch irgendwo ein shell-script dazu geben, wo man sich was abschauen kann?

    Der normale Weg ist, dass das Start-script oder der Server selber einen Eintrag in /var/run/$name.pid macht. Und an die Pid schickt man dann ein Signal. Aber bei hlds mach ich mir da wenig Hoffnung, dass das so funktioniert. 😞



  • Aber auch Hlds muss doch einen normalen weg zum beenden haben. Kann man da nicht aus dem Programm heraus einfach das stop-script aufrufen? oder geht das nicht bei mehreren Servern?


Anmelden zum Antworten