AdminMod.de
https://www.adminmod.de/

Timeleft (DLL-Coding)
https://www.adminmod.de/viewtopic.php?t=4301
Seite 1 von 1

Autor:  Warhead [ 29.10.2002, 14:48 ]
Betreff des Beitrags:  Timeleft (DLL-Coding)

Sorry für diesen neuen Thread, aber er behandelt nicht die banalen Probleme die jeder Newbie sonst mit AM hat. Er richtet sich speziell an die Leute, die sich mit der Programmierung von AM beschäftigen (daRope,[WING]Black Knight) bzw. sich mit dem Quellcode von AM auseinandergesetzt haben.

Ich habe mir mal den Code zum Timeleftproblem in CS angeschaut. Dieser "Hack" funktioniert nur deshalb, weil unter Linux die CS-Multiplayerlib mit einem Linker gelinkt wurde, der defaultmäßig alle Symbole exportiert. Und genau deshalb funktioniert die ganze Sache nicht unter Windows, denn dort müssen die exportierten Symbole explizit angegeben werden. Die ganze Sache funktioniert unter Linux nur so lange, wie diese Option nicht geändert wird.
Es gibt dann aber scheinbar trotzdem noch Probleme bei der Berechnung, die bei Servern die unter hoher Last stehen ungenaue Ergebnisse liefert. Soweit ich das gesehen habe, haben die CS-Coder eine neue Funktion CHalfLifeMultiplay::TimeRemaining(void) zusätzlich implementiert. Hat man damit schonmal probiert, die exakte Restzeit zu bestimmen?

Btw, es gibt noch einen kleinen Bug beim Attachen des Symbols den ich nur zufällig beim man-lesen herausgefunden habe (ich habs vorher auch nicht gewusst):

dlsym takes a "handle" of a dynamic library returned by dlopen and the null terminated symbol name,
returning the address where that symbol is loaded. If the symbol is not found, dlsym returns NULL; how­
ever, the correct way to test for an error from dlsym is to save the result of dlerror into a variable,
and then check if saved value is not NULL. This is because the value of the symbol could actually be
NULL. It is also necessary to save the results of dlerror into a variable because if dlerror is called
again, it will return NULL.

Es könnte also sein, dass die zurückgelieferte Adresse NULL korrekt ist, weil sich das Symbol dort befindet. Im AM-Code wird nur auf NULL des Symbols getestet. Zugegeben, die Chancen dass dieser Fall mal eintritt sind zu gering, um hier von einem Bug zu sprechen...

Autor:  [WING] Black Knight [ 30.10.2002, 00:11 ]
Betreff des Beitrags: 

Zuviel der Ehre.
Ich habe mir den Quellcode von AM mal angesehen. Auf Grund fehlender C-Kenntnisse konnte ich aber nur ansatzweise Infos rausholen. Meine Informationen stammen daher von daRope direkt bzw. dem Betateam.
Die Idee/Prinzip zum Verbessern des nextmap's stammt von mir, aber die Umsetzung überlasse ich den Profis. ;)
Wenn Du helfen möchtest, ist Deine Hilfe wahrscheinlich gern genommen. Solltest Dich mal an daRope per E-Mail wenden.

Autor:  daRope [ 03.11.2002, 19:42 ]
Betreff des Beitrags:  Re: Timeleft (DLL-Coding)

Zitat:
Dieser "Hack" funktioniert nur deshalb, weil unter Linux die CS-Multiplayerlib mit einem Linker gelinkt wurde, der defaultmäßig alle Symbole exportiert.
Nur globale.
Zitat:
Die ganze Sache funktioniert unter Linux nur so lange, wie diese Option nicht geändert wird.
Ehm, das ist wohl auch hoechst unwahrscheinlich. :) Wahrscheinlicher ist, dass die Windowsversion von CS die benoetigten Symbole in Zukunft ebenfalls exportiert. ;)
Zitat:
Soweit ich das gesehen habe, haben die CS-Coder eine neue Funktion CHalfLifeMultiplay::TimeRemaining(void) zusätzlich implementiert. Hat man damit schonmal probiert, die exakte Restzeit zu bestimmen?
Ich vermute mal, dass das nicht viel bringt.Ich muesste mich ueber ein paar Details der Funktion erst schlau machen, aber ich vermute mit hoher Sicherheit folgende zwei Dinge:
1) Diese Funktion ist ebensowenig exportiert. (Oder meintest Du unter Linux?)
2) Das ist keine static member function.

Beides verhindert ihren Einsatz von aussen.

Wenn Du wissen willst, wie CS die timeleft berechnet, dann kuck mal in admin_commands.cpp::timeleft(). :) Es gibt noch einen Unterschied im CS code, der eben bei sv_restartround die Zeit entsprechend umsetzt. Der Unterschied liegt also im setzen einer globalen Variable, nicht in der Berechnung der Restzeit aus derselbigen. Mehr kann (darf) ich Dir hier nicht darueber sagen.

Zitat:
Es könnte also sein, dass die zurückgelieferte Adresse NULL korrekt ist, weil sich das Symbol dort befindet. Im AM-Code wird nur auf NULL des Symbols getestet. Zugegeben, die Chancen dass dieser Fall mal eintritt sind zu gering, um hier von einem Bug zu sprechen...
Sicherlich eine NAchlaessigkeit, auch wenn das entsprechende Symbol mit Sicherheit nicht an Adresse 0 liegt. :)


Wenn Dein Linux Server trotzdem Unterschiede in der timeleft aufweist, waere ich an einer systematischen Untersuchung durchaus weiter interessiert.

Autor:  Warhead [ 03.11.2002, 22:24 ]
Betreff des Beitrags:  Re: Timeleft (DLL-Coding)

Zitat:
1) Diese Funktion ist ebensowenig exportiert. (Oder meintest Du unter Linux?)
Die Exports sind dann natürlich nur bei Linux...
Zitat:
2) Das ist keine static member function.
Unter den Symbolen wird doch bestimmt ein Multiplay-Objekt zu finden sein (während der Laufzeit).
Zitat:
Wenn Du wissen willst, wie CS die timeleft berechnet, dann kuck mal in admin_commands.cpp::timeleft(). :) Es gibt noch einen Unterschied im CS code, der eben bei sv_restartround die Zeit entsprechend umsetzt. Der Unterschied liegt also im setzen einer globalen Variable, nicht in der Berechnung der Restzeit aus derselbigen. Mehr kann (darf) ich Dir hier nicht darueber sagen.
Also eine Berechnung findet da immer noch statt:
Code:
  // fuer CS
  flTimeLimit = *g_pflTimeLimit;

  // Berechnung
  int timeleft = (int)(flTimeLimit - gpGlobals->time);

Das g_pflTimeLimit ist dabei an das Symbol aus der Lib attached (wird in der h_export.cpp gemacht).
Das Timelimit scheint damit nun korrekt zu sein. Es kann also nur noch an der verstrichenen Zeit, die über die gpGlobals geliefert wird, liegen.

Autor:  daRope [ 04.11.2002, 00:27 ]
Betreff des Beitrags:  Re: Timeleft (DLL-Coding)

Zitat:
Unter den Symbolen wird doch bestimmt ein Multiplay-Objekt zu finden sein (während der Laufzeit).
Nein. Du findest den Code zu der Memberfunktion, aber Dir fehlt das Objekt dazu, sprich der implizite this Pointer. Daher bekommst Du nur Speichermuell. Dafuer gibt es ja eben static members.

Zitat:
Code:
  // fuer CS
  flTimeLimit = *g_pflTimeLimit;

  // Berechnung
  int timeleft = (int)(flTimeLimit - gpGlobals->time);

Das g_pflTimeLimit ist dabei an das Symbol aus der Lib attached (wird in der h_export.cpp gemacht).
Das Timelimit scheint damit nun korrekt zu sein. Es kann also nur noch an der verstrichenen Zeit, die über die gpGlobals geliefert wird, liegen.
Es wird etwas berechnet. Und, ich will es mal so ausdruecken, die Wahrscheinlichkeit steht sehr hoch, dass es exakt so berechnet wird, wie in CS. :)

Pruefe doch mal bitte, mit welcher Systematik eine Verschiebung auftaucht. Ist das konstant? Tritt das von Anfang an auf? Ist das proportional zu Restarts? Haben alle Clients die exakt gleiche Anzeige bei CS timeleft? Usw...

Seite 1 von 1 Alle Zeiten sind UTC+01:00
Powered by phpBB® Forum Software © phpBB Limited
https://www.phpbb.com/