Server Help

ASSS Questions - Goal callback

Icebird - Thu Sep 25, 2008 11:24 am
Post subject: Goal callback
Hi.

I setup a callback for CB_GOAL. The module looks like this:

Code: Show/Hide

...

local void SSSC_GoalAction(Arena *arena, Player *p, int bid, int x, int y)
{   
   chat->SendArenaMessage(arena, "SSSC_game - Goal detected");
}

// The entry point:
EXPORT int MM_sssc_game(int action, Imodman *mm_, Arena *arena)
{
   int rv = MM_FAIL; // return value

   if (action == MM_LOAD)
   {
      mm = mm_;

      ball = mm->GetInterface(I_BALLS, ALLARENAS);
      game = mm->GetInterface(I_GAME, ALLARENAS);
      stats = mm->GetInterface(I_STATS, ALLARENAS);
      pd = mm->GetInterface(I_PLAYERDATA, ALLARENAS);
      chat = mm->GetInterface(I_GAME, ALLARENAS);

      if (!ball || !game || !stats || !pd || !chat)
      {
         // release interfaces if loading failed
         mm->ReleaseInterface(ball);
         mm->ReleaseInterface(game);
         mm->ReleaseInterface(stats);
         mm->ReleaseInterface(pd);
         mm->ReleaseInterface(chat);
         rv = MM_FAIL;
      }
      else
      {
         // callbacks
         mm->RegCallback(CB_GOAL, SSSC_GoalAction, ALLARENAS);
         rv = MM_OK;
      }
   }

...


I never see the arena message in SSSC_GoalAction. I only see the standard

"Team Goal! by Icebird
SCORE: Evens:1 Odds:0
Soccer game over."

sssc_game + balls in modules.conf [OK]
sssc_game + balls in arena.conf [OK]
?lsmod shows sssc_game + balls [OK]

settings:
Code: Show/Hide

[Soccer]
DisableWallPass=1
DisableBallKilling=0
BallBounce=1
AllowBombs=1
AllowGuns=1
PassDelay=10
Mode=1
BallBlankDelay=200
UseFlagger=0
BallLocation=1
BallCount=1
SendTime=200
Reward=0
CapturePoints=-1
CatchMinimum=1
CatchPoints=1
WinBy=1

Dr Brain - Thu Sep 25, 2008 4:24 pm
Post subject:
What's ?lsmod -a show?
Icebird - Thu Sep 25, 2008 5:50 pm
Post subject:
It shows

Modules attached to arena 0:
fg_turf, points_goal, points_flag, points_kill, points_periodic, fm_shiplimits

in arena.conf i have:

AttachModules = \
fm_shiplimits \
points_periodic \
points_kill \
points_flag \
points_goal \
balls \
pymod \
fg_turf \
watchdamage \
sssc_spawn \
sssc_shields \
sssc_game
Dr Brain - Thu Sep 25, 2008 9:22 pm
Post subject:
Odd that so few are attached when you try to attach so many.

I know for a fact that pymod doesn't attach to arenas. I'm guessing the same is true for balls.

But that's not your issue. Put a lm->Log in when you register the callback and make sure it's actually getting registered. If it is, run a debugger and breakpoint on the DO_CBS for CB_GOAL in balls.c, then step through and see why your module isn't getting called.
Hakaku - Fri Sep 26, 2008 12:13 am
Post subject:
This is just a guess, since the rest of the code isn't there, but I'd assume the reason why the module isn't getting attached to the arena is because the following is missing :
Code: Show/Hide
    else if (action == MM_ATTACH)
    {
        rv = MM_OK;
    }
    else if (action == MM_DETACH)
    {
        rv = MM_OK;
    }

Also, I hope that you specified the following somewhere at the top:
Code: Show/Hide

#include "balls.h"
local Iballs *ball;

If you're still at a loss, I've attached an example of a simple module that uses the goal callback, which you could use to compare what you have.
Icebird - Fri Sep 26, 2008 4:39 am
Post subject:
I never used MM_ATTACH/DETACH in my own modules. However the first two (sssc_shields & sssc_spawn) worked without it. I added Hakaku's code for MM_ATTACH/DETACH to sssc_game. It is listed in ?lsmod -a but it doesn't work.

I use #include "asss.h" which includes "balls.h".

I logged it and I see the log message in the asss console so the "error" probably is in balls.c. Unfortuantely I don't know how to debug the dll (using Dev-C++).
Dr Brain - Fri Sep 26, 2008 6:36 am
Post subject:
Attaching is nice for things that shouldn't apply to every arena. It's not related to the problem at hand, though, as the goal callback should work the way you've registered it.

Are you compiling the entire core with Dev-C++? If so, you should just be able to run asss.exe in its debugger after setting a breakpoint on the correct line in balls.c. When it gets there, it'll stop and you should be able to step through each line. Just a hint: it sometimes helps to unload the deadlock module first.
Icebird - Fri Sep 26, 2008 8:08 am
Post subject:
My project only contains sssc_game.c and util.c.

balls.c:
Code: Show/Hide

void PGoal(Player *p, byte *pkt, int len)
{
   Arena *arena = p->arena;
   ArenaBallData *abd = P_ARENA_DATA(arena, abdkey);
   MyBallData *pbd = P_ARENA_DATA(arena, pbdkey);
   int bid;
   struct C2SGoal *g = (struct C2SGoal*)pkt;
   struct BallData *bd;

   if (len != sizeof(struct C2SGoal))
   {
      logm->LogP(L_MALICIOUS, "balls", p, "bad size for goal packet");
      return;
   }

   if (!arena || p->status != S_PLAYING)
   {
      logm->LogP(L_WARN, "balls", p, "goal packet from bad arena or status");
      return;
   }

   LOCK_STATUS(arena);

   bid = g->ballid;

   if (bid < 0 || bid >= abd->ballcount)
   {
      logm->LogP(L_MALICIOUS, "balls", p, "sent a goal for a nonexistent ball");
      UNLOCK_STATUS(arena);
      return;
   }

   bd = abd->balls + bid;

   /* we use this as a flag to check for dupilicated goals */
   if (bd->carrier == NULL)
   {
      UNLOCK_STATUS(arena);
      return;
   }

   if (bd->state != BALL_ONMAP)
   {
      logm->LogP(L_WARN, "balls", p, "state sync problem: sent goal for carried ball");
      UNLOCK_STATUS(arena);
      return;
   }

   if (p != bd->carrier)
   {
      logm->LogP(L_MALICIOUS, "balls", p, "sent goal for ball he didn't fire");
      UNLOCK_STATUS(arena);
      return;
   }

   /* do callbacks before spawning */
   DO_CBS(CB_GOAL, arena, GoalFunc, (arena, p, g->ballid, g->x, g->y));


All those if statements write some log message, except "if (bd->carrier == NULL)". As I see none of these messages in the console after scoring a goal it must be this if-block that returns before the DO_CBS is reached, no? why would the carrier be NULL?
Dr Brain - Fri Sep 26, 2008 1:14 pm
Post subject:
No, because the other arena messages you're seeing only happen if the DO_CBS gets executed. So the question isn't if it's happening, the question is why isn't yours included.
tcsoccerman - Fri Sep 26, 2008 3:33 pm
Post subject:
If i was debugging this, i would be sure to have a chat->SendArenaMessage or a log that is not in an if statememt, because what if all those if statements return false, and don't execute.
Hakaku - Fri Sep 26, 2008 7:03 pm
Post subject:
Icebird wrote:
I never used MM_ATTACH/DETACH in my own modules. However the first two (sssc_shields & sssc_spawn) worked without it. I added Hakaku's code for MM_ATTACH/DETACH to sssc_game. It is listed in ?lsmod -a but it doesn't work.
Yeah, from your arena.conf file, it seemed as if you wanted to attach them to the arena. This isn't necessary if you use "ALLARENAS" (instead of just "arena"), which is why the other two modules work despite not being attached. It's not an actual fix for your problem though.

Icebird wrote:
I logged it and I see the log message in the asss console so the "error" probably is in balls.c. Unfortuantely I don't know how to debug the dll (using Dev-C++).
Unless you modified the core file, there shouldn't be any issues with the callback in balls.c (try compiling my example and test it out to see if it works). I'm guessing, that the problem lies within a part of your module that you aren't showing us. Are you sure that the line " local Iballs *ball; " is present?
Icebird - Sun Sep 28, 2008 6:02 am
Post subject:
OK, I think it is better to post the whole code:

Code: Show/Hide

#include "asss.h"

#define SSSC_VERBOSE 1

// Interfaces
local Imodman *mm;
local Iballs *ball;
local Igame *game;
local Istats *stats;
local Iplayerdata *pd;
local Ichat *chat;
local Ilogman *lm;

// This function is called when a goal is scored
local void SSSC_GoalAction(Arena *arena, Player *p, int bid, int x, int y)
{   
   Player *player;
   Link *link;
   
   if (SSSC_VERBOSE) chat->SendArenaMessage(arena, "SSSC_game - Goal detected");
   
   pd->Lock();

   FOR_EACH_PLAYER(player)
   {
      if (SSSC_VERBOSE) chat->SendMessage(player, "SSSC_game - Preparing for restart");
      // warp the player back to the spawn
      if (p->status == S_PLAYING)
      {
         Target t;
         t.type = T_PLAYER;
         t.u.p = player;
         
         if (SSSC_VERBOSE) chat->SendMessage(player, "SSSC_game - Warping you back to spawn");
         
   //      if (x < 0 || y < 0)
   //      {
   //         if (SSSC_VERBOSE) chat->SendArenaMessage(player->arena, "SSSC_spawn - Invalid warp coordinates for %s [%i,%i]", player->name, aw->x, aw->y);
   //         continue;
   //      }
   //      game->WarpTo(&t, aw->x, aw->y);
         game->ShipReset(&t);
      }
      
      // reset his points
      
   }
   
   pd->Unlock();
   
   stats->SendUpdates(NULL);
}

// The entry point:
EXPORT int MM_sssc_game(int action, Imodman *mm_, Arena *arena)
{
   int rv = MM_FAIL; // return value

   if (action == MM_LOAD)
   {
      mm = mm_;

      ball = mm->GetInterface(I_BALLS, ALLARENAS);
      game = mm->GetInterface(I_GAME, ALLARENAS);
      stats = mm->GetInterface(I_STATS, ALLARENAS);
      pd = mm->GetInterface(I_PLAYERDATA, ALLARENAS);
      chat = mm->GetInterface(I_GAME, ALLARENAS);
      lm = mm->GetInterface(I_LOGMAN, ALLARENAS);

      if (!ball || !game || !stats || !pd || !chat || !lm)
      {
         // release interfaces if loading failed
         mm->ReleaseInterface(ball);
         mm->ReleaseInterface(game);
         mm->ReleaseInterface(stats);
         mm->ReleaseInterface(pd);
         mm->ReleaseInterface(chat);
         mm->ReleaseInterface(lm);
         rv = MM_FAIL;
      }
      else
      {
         // callbacks
         mm->RegCallback(CB_GOAL, SSSC_GoalAction, ALLARENAS);
         lm->Log(L_INFO, "<SSSC_game> registered CB_GOAL");

         // timers
         // times are in centiseconds

         // commands

         rv = MM_OK;
      }
   }
   else if (action == MM_UNLOAD)
   {   
      // clear timers

      // unregister callbacks
      mm->UnregCallback(CB_GOAL, SSSC_GoalAction, ALLARENAS);

      // free allocated data

      // release interfaces
      mm->ReleaseInterface(ball);
      mm->ReleaseInterface(game);
      mm->ReleaseInterface(stats);
      mm->ReleaseInterface(pd);
      mm->ReleaseInterface(chat);
      mm->ReleaseInterface(lm);
      rv = MM_OK;
   }
   else if (action == MM_ATTACH)
    {
        rv = MM_OK;
    }
    else if (action == MM_DETACH)
    {
        rv = MM_OK;
    }

   return rv;
}

Dr Brain - Sun Sep 28, 2008 8:15 am
Post subject:
Here's your issue
Code: Show/Hide
chat = mm->GetInterface(I_GAME, ALLARENAS);

it's a miracle it doesn't crash.
Icebird - Sun Sep 28, 2008 12:43 pm
Post subject:
Aw, thank you so much. It works no (no wonder biggrin.gif) I'll have to be more careful in the future with those interfaces.
All times are -5 GMT
View topic
Powered by phpBB 2.0 .0.11 © 2001 phpBB Group