.:: Bots United ::.

.:: Bots United ::. (http://forums.bots-united.com/index.php)
-   Half-Life 1 SDK (http://forums.bots-united.com/forumdisplay.php?f=33)
-   -   NEW STEAM: Failure on detecting round, how do YOU do it? (http://forums.bots-united.com/showthread.php?t=748)

stefanhendriks 13-02-2004 15:12

NEW STEAM: Failure on detecting round, how do YOU do it?
 
Here is my sollution, probably many use it as i believe i got this from the forums when i just started RB :D

Code:

edict_t* pfnFindEntityByString(edict_t *pEdictStartSearchAfter, const char *pszField, const char *pszValue)
{
 // Counter-Strike - New Round Started
 if (strcmp(pszValue,"info_map_parameters") == 0) {
               
  // New round started.
  Game.SetNewRound(true);
                Game.SetRoundTime(gpGlobals->time); 
 }
  RETURN_META_VALUE (MRES_IGNORED, NULL);
}

I think the 'new optimized shit code from cs dll' does not do this anymore at round start.

Perhaps an engine message gets sent ALL THE TIME (also on dedicated server) so we can use that as a sollution?

Pierre-Marie Baty 13-02-2004 16:09

Re: NEW STEAM: Failure on detecting round, how do YOU do it?
 
Ah. Here's the pitfall.

I believe it's eLiTe who figured out this code. Anyhow... I always suspected this was not a clean way to detect round start.

I will run some tests using my o-so-handy PMtools plugin. Perhaps I can find a network message that is sent at round start and only then. Back in 2 minutes...

stefanhendriks 13-02-2004 16:15

Re: NEW STEAM: Failure on detecting round, how do YOU do it?
 
I admit this is method is probably not the most clean one, but it worked all the time, and as long as it works, don't fix things that are not broken (yet? :D)

Pierre-Marie Baty 13-02-2004 16:26

Re: NEW STEAM: Failure on detecting round, how do YOU do it?
 
HOLY SHIT!

Here's what is sent as soon as I toggle sv_restartround to 1:
Code:

PMTOOLS (HUD): NULLENT [= Game] SENDS MESSAGE type 76 ("TextMsg") in 2 ("MSG_ALL") from NULL
PMTOOLS (HUD): NULLENT [= Game] SENDS MESSAGE type 76 ("TextMsg") in 2 ("MSG_ALL") from NULL
PMTOOLS (HUD): Entity #1 (player) SENDS MESSAGE type 65 ("ReqState") in 1 ("MSG_ONE") from NULL
PMTOOLS (HUD): Entity #3 (player) SENDS MESSAGE type 65 ("ReqState") in 1 ("MSG_ONE") from NULL
PMTOOLS (HUD): Entity #1 (player) SENDS MESSAGE type 65 ("ReqState") in 1 ("MSG_ONE") from NULL
PMTOOLS (HUD): Entity #3 (player) SENDS MESSAGE type 65 ("ReqState") in 1 ("MSG_ONE") from NULL
PMTOOLS (HUD): Entity #1 (player) SENDS MESSAGE type 65 ("ReqState") in 1 ("MSG_ONE") from NULL
PMTOOLS (HUD): Entity #3 (player) SENDS MESSAGE type 65 ("ReqState") in 1 ("MSG_ONE") from NULL
PMTOOLS (HUD): NULLENT [= Game] SENDS MESSAGE type 117 ("BombPickup") in 2 ("MSG_ALL") from NULL
PMTOOLS (HUD): NULLENT [= Game] SENDS MESSAGE type 87 ("TeamScore") in 2 ("MSG_ALL") from NULL
PMTOOLS (HUD): NULLENT [= Game] SENDS MESSAGE type 87 ("TeamScore") in 2 ("MSG_ALL") from NULL
PMTOOLS (HUD): Entity #1 (player) SENDS MESSAGE type 102 ("Money") in 1 ("MSG_ONE") from NULL
PMTOOLS (HUD): Entity #1 (player) SENDS MESSAGE type 102 ("Money") in 1 ("MSG_ONE") from NULL
PMTOOLS (HUD): NULLENT [= Game] SENDS MESSAGE type 85 ("ScoreInfo") in 2 ("MSG_ALL") from NULL
PMTOOLS (HUD): Entity #2 (PMB) SENDS MESSAGE type 102 ("Money") in 1 ("MSG_ONE") from NULL
PMTOOLS (HUD): Entity #2 (PMB) SENDS MESSAGE type 102 ("Money") in 1 ("MSG_ONE") from NULL
PMTOOLS (HUD): NULLENT [= Game] SENDS MESSAGE type 85 ("ScoreInfo") in 2 ("MSG_ALL") from NULL
PMTOOLS (HUD): Entity #3 (player) SENDS MESSAGE type 102 ("Money") in 1 ("MSG_ONE") from NULL
PMTOOLS (HUD): Entity #3 (player) SENDS MESSAGE type 102 ("Money") in 1 ("MSG_ONE") from NULL
PMTOOLS (HUD): NULLENT [= Game] SENDS MESSAGE type 85 ("ScoreInfo") in 2 ("MSG_ALL") from NULL
PMTOOLS (HUD): Entity #2 (PMB) SENDS MESSAGE type 102 ("Money") in 1 ("MSG_ONE") from NULL
PMTOOLS (HUD): Entity #2 (PMB) SENDS MESSAGE type 111 ("NVGToggle") in 1 ("MSG_ONE") from NULL
PMTOOLS (HUD): Entity #2 (PMB) SENDS MESSAGE type 78 ("ResetHUD") in 1 ("MSG_ONE") from NULL
PMTOOLS (HUD): Entity #2 (PMB) SENDS MESSAGE type 102 ("Money") in 1 ("MSG_ONE") from NULL
PMTOOLS (HUD): Entity #2 (PMB) SENDS MESSAGE type 107 ("StatusIcon") in 1 ("MSG_ONE") from NULL
PMTOOLS (HUD): Entity #1 (player) SENDS MESSAGE type 84 ("ScoreAttrib") in 1 ("MSG_ONE") from NULL
PMTOOLS (HUD): Entity #2 (PMB) SENDS MESSAGE type 84 ("ScoreAttrib") in 1 ("MSG_ONE") from NULL
PMTOOLS (HUD): Entity #3 (player) SENDS MESSAGE type 84 ("ScoreAttrib") in 1 ("MSG_ONE") from NULL
PMTOOLS (HUD): Entity #2 (PMB) SENDS MESSAGE type 101 ("RoundTime") in 1 ("MSG_ONE") from NULL
PMTOOLS (HUD): Entity #2 (PMB) SENDS MESSAGE type 87 ("TeamScore") in 1 ("MSG_ONE") from NULL
PMTOOLS (HUD): Entity #2 (PMB) SENDS MESSAGE type 87 ("TeamScore") in 1 ("MSG_ONE") from NULL
PMTOOLS (HUD): Entity #2 (PMB) SENDS MESSAGE type 94 ("HideWeapon") in 1 ("MSG_ONE") from NULL
PMTOOLS (HUD): Entity #2 (PMB) SENDS MESSAGE type 95 ("SetFOV") in 1 ("MSG_ONE") from NULL
PMTOOLS (HUD): Entity #2 (PMB) SENDS MESSAGE type 72 ("Battery") in 1 ("MSG_ONE") from NULL
PMTOOLS (HUD): Entity #2 (PMB) SENDS MESSAGE type 71 ("Damage") in 1 ("MSG_ONE") from NULL
PMTOOLS (HUD): Entity #2 (PMB) SENDS MESSAGE type 69 ("FlashBat") in 1 ("MSG_ONE") from NULL
PMTOOLS (HUD): Entity #2 (PMB) SENDS MESSAGE type 73 ("Train") in 1 ("MSG_ONE") from NULL
PMTOOLS (HUD): Entity #2 (PMB) SENDS MESSAGE type 99 ("AmmoX") in 1 ("MSG_ONE") from NULL
PMTOOLS (HUD): Entity #2 (PMB) SENDS MESSAGE type 107 ("StatusIcon") in 1 ("MSG_ONE") from NULL
PMTOOLS (HUD): Entity #2 (PMB) SENDS MESSAGE type 66 ("CurWeapon") in 1 ("MSG_ONE") from NULL
PMTOOLS (HUD): Entity #2 (PMB) SENDS MESSAGE type 92 ("WeapPickup") in 1 ("MSG_ONE") from NULL
PMTOOLS (HUD): Entity #2 (PMB) SENDS MESSAGE type 92 ("WeapPickup") in 1 ("MSG_ONE") from NULL
PMTOOLS (HUD): Entity #2 (PMB) SENDS MESSAGE type 91 ("AmmoPickup") in 1 ("MSG_ONE") from NULL
PMTOOLS (HUD): Entity #1 (player) SENDS MESSAGE type 84 ("ScoreAttrib") in 1 ("MSG_ONE") from NULL
PMTOOLS (HUD): Entity #2 (PMB) SENDS MESSAGE type 84 ("ScoreAttrib") in 1 ("MSG_ONE") from NULL
PMTOOLS (HUD): Entity #3 (player) SENDS MESSAGE type 84 ("ScoreAttrib") in 1 ("MSG_ONE") from NULL
PMTOOLS (HUD): NULLENT [= Game] SENDS MESSAGE type 86 ("TeamInfo") in 2 ("MSG_ALL") from NULL
PMTOOLS (HUD): NULLENT [= Game] SENDS MESSAGE type 85 ("ScoreInfo") in 2 ("MSG_ALL") from NULL
PMTOOLS (HUD): Entity #2 (PMB) SENDS MESSAGE type 98 ("ScreenFade") in 1 ("MSG_ONE") from NULL
PMTOOLS (HUD): Entity #2 (PMB) SENDS MESSAGE type 101 ("RoundTime") in 1 ("MSG_ONE") from NULL
PMTOOLS (HUD): Entity #2 (PMB) SENDS MESSAGE type 99 ("AmmoX") in 1 ("MSG_ONE") from NULL
PMTOOLS (HUD): Entity #2 (PMB) SENDS MESSAGE type 66 ("CurWeapon") in 1 ("MSG_ONE") from NULL
PMTOOLS (HUD): Entity #2 (PMB) SENDS MESSAGE type 66 ("CurWeapon") in 1 ("MSG_ONE") from NULL
PMTOOLS (HUD): Entity #2 (PMB) SENDS MESSAGE type 74 ("HudText") in 1 ("MSG_ONE") from NULL
PMTOOLS (HUD): Entity #1 (player) SENDS MESSAGE type 65 ("ReqState") in 1 ("MSG_ONE") from NULL
PMTOOLS (HUD): Entity #3 (player) SENDS MESSAGE type 65 ("ReqState") in 1 ("MSG_ONE") from NULL
PMTOOLS (HUD): Entity #2 (PMB) SENDS MESSAGE type 69 ("FlashBat") in 1 ("MSG_ONE") from NULL
PMTOOLS (HUD): Entity #1 (player) SENDS MESSAGE type 65 ("ReqState") in 1 ("MSG_ONE") from NULL
PMTOOLS (HUD): Entity #3 (player) SENDS MESSAGE type 65 ("ReqState") in 1 ("MSG_ONE") from NULL
PMTOOLS (HUD): Entity #2 (PMB) SENDS MESSAGE type 107 ("StatusIcon") in 1 ("MSG_ONE") from NULL
PMTOOLS (HUD): Entity #1 (player) SENDS MESSAGE type 65 ("ReqState") in 1 ("MSG_ONE") from NULL
PMTOOLS (HUD): Entity #3 (player) SENDS MESSAGE type 65 ("ReqState") in 1 ("MSG_ONE") from NULL
PMTOOLS (HUD): Entity #1 (player) SENDS MESSAGE type 65 ("ReqState") in 1 ("MSG_ONE") from NULL
PMTOOLS (HUD): Entity #3 (player) SENDS MESSAGE type 65 ("ReqState") in 1 ("MSG_ONE") from NULL
PMTOOLS (HUD): Entity #1 (player) SENDS MESSAGE type 65 ("ReqState") in 1 ("MSG_ONE") from NULL
PMTOOLS (HUD): Entity #3 (player) SENDS MESSAGE type 65 ("ReqState") in 1 ("MSG_ONE") from NULL
PMTOOLS (HUD): Entity #1 (player) SENDS MESSAGE type 65 ("ReqState") in 1 ("MSG_ONE") from NULL
PMTOOLS (HUD): Entity #3 (player) SENDS MESSAGE type 65 ("ReqState") in 1 ("MSG_ONE") from NULL
PMTOOLS (HUD): Entity #1 (player) SENDS MESSAGE type 65 ("ReqState") in 1 ("MSG_ONE") from NULL
PMTOOLS (HUD): Entity #3 (player) SENDS MESSAGE type 65 ("ReqState") in 1 ("MSG_ONE") from NULL
PMTOOLS (HUD): Entity #2 (PMB) SENDS MESSAGE type 67 ("Geiger") in 1 ("MSG_ONE") from NULL
PMTOOLS (HUD): Entity #1 (player) SENDS MESSAGE type 65 ("ReqState") in 1 ("MSG_ONE") from NULL
PMTOOLS (HUD): Entity #3 (player) SENDS MESSAGE type 65 ("ReqState") in 1 ("MSG_ONE") from NULL
PMTOOLS (HUD): NULLENT [= Game] SENDS MESSAGE type 76 ("TextMsg") in 2 ("MSG_ALL") from NULL
PMTOOLS (HUD): Entity #1 (player) SENDS MESSAGE type 84 ("ScoreAttrib") in 1 ("MSG_ONE") from NULL
PMTOOLS (HUD): Entity #2 (player) SENDS MESSAGE type 84 ("ScoreAttrib") in 1 ("MSG_ONE") from NULL
PMTOOLS (HUD): Entity #3 (player) SENDS MESSAGE type 84 ("ScoreAttrib") in 1 ("MSG_ONE") from NULL
PMTOOLS (HUD): Entity #2 (player) SENDS MESSAGE type 99 ("AmmoX") in 1 ("MSG_ONE") from NULL
PMTOOLS (HUD): Entity #2 (player) SENDS MESSAGE type 66 ("CurWeapon") in 1 ("MSG_ONE") from NULL
PMTOOLS (HUD): NULLENT [= Game] SENDS MESSAGE type 76 ("TextMsg") in 2 ("MSG_ALL") from NULL
PMTOOLS (HUD): NULLENT [= Game] SENDS MESSAGE type 76 ("TextMsg") in 2 ("MSG_ALL") from NULL
PMTOOLS (HUD): NULLENT [= Game] SENDS MESSAGE type 100 ("SendAudio") in 0 ("MSG_BROADCAST") from NULL

ReqState messages are discardable, they are sent every second in the game and are part of the network pack... that's all I can say. Which one to trust, according to you ? Are messages like TeamScore sent only at map change ?

stefanhendriks 13-02-2004 16:31

Re: NEW STEAM: Failure on detecting round, how do YOU do it?
 
I don't know about teamscore, i thought i have seen it changed directly after the bomb exploded or hostages have been rescued. So i am not sure about that.

I did see a roundtimer got set too?

Pierre-Marie Baty 13-02-2004 16:53

Re: NEW STEAM: Failure on detecting round, how do YOU do it?
 
yes... the RoundTime message. What if we tested this one ?

Pierre-Marie Baty 13-02-2004 17:13

Re: NEW STEAM: Failure on detecting round, how do YOU do it?
 
WORKS!!!!!! :D :D :D

this message is sent ONLY when the round restarts ! it is NOT sent when you change the mp_roundtime CVAR !

Here's the fix, guys !

in pfnMessageBegin():
Code:

                else if (msg_type == GetUserMsgId ("RoundTime"))
                        mission.finished = TRUE; // the round has restarted


botmeister 14-02-2004 04:47

Re: NEW STEAM: Failure on detecting round, how do YOU do it?
 
PMB I looked at your plugin solution. It seems that you won't detect the very first round start because "round_end" is set to true only after the round ends. To start off, round_end should be initialized to true, that way on the first start frame the first round start will be detected.

Your code may be fine if the intention is to detect only the end of a round, but I did not dig into it that far.

*edit*

I see another problem. What about a map change before a round ends? For example, if you issue a changelevel command in the middle of a round, will the roundend message be sent? Even if the roundend message is sent, several frames may go by before the map starts to load up, and your plugin will not be aware of exactly when the first round of the new map started. It will instead think the round started before the map even started to load up.

Tosolve this, you will have to also add the round_end detection in pfnChangeLevel, in PMB's case, set the bool
Code:

round_end = true
in there. After the pfnChangeLevel function call, the next frame should be the first frame of the newly loaded map, which hopefully will also be the first frame of the round start (or close enough).

I have not yet tested any of this with the new CS 1.6 update (I am coding the changes now as I type), so don't assume I know what I'm talking about. I'll post updates once I have my updates coded and tested.

*edit*

I am assuming that the roundtime message is sent directly after a round ends, not when a round begins.

stefanhendriks 16-02-2004 12:18

Re: NEW STEAM: Failure on detecting round, how do YOU do it?
 
FINALLY BU works again.

And i got the fix too, this one is with help from Alfred. Using messages with destination MSG_SPEC...

engine.cpp
Code:

          // STEFAN
          else if (msg_dest == MSG_SPEC)
          {
                botMsgFunction = NULL;  // no msg function until known otherwise
                botMsgIndex = -1;          // index of bot receiving message (none)
                if (mod_id == CSTRIKE_DLL)
                {
                        if (msg_type == GET_USER_MSG_ID (PLID, "HLTV", NULL))
                                botMsgFunction = BotClient_CS_HLTV;
                }
          }
          // STEFAN END

botclient.cpp
Code:

// STEFAN
// This message gets sent for HLTV, according to Alfred (Valve) also
// unique for each round-start.
void BotClient_CS_HLTV(void *p, int bot_index)
{
  static int state = 0;  // current state machine state
  static int players = 0;
  /*
        From e-mail Alfred:
  // reset all players health for HLTV
 MESSAGE_BEGIN( MSG_SPEC, gmsgHLTV );
  WRITE_BYTE( 0 ); // 0 = all players
  WRITE_BYTE( 100 | 128 );
 MESSAGE_END();
 // reset all players FOV for HLTV
 MESSAGE_BEGIN( MSG_SPEC, gmsgHLTV );
  WRITE_BYTE( 0 ); // all players
  WRITE_BYTE( 0 );
 MESSAGE_END();
  */
  if (state == 0)
  {
          players = *(int *) p; // check the byte
          state++;
  }
  else if (state == 1)
  {
          // I check here on purpose. Multiple HLTV messages get sent within the game,
          // by checking for the second state i AND the 'all players' flag as above in Alfreds
          // code i hopefully elminate all faulty 'new round' detections. Testing
          // has shown me that the state machine MUST be in, else you will get "New Round"
          // detections on strange occasions!
          // We could do some cool stuff here, but all i want to know is if the
          // round has (re)started, so i just set that flag and i am done dude.
          if (players == 0)
          {
                  // New round started.
                  Game.SetNewRound(true);
                  Game.SetRoundTime(gpGlobals->time);
          }
          state = 0;
  }
}
// STEFAN - END


Pierre-Marie Baty 16-02-2004 12:55

Re: NEW STEAM: Failure on detecting round, how do YOU do it?
 
Nice... but I prefer my method. Less code involved :P

and my method always works since any map change / map start / server start calls ServerActivate(), which resets all the round and mission parameters and sets mission.finished to TRUE automatically. :)

*edit*
in CS 1.5 at least, RoundTime is sent for the first round too, so it DOES indeed catch every round START. I don't know for CS 1.6. Can one of you confirm ?

stefanhendriks 16-02-2004 13:01

Re: NEW STEAM: Failure on detecting round, how do YOU do it?
 
Well, i got word from Alfred that this is unique to the round-start function code in CS. So i'll take that code, as its only needed for round-start ;)

Pierre-Marie Baty 16-02-2004 15:56

Re: NEW STEAM: Failure on detecting round, how do YOU do it?
 
BTW, this thread rather belongs to the SDK coding forum since it's HL specific, no ?

I'm moving it there.

Terran 16-02-2004 17:36

Re: NEW STEAM: Failure on detecting round, how do YOU do it?
 
@stefanhendriks:
I'm not sure if I understood correctly. You are using Alfreds or PMBs code?

KaCaT 16-02-2004 17:43

Re: NEW STEAM: Failure on detecting round, how do YOU do it?
 
Below is the code that I'm using to detect a new round in CS 1.6 (adapted from statsme):

Code:

extern float g_fTimeNewRound;
Code:

void BotClient_CS_TextMsg (void *p, int bot_index)
{
 static bool bWillRestart;
 if (state == 0)
 {
  state++;
  return;
 }
 else if (state == 1)
 {
  bWillRestart = FALSE;

  if (strncmp("#Game_C", (char *)p , 7) == 0) // "Game Commencing!"
  g_fTimeNewRound = gpGlobals->time + 3.07;
  else if (strncmp("#Game_w", (char *)p , 7) == 0) // "The game will restart in ..."
  bWillRestart = TRUE;
 }
 else if (state == 2)
 {
  if (!bWillRestart)
  return;

  g_fTimeNewRound = gpGlobals->time + atoi((char *)p);
 }
 state++;
}

Code:

void BotClient_CS_SendAudio (void *p, int bot_index)
{
 if (state == 0)
 {
  state++;
  return;
 }
 else if (state == 1)
 {
  if ((strcmp((char *)p, "%!MRAD_terwin") == 0) || // "Terrorists Win!"
  (strcmp((char *)p, "%!MRAD_ctwin") == 0) || // "Counter-Terrorists Win!"
  (strcmp((char *)p, "%!MRAD_rounddraw") == 0)) // "Round Draw!"
  {
  g_fTimeNewRound = gpGlobals->time + 5.07;
  }
 }
}

in StartFrame()
Code:

if (g_fTimeNewRound && (g_fTimeNewRound < gpGlobals->time))
  {
  g_fTimeNewRound = 0;
  // New round detected, do what you want to do now


Pierre-Marie Baty 16-02-2004 17:52

Re: NEW STEAM: Failure on detecting round, how do YOU do it?
 
wow... does StatMe really do that ?? it's ugly :(

stefanhendriks 16-02-2004 17:54

Re: NEW STEAM: Failure on detecting round, how do YOU do it?
 
i got code from Alfred (of Valve) , he replied to my 'angry' mail at the hlcoders list...

he said that code is always called at round start (as i show above), so i rely on that.

And yes, that statsme code is very ugly.

botmeister 16-02-2004 19:16

Re: NEW STEAM: Failure on detecting round, how do YOU do it?
 
I don't like any of the methods, they are all ugly and inaccurate options to choose from. This is not my opinion, I before reading this, I did extensive tests to see if I could find a good solution, I explored each of the options mentioned and they all have problems.

At this point, the statsme code is the only code that will work most of the time, and possibly all the time.

All the other methods do not work 100% and some probably don't even work at all, like the HLTV message detection because the HLTV message is sent at regular intervals during a round and not just during a round start. I gave up on that method quickly.

The RoundTimer message is sent ONLY when there are players in a game. This may work fine for some plugins, but is of no use to plugins that require knowing when a round started no matter if there are players in game or not. Also, because the round start is detected only when the round ends, you should also check for "worldspawn" to detect a fresh mapload or first round after the server started. The problem with "worlspawn" is that there is a delay from that activity to when the round actually starts, so your timing may be off by a few seconds.

In each case, multiple messages will be detected, meaning your code will detect multiple round starts for every round start! This can lead to problems. For example, knowing when the round actually started is not accurate. If you stop your bots from moving until after the roundstart delay, your bots will be stuck for a few seconds after the delay passed depending on when the last round start message was detected.

It's just damn UGLY!

I'll keep searching for a good solution. Does anyone know how to monitor the roundtimer? That's the time telling you how much time is left in the round. I don't think this will help by itself, but it may be part of a foolproof solution.

This is what you get for hacking into someone else's code.

Pierre-Marie Baty 16-02-2004 20:00

Re: NEW STEAM: Failure on detecting round, how do YOU do it?
 
@botmeister : don't forget that we are hooking the date when the messages are being SENT, not the date at which clients receive them. And such messages are all sent in a row in the same frame, for each client in the game. Thus you won't be triggering the round start several times but only ONCE provided all you do is raising a boolean flag that you will check later on in StartFrame.

Also, as I explained, ServerActivate() DOES raise this flag too and since ServerActivate is the LAST function to be called before the first StartFrame(), I can hook map changes and server restarts like this as well. I don't find this "ugly", I find this very neat instead...



...RoundTime is not sent when no players/bots are in game ? Sure, but nevermind for me, my code does strictly nothing when there are no bots or players in game. Anyway, as soon as a player will join, the round will immediately restart. So...

botmeister 16-02-2004 20:50

Re: NEW STEAM: Failure on detecting round, how do YOU do it?
 
Quote:

Originally Posted by Pierre-Marie Baty
@botmeister : don't forget that we are hooking the date when the messages are being SENT, not the date at which clients receive them. And such messages are all sent in a row in the same frame, for each client in the game. Thus you won't be triggering the round start several times but only ONCE provided all you do is raising a boolean flag that you will check later on in StartFrame.

OK, but for some reason in my tests the messages are being delayed, perhaps my code has a problem. No matter, I won't be considering the roundtime option anyway because it is not universal (requires players in game) and I don't want to deal with multiple messages if I don't have to.

Quote:

Also, as I explained, ServerActivate() DOES raise this flag too and since ServerActivate is the LAST function to be called before the first StartFrame(), I can hook map changes and server restarts like this as well. I don't find this "ugly", I find this very neat instead...
OK, I'll try ServerActivate(), that sounds like a good solution to the worldspawn delay. For it to work it has to get called on each map start, even if the same map is reloaded, and if the map is loaded manually using commands from the server console or from a timeout. Are you sure it will do this in every case?

I have to correct myself. The HLTV message check actually DOES appear to be the very best solution. I missed the obvious, and it's what Stephan's function points out, you have to look for a message that looks like this:

Message_Begin
MessageType: 125
MessageDest: 9
WriteByte : 0
WriteByte : 0
Message_End

This form of message appears to be sent only once after a round ends. The in round messages have nonzero values for each byte, although more tests are needed to confirm this. So using it, along with the ServerActivate() function hook (as PMB points out) should give us a fool proof and universal method of detecting a round start.

Quote:

...RoundTime is not sent when no players/bots are in game ? Sure, but nevermind for me, my code does strictly nothing when there are no bots or players in game. Anyway, as soon as a player will join, the round will immediately restart. So...
Yes, I agree the RoundTime solution may work for you, but it won't work for some other plugins. In your case, you may want to detect a roundstart only if there are bots in a game, so you could even check to see if the messages are being sent to bots or not. However, the tests I did gave me a long delay from when the last message was sent and when the round actually started, but if you don't have this same problem, then the problem may be with my code. In any case, I still like the HLTV message solution best :)

Pierre-Marie Baty 16-02-2004 21:30

Re: NEW STEAM: Failure on detecting round, how do YOU do it?
 
Regarding ServerActivate(), yes, it is called everytime a new map boots in. Actually a new map means a new server ; each time you change level (even in single player with level transitions), or force a level restart, in whatever manner you want, you will force a call to ServerDeactivate() immediately after the last StartFrame() in which the command was triggered, and a call to ServerActivate() immediately before the first StartFrame() of the new map.

<facultative>
Why I'm reluctant to using HLTV messages is that HLTV is an "external" application using a not-so-well defined protocol, that changes very often. And the purpose of HLTV messages is not for notifying players of a round change, actually if this code is specific to a round change in CS it's pure coincidence ; and on the contrary, notifying clients of a change in the round timer is exactly the point of RoundTime messages...
</facultative>

botmeister 16-02-2004 22:16

Re: NEW STEAM: Failure on detecting round, how do YOU do it?
 
Quote:

Originally Posted by Pierre-Marie Baty
Regarding ServerActivate(), yes, it is called everytime a new map boots in. Actually a new map means a new server ; each time you change level (even in single player with level transitions), or force a level restart, in whatever manner you want, you will force a call to ServerDeactivate() immediately after the last StartFrame() in which the command was triggered, and a call to ServerActivate() immediately before the first StartFrame() of the new map.

<facultative>
Why I'm reluctant to using HLTV messages is that HLTV is an "external" application using a not-so-well defined protocol, that changes very often. And the purpose of HLTV messages is not for notifying players of a round change, actually if this code is specific to a round change in CS it's pure coincidence ; and on the contrary, notifying clients of a change in the round timer is exactly the point of RoundTime messages...
</facultative>

I see your points, but in my case I need to know about round starts no matter if there are players in game or not, so my options are limited to those that do not depend on players being in the game.

I do think that HLTV would need to know about round starts even if there are no players in the game - no?

Lazy 16-02-2004 22:35

Re: NEW STEAM: Failure on detecting round, how do YOU do it?
 
If you're looking for round events try looking in pfnAlertMessage.

The at_logged event should have something like...
"world" triggered "Round_Start", ect.

Unfortunately, the site that hosted information about logs and the standard format is gone so I'm going by memory on this.

botmeister 17-02-2004 00:02

Re: NEW STEAM: Failure on detecting round, how do YOU do it?
 
Quote:

Originally Posted by Lazy
If you're looking for round events try looking in pfnAlertMessage.

The at_logged event should have something like...
"world" triggered "Round_Start", ect.

Unfortunately, the site that hosted information about logs and the standard format is gone so I'm going by memory on this.

The log message looks like this:
L 01/01/2004 - 01:25:55: World triggered "Round_Start"

You can also look for this one:
L 01/01/2004 - 01:25:55: World triggered "Game_Commencing"

and this
L 01/01/2004 - 01:26:21: World triggered "Round_End"

Thanks Lazy for this idea :)

Pierre-Marie Baty 17-02-2004 00:09

Re: NEW STEAM: Failure on detecting round, how do YOU do it?
 
It works ! I side with this method too.

If you're interested I have updated my PMTools plugin to make it hook pfnAlertMessage()s and send them directly on the listenserver's HUD.

botmeister 17-02-2004 01:26

Re: NEW STEAM: Failure on detecting round, how do YOU do it?
 
Quote:

Originally Posted by Pierre-Marie Baty
It works ! I side with this method too.

If you're interested I have updated my PMTools plugin to make it hook pfnAlertMessage()s and send them directly on the listenserver's HUD.

Looks like a simple and reliable method. I'll give it a try. Will get the updated PMTools of course - can't live without it :)

Terran 17-02-2004 10:00

Re: NEW STEAM: Failure on detecting round, how do YOU do it?
 
That's funny, I always thought that you're aware of this message and simply don't reply upon it because of some timing issues :-)

botmeister 17-02-2004 10:02

Re: NEW STEAM: Failure on detecting round, how do YOU do it?
 
Bah! I'm back with the HLTV method. Take a look at this test log.

Code:

00:42:00 2004 :: World triggered "Round_End"
00:42:05 2004 :: THE ROUND HAS REALLY STARTED
00:42:12 2004 :: World triggered "Round_Start"

Look at the times above, the "Round_End" pfnAlertMessage happens just before the round really ends. It is issued as soon as the round timer goes to zero, but the round does not switch to a new round until about 5 seconds afterwards. The pfnAlertMessage "Round_Start" does not happen until the countdown delay completes. In other words, it gets issued a few seconds after the round really starts (the delay is 7 seconds in the example).

This may work fine for other people, but it is no good to me as I need to know exactly when a round really starts.

*edit*

Quote:

That's funny, I always thought that you're aware of this message and simply don't reply upon it because of some timing issues :-)
LOL just saw your message after I posted - yes, this is funny because I can't use it because of the timing issues!

*edit*

FYI: the Round_End message gets sent only when a round times out. It will not get sent if the round is cut short by other means.

Terran 17-02-2004 10:16

Re: NEW STEAM: Failure on detecting round, how do YOU do it?
 
The Round_Start message is send when the "freezetime" is over? In that case you could use for other purposes :-)

botmeister 17-02-2004 22:13

Re: NEW STEAM: Failure on detecting round, how do YOU do it?
 
OK, I've finally settled on a solution that works great for me. For those who are interested, I've done the following:

1. Hook onto pfnServerActivate. This tells me when a new round has starting after a map load. I set a bool flag indicating that a round is just about to start: RoundStart = true;

2. Hook onto message "HLTV". If the two bytes in the message are both zero, then this tells me a round has just started. RoundStart = true; Note: This message is sent ONLY after a round is ended and at the same time the new round has started - there's no delay between the message and the start of the new round. It will get sent no matter how the round has been ended, and not just when the round times out.

3. Optional: Hook onto pfnStartFrame
Code:

If (RoundStart)
{
        RoundStart = false;
        // round has started - do whatever is needed;
 
}

This hook is optional because you could simply activate your round_start code in both the "HLTV" message hook, and in the pfnServerActivate hook.

Austin 17-02-2004 23:28

Re: NEW STEAM: Failure on detecting round, how do YOU do it?
 
Quote:

Originally Posted by botmeister
OK, I've finally settled on a solution that works great for me. For those who are interested, I've done the following:

Clean!
Cool!

Botmesiter, you said:
"Hook onto message "HLTV". If the two bytes in the message are both zero, "

Could you please post some sample code on how to do this?
Thanks...

Pierre-Marie Baty 18-02-2004 00:39

Re: NEW STEAM: Failure on detecting round, how do YOU do it?
 
code aesthetes aren't we...

weirdos united ! :D


All times are GMT +2. The time now is 02:30.

Powered by vBulletin® Version 3.8.2
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.