Online game, coding problems. - Link - 06-19-2011
I ran an online game since about 2002, Coded with c, java, perl and cgi.
When Linux updated higher than Linux Kernel 2.6.17 My game started posing errors. Then it started crashing. I have about 3 out of 4 problems fixed, If I post my examples of problems can I get assistance in probably fixing the last one?
My game ran the function, gettip to gettid to make this function look like this
example #1 -
c->game->clientPid = gettip(); original
c->game->clientPid = gettid(); updated
example #2 -
I had to add something to make gettid(); work so I added this.
/************************************************************************
/
/ FUNCTION NAME: gettid()
/
/ FUNCTION: get the child processes id
/
/ ARGUMENTS:
/
/
*************************************************************************/
pid_t gettid(void) {
pid_t ret;
__asm__("int $0x80" : "=a" (ret) : "0" (224) /* SYS_gettid */);
if (ret < 0){
ret = -1;
}
return ret;
}
The result of replacing all gettips to gettid and adding the function allowed my game to boot properly.
Now this one. Everytime I suspended a bad member to the "Wizard Channel", and they tried talking in it, the game would crash.
THIS IS THE OLD FUNCTION
Do_suspend(struct client_t *c, struct event_t *the_event)
{
sigset_t sigMask;
int theAnswer, oldChannel;
bool oldMute, oldVirtual;
double oldEnergy;
char string_buffer[SZ_LINE];
char error_msg[SZ_ERROR_MESSAGE];
/* prepare to unblock SIGIO */
sigprocmask(0, NULL, &sigMask);
sigdelset(&sigMask, SIGIO);
/* set the suspended flag */
c->suspended = TRUE;
oldChannel = c->channel;
c->channel = 9;
oldMute = c->hearBroadcasts;
c->hearBroadcasts = TRUE;
Do_lock_mutex(&c->realm->realm_lock);
Do_player_description©;
oldVirtual = c->game->virtual;
c->game->virtual = TRUE;
Do_unlock_mutex(&c->realm->realm_lock);
Do_send_specification(c, CHANGE_PLAYER_EVENT);
Do_send_clear©;
sprintf(string_buffer, "Your game has been suspended by the Wizard %s. Until released, you will only be heard by game-wizard characters.\n", the_event->arg4);
Do_send_line(c, string_buffer);
free((void *)the_event->arg4);
Do_send_line(c, "Closing the window will kill your character and give you a ban.\n");
while(c->suspended) {
/* before we wait, send anything in the buffer */
Do_send_buffer©;
/* wait for a signal to proceed */
sigsuspend(&sigMask);
Do_get_nothing©;
Do_check_events_in©;
if (c->run_level == EXIT_THREAD || c->socket_up == FALSE) {
c->suspended = FALSE;
c->run_level = EXIT_THREAD;
return;
}
}
Do_more©;
Do_send_clear©;
c->channel = oldChannel;
c->hearBroadcasts = oldMute;
Do_lock_mutex(&c->realm->realm_lock);
Do_player_description©;
c->game->virtual = oldVirtual;
Do_unlock_mutex(&c->realm->realm_lock);
Do_send_specification(c, CHANGE_PLAYER_EVENT);
return;
}
THIS IS WHAT I REPLACED IT WITH
Do_suspend(struct client_t *c, struct event_t *the_event)
{
sigset_t sigMask;
int theAnswer, oldChannel;
bool oldMute, oldVirtual;
double oldEnergy;
char string_buffer[SZ_LINE];
char error_msg[SZ_ERROR_MESSAGE];
/* prepare to unblock SIGIO */
sigprocmask(0, NULL, &sigMask);
sigdelset(&sigMask, SIGIO);
/* set the suspended flag */
c->suspended = TRUE;
oldChannel = c->channel;
c->channel = 9;
oldMute = c->hearBroadcasts;
c->hearBroadcasts = TRUE;
Do_lock_mutex(&c->realm->realm_lock);
Do_player_description©;
oldVirtual = c->game->virtual;
c->game->virtual = TRUE;
Do_unlock_mutex(&c->realm->realm_lock);
Do_send_specification(c, CHANGE_PLAYER_EVENT);
Do_send_clear©;
sprintf(string_buffer, "Your game has been suspended by %s. Until released, you will only be heard by game-wizard characters.\n", the_event->arg4);
Do_send_line(c, string_buffer);
free((void *)the_event->arg4);
Do_send_line(c, "Closing the window will kill your character.\n");
while(c->suspended) {
/* before we wait, send anything in the buffer */
Do_send_buffer©;
/* wait for a signal to proceed */
/* if we run sigsuspend, we crash, why? who knows
sigsuspend(&sigMask);
*/
/* so just sleep for a second instead, same result, just choppy chat */
sleep(1);
Do_get_nothing©;
Do_check_events_in©;
if (c->run_level == EXIT_THREAD || c->socket_up == FALSE) {
c->suspended = FALSE;
c->run_level = EXIT_THREAD;
return;
}
}
Do_more©;
Do_send_clear©;
c->channel = oldChannel;
c->hearBroadcasts = oldMute;
Do_lock_mutex(&c->realm->realm_lock);
Do_player_description©;
c->game->virtual = oldVirtual;
Do_unlock_mutex(&c->realm->realm_lock);
Do_send_specification(c, CHANGE_PLAYER_EVENT);
return;
}
You can see what I did to improve it. After that part in the loop was fixed the game would stop crashing. Because that was fixed the game stopped randomly crashing aswell fixing about 3 out of 4 of my problems
Now my last issue That I cannot seem to resolve is, when players go together in ITCombat. Meaning they land on the same coordinates the game crashes automatically. I cannot seem to figure out why that is
Here is the code.
/***************************************************************************
/ FUNCTION NAME: Do_opponent_struct(struct client_t *c, struct opponent_t *theOpponent)
/
/ FUNCTION: Check to see if a player entered an occupied square
/
/
/ ARGUMENTS:
/ struct server_t s - the server strcture
/ struct game_t this_game - pointer to the player we're checking
/
/ RETURN VALUE: none
/
/ DESCRIPTION:
/ Process arguments, initialize program, and loop forever processing
/ player input.
/
****************************************************************************/
void Do_opponent_struct(struct client_t *c, struct opponent_t *theOpponent)
{
char string_buffer[SZ_LINE];
c->battle.ring_in_use = FALSE;
c->battle.melee_damage = 0.0;
c->battle.skirmish_damage = 0.0;
c->battle.tried_luckout = FALSE;
strcpy(theOpponent->name, c->modifiedName);
theOpponent->processID = c->game->clientPid;
/* passable experience = all player exp now that nicking is capped */
/* Kings and higher are immune to nicking */
if (c->player.special_type >= SC_KING) {
theOpponent->experience = 0.0;
}
else {
theOpponent->experience = floor(c->player.experience /
(30 * c->player.level + 1));
}
theOpponent->strength = c->player.strength + c->player.sword;
theOpponent->max_strength = theOpponent->strength;
theOpponent->energy = c->player.energy;
theOpponent->max_energy = c->player.max_energy + c->player.shield;
theOpponent->speed = c->player.quickness + 1;
theOpponent->max_speed = theOpponent->speed;
theOpponent->brains = c->player.brains;
theOpponent->size = c->player.level;
/* the bigger they are, the harder they fall to all or nothing */
theOpponent->sin = c->player.sin + floor(c->player.level / 100);
sprintf(string_buffer,
"%s, %s, Level %.0lf, Sin %.0f has effective Sin of %.0lf\n",
c->player.lcname,
c->realm->charstats[c->player.type].class_name,
c->player.level,
c->player.sin,
theOpponent->sin);
Do_log(COMBAT_LOG, string_buffer);
theOpponent->shield = 0;
theOpponent->special_type = SM_IT_COMBAT;
theOpponent->treasure_type = 0;
theOpponent->flock_percent = 0;
/* throw up spells for combat */
Do_starting_spells©;
}
/***************************************************************************
/ FUNCTION NAME: Do_setup_it_combat(struct client_t *c, struct game_t *theGame)
/
/ FUNCTION: Check to see if a player entered an occupied square
/
/
/ ARGUMENTS:
/ struct server_t s - the server strcture
/ struct game_t this_game - pointer to the player we're checking
/
/ RETURN VALUE: none
/
/ DESCRIPTION:
/ Process arguments, initialize program, and loop forever processing
/ player input.
/
****************************************************************************/
Do_setup_it_combat(struct client_t *c, struct game_t *theGame)
{
float ftemp;
/* WARNING: c->realm->realm_lock is passed LOCKED! */
/*
Do_lock_mutex(&c->realm->realm_lock);
*/
struct it_combat_t *theCombat;
struct event_t *event_ptr;
struct it_combat_t *it_combat_ptr;
char string_buffer[SZ_LINE];
theCombat = (struct it_combat_t *) Do_malloc(SZ_IT_COMBAT);
theCombat->opponentFlag[0] = FALSE;
theCombat->opponentFlag[1] = FALSE;
theCombat->next_opponent = NULL;
theCombat->player_ptr = NULL;
Do_init_mutex(&theCombat->theLock);
c->game->it_combat = theCombat;
if (theGame->it_combat == NULL) {
theGame->it_combat = theCombat;
Do_unlock_mutex(&c->realm->realm_lock);
event_ptr = (struct event_t *) Do_create_event();
event_ptr->type = IT_COMBAT_EVENT;
event_ptr->arg4 = theCombat;
event_ptr->to = theGame;
event_ptr->from = c->game;
Do_send_event(event_ptr);
Do_send_clear©;
if (c->player.blind)
sprintf(string_buffer,
"You hear another player nearby!\n");
else
sprintf(string_buffer,
"You see another player in the distance!\n");
}
else {
it_combat_ptr = theGame->it_combat;
while (it_combat_ptr->next_opponent != NULL)
it_combat_ptr = it_combat_ptr->next_opponent;
it_combat_ptr->next_opponent = theCombat;
Do_unlock_mutex(&c->realm->realm_lock);
Do_send_clear©;
if (c->player.blind)
sprintf(string_buffer,
"You sense that several players are nearby!\n");
else
sprintf(string_buffer,
"You see several players in the distance!\n");
}
Do_send_line(c, string_buffer);
Do_lock_mutex(&theCombat->theLock);
Do_opponent_struct(c, &theCombat->opponent[0]);
c->battle.opponent = &theCombat->opponent[1];
Do_unlock_mutex(&theCombat->theLock);
/* for attacking another player, pick up sin */
Do_sin(c, .5);
sprintf(string_buffer, "%s ATTACKED another player.\n", c->player.lcname);
Do_log(BATTLE_LOG, string_buffer);
Do_send_line(c, "Waiting for the other player(s)...\n");
Do_it_combat_turns(c, theCombat, &theCombat->opponent[0],
&theCombat->opponentFlag[0], &theCombat->opponentFlag[1]);
return;
}
/***************************************************************************
/ FUNCTION NAME: Do_it_combat(struct client_t *c, struct event_t *theEvent)
/
/ FUNCTION: Check to see if a player entered an occupied square
/
/
/ ARGUMENTS:
/ struct server_t s - the server strcture
/ struct game_t this_game - pointer to the player we're checking
/
/ RETURN VALUE: none
/
/ DESCRIPTION:
/ Process arguments, initialize program, and loop forever processing
/ player input.
/
****************************************************************************/
Do_it_combat(struct client_t *c, struct event_t *theEvent, int available)
{
struct it_combat_t *theCombat;
char string_buffer[SZ_LINE];
Do_send_clear©;
theCombat = (struct it_combat_t *) theEvent->arg4;
Do_lock_mutex(&theCombat->theLock);
/* if our flag is set, there is a problem */
if (!theCombat->opponentFlag[1]) {
theCombat->opponentFlag[0] = TRUE;
theCombat->opponentFlag[1] = FALSE;
Do_opponent_struct(c, &theCombat->opponent[1]);
if (c->player.energy <= 0) {
theCombat->message = IT_JUST_DIED;
Do_unlock_mutex(&theCombat->theLock);
kill(theCombat->opponent[0].processID ,SIGIO);
Do_lock_mutex(&c->realm->realm_lock);
c->game->it_combat = NULL;
Do_unlock_mutex(&c->realm->realm_lock);
return;
}
else if (!available) {
theCombat->message = IT_JUST_LEFT;
Do_unlock_mutex(&theCombat->theLock);
kill(theCombat->opponent[0].processID ,SIGIO);
Do_lock_mutex(&c->realm->realm_lock);
c->game->it_combat = NULL;
Do_unlock_mutex(&c->realm->realm_lock);
return;
}
else {
theCombat->message = IT_REPORT;
}
}
c->battle.opponent = &theCombat->opponent[0];
if (c->player.blind) {
if (c->stuck) {
c->stuck = FALSE;
sprintf(string_buffer,
"Before you can move, you hear another player in the area!\n");
}
else {
sprintf(string_buffer,
"You hear another player approach!\n");
}
}
else {
if (c->stuck) {
c->stuck = FALSE;
sprintf(string_buffer,
"Before you can move, %s enters the area!\n",
theCombat->opponent[0].name);
}
else {
sprintf(string_buffer,
"You see %s approaching from the distance!\n",
theCombat->opponent[0].name);
}
}
Do_unlock_mutex(&theCombat->theLock);
kill(theCombat->opponent[0].processID ,SIGIO);
Do_send_line(c, string_buffer);
Do_send_buffer©;
sleep(2);
Do_it_combat_turns(c, theCombat, &theCombat->opponent[1],
&theCombat->opponentFlag[1], &theCombat->opponentFlag[0]);
return;
}
I would appreciate any help you can give me. Thank you.
RE: Online game, coding problems. - icecubemachines - 08-05-2011
What do you use to program with?
I'm guessing the crash you're getting is related to memory access problems, since you're using a lot of array's and pointers. These are pretty easy to correct with a good debugger. Sadly, I can only help if you're using Visual Studio or Visual Express. I don't like Microsoft, but there debuggers are really easy to work with (and the sole reason why I use Visual Studio)
What you could try (if you're running something from MS):
- run the program inside the IDE
- force a crash. When it happens, you need to "debug and view the call stack" or something along those line. The stack contains all data at the moment of execution, and is the easiest way of catching your bug.
- if you're using Visual Express/Studio, it'll show all the variables in the stack and highlight where it went wrong. It always boils down to the same problem: a pointer is being used which points to some random location instead of the proper object.
This might be because the object it's supposed to point to A) never got created B) was created inside a function, without using "new" to reserve space on the stack (and thus it got destroyed when the function ended) C) got lost in translating pointers to references to pointers to references etc etc.
If you actually look at the stack at the moment of the crash, it should become clear which data is missing. Then you just track down where you create the troubled object (and in 99% of all cases, smack yourself against the head because you forgot to reserve space with "new")
If you're not using a debugger, put "cout << somenumber << endl;" every even/odd line to locate the exact moment stuff starts crashing.
RE: Online game, coding problems. - haphazard - 09-14-2011
your last error 4/4
wut is going on with the flags?
/* if our flag is set, there is a problem */
if (!theCombat->opponentFlag[1]) {
theCombat->opponentFlag[0] = TRUE;
theCombat->opponentFlag[1] = FALSE;
Do_opponent_struct(c, &theCombat->opponent[1]);
if (c->player.energy <= 0) {
theCombat->message = IT_JUST_DIED;
Do_unlock_mutex(&theCombat->theLock);
kill(theCombat->opponent[0].processID ,SIGIO);
Do_lock_mutex(&c->realm->realm_lock);
c->game->it_combat = NULL;
Do_unlock_mutex(&c->realm->realm_lock);[/code]
Now I am not the most avid C++ coder which btw I must give you sum serious coodos for such a nice program.. But I dont beleive the BOLD sentences are legitimate arguments, even though your IDE may let you get away with this, I dont beleive that those two lines actually do something. maybe if you proceded with an "if" statement and capped the arguments in braces it "MIGHT" work. I was hesitant to awnser with a reply cause I didnt want to fail/seam like a dumbass offering null advice, but who knows maybe it might work? and at the very least a bump to the thread
RE: Online game, coding problems. - hacker - 09-14-2011
lol, i have never seen that before, goodluck
RE: Online game, coding problems. - +Awesome - 09-18-2011
Oh, there maybe a problem with something, I'm still learning, so no opinions. Sorry.
|