[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

The Unknown Game



IIRC, I've already mentioned my current pet-project - The Unknown Game.
I'm stuck right now with a terrible problem with loadable modules, and
passing C++ classes betwixt main program code and a loaded module.  I hope
this post isn't too long...  In unk, all the actual operations that are
performed on a character are implemented as loadable modules, so as to
allow a maximum functionality.  If one wishes to revamp the way certain
actions are handled internally, all they'll need to do is write a new
module to handle it.  My problem right now is memory-related, and I'm
having some odd dificulties.

I would like to mention that I'm using configure, libtool and automake to
handle the Makefile/library building, if you want an archive of all my
source, just let me and I'll e-mail you the tarball(it's 77k).

First, the game data manip classes/functions:

/* gamedat.H*/
// Game data classes

#ifndef GAMEDAT_H
#define GAMEDAT_H
// Multi-inclusion flubbing prevention
//#include <String.h>

class Item 
{
  char * color;
  char * description;
  int type;
  int whack_power;
  int index;
  int owner;  // Corresponds to Player.id
  // Used mainly for weapons.
};

/* type is used internally to represent properties and strengths -
 * the full power of this comes from the modularized data handling
 * funcs.  It allows THEM to calculate health, and allows the game
 * designer to come up with some really incredible stuff.
 */

class Player 
{
  void WhackData(Player * data);
public:
  char *charname;
  int id;
  int health;
  int intelligence;
  int age;
  int eot;
  // eot is the time to the player's end of turn
  int strength;
  int location;
  int charm;
  int wit;
  int luck;
  Item posessions[30];
  // Person can only carry 30 posessions - hope to make it configurable.
  
  void Kill(Player *tokill);
  void AllNighter(void);
  /*  void Enter(void);
  void Take(Item *totake);
  void Drop(void);
  void Dismember(Player *todismember);
  void Eat(Item *toeat);
  // Interestingly, Eat() is the only action that can be done after
  // Kill() and Dismember().  Not recommended, lowers health and
  // intelligence.
  void Attack(Player *toattack);
  void Use(Item thing);*/
  // Goal of Attack() is to knock out.
};

/* id is the person's id number as connected - this will probably
 * be updated when a client asks fabricate so it can take directly
 * to another client.  health is an index of the person's health,
 * intelligence is similar, as is strength.  age is the length of
 * time this character has lived - only used if specified by the
 * gameball, this allows characters to get old and die if
 * indicated. */


#endif

/* gamedat.C */
// Now, this may make life difficult.
// Uses modules to implement different funcs.

#include <dlfcn.h>  // NEEDS -ldl

#include "common.h"  // autoinc's gamedat.h
#include "kill.lib/kill.h"

void Player::Kill(Player *tokill)
{
  char * fname="/usr/local/src/gamestuff/foobin/lib/libkill.so";
  char * func="kill";
  Player * (*kill)(Player * actupon, Player * me);
  Player *data;
  
  void * handle;
  char *error;
  data=new Player;
  
  printf("\nLOADING LIB...\n");
  
  
  handle=dlopen(fname, RTLD_LAZY);
  if (!handle) {
    printf("\nCouldn't load kill.so!  Reason: %s\n", dlerror());
    exit(1);
  }


  printf("\nLoaded kill.so.\n");
  kill=dlsym(handle, func);
  if ((error = dlerror()) !=NULL) {
    printf("\nCould access kill() function! Reason: %s\n", error);
    exit(1);
  }

  printf("\nGot handle to kill func.\n");
  // Okay, we've got the lib loaded, let's run it...
  data=(*kill)(tokill, this);
  // this is, as you know, extant.
  printf("\nDATA->HEALTH: %d\n", data->health);
  
  if (data == NULL) {
    printf("\nPATHOLOGICAL CASE OF CIGARS\n");
    exit(1);
  }
  
  /*  health=data.health;
  intelligence=data.intelligence;
  age=data.age;  //  Hmm, FIZZME - make age-munging impossible
  eot=data.eot;
  strength=data.strength;
  location=data.location;
  charm=data.charm;
  wit=data.wit;
  luck=data.luck;
  health=data.health;
  
  for (int i=0; i<30; i++) {
    posessions[i]=data.posessions[i];
    }*/
  WhackData(data);
  
  
}

void Player::AllNighter( void )
{
  char *fname="allnight.so";
  char *func="allnight";
  Player *(*allnighter)(Player * me);
  

  
}

void Player::WhackData(Player * data)
{
  health=data->health;
  intelligence=data->intelligence;
  age=data->age;//  Hmm, FIZZME - make age-munging impossible
  eot=data->eot;
  strength=data->strength;
  location=data->location;
  charm=data->charm;
  wit=data->wit;
  luck=data->luck;
  health=data->health;
  
  for (int i=0; i<30; i++) {
    
    posessions[i]=data->posessions[i];
    
  }
  
}


/* common.h */
// Common game junk...

#ifndef COMMON_H
#define COMMON_H

#include "ZombieClient.h"
#include "gamedat.H"

void SpewGameInfo(int to, ZombieClient * me, Player dat[]);

#endif

/* kill.C */
// Use kill.h to handle func proto's - with gamedat.H inc'ed.

#include "kill.h"
#include <stdio.h>

Player * kill(Player * tokill, Player * me)
{
  // Do really stupid hacking...  null health,
  // intell and strength of killed dude, give to killer
  fprintf(stderr, "\nFOOBAR!\n");
  me->health+=tokill->health;
  fprintf(stderr, "\nFOO!\n");

}

/* kill.h */
// kill.so header file

#ifndef KILL_H
#define KILL_H

#include "../gamedat.H"

Player * kill(Player * tokill, Player * me);

#endif /* KILL_H */


/* foo.C - for testing kill loadable modules*/
// foo.C tests my class-ical implementation of Player::kill()
// I hope this works...


#include <stdio.h>
#include "common.h"

main()
{
  Player * tokill, *me;
  tokill=new Player;
  me=new Player;
  
  printf("\n Loading vars...\n");
  me->health=20;
  tokill->health=30;
  printf("\ntokill: %d, me: %d\n", tokill->health, me->health);
  printf("\nKilling...\n");
  me->Kill(tokill);
  
  printf("\nDid it!\nReports me: %d, tokill: %d\n", me->health, tokill->health);
  delete me;
  delete tokill;
}

(I hope I didn't forget any code, I hate it when I get to the point that
what I'm testing relies on a lot of code)

Anyways, clerical error pointing out appreciated, and I would REALLY
appreciate it if someone out there could help me figure this out.  Jeers
from the peanut gallery can be directed to /dev/null:)

I trust people manage to build this, remember though that this code is not
for actual use...  When I build and run the code, I get the following
output:

geeky1,60:/usr/local/src/gamestuff/unk% ./fookill

 Loading vars...

tokill: 30, me: 20

Killing...

LOADING LIB...

Loaded kill.so.

Got handle to kill func.
zsh: segmentation fault (core dumped)  ./fookill
geeky1,60:/usr/local/src/gamestuff/unk% gdb fookill core
GDB is free software and you are welcome to distribute copies of it
 under certain conditions; type "show copying" to see the conditions.
There is absolutely no warranty for GDB; type "show warranty" for details.
GDB 4.16 (i586-debian-linux), Copyright 1996 Free Software Foundation,
Inc...
Core was generated by `./fookill'.
Program terminated with signal 11, Segmentation fault.
Reading symbols from /lib/libdl.so.1...done.
Reading symbols from /lib/libm.so.5...done.
Reading symbols from /lib/libc.so.5...done.
Reading symbols from /lib/ld-linux.so.1...done.
Reading symbols from
/usr/local/src/gamestuff/foobin/lib/libkill.so...done.
#0  Player::Kill (this=0x804b578, tokill=0x804b278) at gamedat.C:41
41        printf("\nDATA->HEALTH: %d\n", data->health);
(gdb) bt
#0  Player::Kill (this=0x804b578, tokill=0x804b278) at gamedat.C:41
#1  0x8048802 in main ()
#2  0x80486ce in ___crt_dummy__ ()
Current language:  auto; currently c++

>From this you can see where it dies...  Something weird is happening
inside kill.so, but I'm not sure what.  You'll notice that none of the
fprintf()'s from kill.so get out, even though according to the program
kill() finished executing.  TIA, TTYL!



---
Paul Anderson
hacker@geeky1.ebtech.net
"This is Maurice, our sheep-hearding carrot."