home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #27 / NN_1992_27.iso / spool / alt / sources / 2611 / master.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-11-23  |  6.7 KB  |  421 lines

  1. #ifndef lint
  2. static    char    sccsid[] = "@(#)master.c 1.1 92/05/28 SMI" ;
  3.     /* from master.c 1.2 88/10/19 SMI */
  4. #endif
  5.  
  6. /*
  7.  * Copyright (c) 1986 by Sun Microsystems, Inc.
  8.  */
  9.  
  10. /*
  11.  * This is the stuff handled by the master.
  12.  */
  13.  
  14.  
  15.  
  16. #include <stdio.h>
  17. #include <sys/time.h>
  18.  
  19. #include "dstar.h"
  20. #include "object_types.h"
  21. #include "netio.h"
  22.  
  23.  
  24.  
  25. extern    int    debug_level ;
  26.  
  27.  
  28.  
  29.  
  30.  
  31.  
  32. /****
  33.  * get free entry in object list
  34.  ****/
  35.  
  36.  
  37. static    int
  38. get_free_object()
  39. {
  40. register int        id ;
  41. register Object        *object ;
  42.  
  43.     id = 0;
  44.     object = &objects[0] ;
  45.     for(;;)
  46.     {
  47.       if(object->class == OBJ_EMPTY)
  48.         return(id) ;
  49.       else if(++id >= MAX_PLAYERS)
  50.         return(-1) ;
  51.       else
  52.         ++object ;
  53.     }
  54. }
  55.  
  56.  
  57.  
  58.  
  59. /****
  60.  *
  61.  * tell somebody about all the players in the game
  62.  *
  63.  ****/
  64.  
  65. static
  66. send_lists(id)
  67.     int        id ;
  68. {
  69. register int            i ;
  70. register Object            *object ;
  71.  
  72.  
  73.     object = &objects[0] ;
  74.     for(i=0; i < MAX_PLAYERS; ++i)
  75.     {
  76.       if(object->class != OBJ_EMPTY  &&  object->id != id)
  77.         send_status(object) ;
  78.       ++object ;
  79.     }
  80. }
  81.  
  82.  
  83.  
  84.  
  85.  
  86.  
  87.  
  88.  
  89. poll_player(player)
  90. register Object    *player ;
  91. {
  92.     Net_are_you_there poll_msg ;
  93.  
  94.     if(Now.tv_sec - player->last_rep.tv_sec > 60)
  95.     {
  96.       /* He's dead Jim. You grab his tricorder, I'll get his wallet */
  97.       net_remove_player(player->id) ;
  98.     }
  99.     else if(Now.tv_sec - player->last_rep.tv_sec > 30)
  100.     {
  101.       /* where is it? */
  102.       net_start_message( player ) ;
  103.       poll_msg.type = NET_ARE_YOU_THERE ;
  104.       poll_msg.len = sizeof(Net_are_you_there) ;
  105.       poll_msg.id = Me->id ;
  106.       poll_msg.sequence = ++sequence_number ;
  107.       poll_msg.his_id = player->id ;
  108.       add_message(&poll_msg, sizeof(poll_msg)) ;
  109.     }
  110. }
  111.  
  112.  
  113.  
  114.  
  115.  
  116. net_poll()
  117. {
  118. register Object        *object ;
  119.     int        count ;
  120.     Net_died    died_msg ;
  121.     int        iret ;
  122.  
  123.     if(Me->net_status == UNKNOWN)
  124.     {
  125.       become_master() ;
  126. #ifdef    DEBUG
  127.       if(status_display)
  128.         status_update() ;
  129. #endif    DEBUG
  130.       return ;
  131.     }
  132.  
  133.  
  134.  
  135.  
  136.  
  137.  
  138.     if(Me->net_status != MASTER)
  139.     {
  140. #ifdef    DEBUG
  141.       if(status_display)
  142.         status_update() ;
  143. #endif    DEBUG
  144.       if( poll_master )
  145.         poll_player(&objects[master_id]) ;
  146.       return ;
  147.     }
  148.  
  149.  
  150.  
  151.  
  152.     object = &objects[0] ;
  153.     for(count = MAX_PLAYERS; count--; )
  154.     {
  155.       if(object != Me  &&
  156.          (object->class == OBJ_PLAYER ||
  157.           (object->class == OBJ_MISSILE  &&  object->team != Me->id)) )
  158.         poll_player( object ) ;
  159.       ++object ;
  160.     }
  161.  
  162.  
  163.     /* finally, re-sync static objects */
  164.  
  165.     net_start_message( NULL ) ;
  166.     object = &objects[0] ;
  167.     for(count = MAX_PLAYERS; count--; )
  168.     {
  169.       if( object->class == OBJ_STATIC )
  170.         send_status( object ) ;
  171.       ++object ;
  172.     }
  173.  
  174. #ifdef    DEBUG
  175.     if(status_display)
  176.       status_update() ;
  177. #endif    DEBUG
  178. }
  179.  
  180.  
  181.  
  182.  
  183.  
  184. /*
  185.  * MASTER DUTY HANDLERS:
  186.  *
  187.  * become_master()    -    initialize extra duty functions
  188.  *
  189.  */
  190.  
  191.  
  192.  
  193.  
  194.  
  195. become_master()
  196. {
  197. register Object    *object ;
  198.  
  199.  
  200.     puts("No other players, waiting...") ;
  201.  
  202.     Me->id = 0 ;
  203.  
  204.     special_welcome() ;
  205.  
  206.     /* put static objects into database */
  207.  
  208.     create_planet(get_free_object()) ;
  209.     create_monolith(get_free_object()) ;
  210.  
  211. #ifdef    DEBUG
  212.     if(debug_level >= 1)
  213.       dump_lists() ;
  214. #endif    DEBUG
  215.  
  216.     rehash_netlists() ;
  217. }
  218.  
  219.  
  220.  
  221.  
  222.  
  223.  
  224.  
  225. take_over()
  226. {
  227. register Object    *object ;
  228.  
  229.  
  230. #ifdef    DEBUG
  231.     printf("taking over as master\n") ;
  232. #endif    DEBUG
  233.  
  234.     if( objects[0].class == OBJ_EMPTY )
  235.     {
  236.       net_rename(0) ;
  237.       Me = &objects[0] ;
  238.     }
  239.  
  240.     else if( &objects[0] == Me )
  241.       Me->id = 0 ;
  242.  
  243. #ifdef    DEBUG
  244.     if(debug_level >= 1)
  245.       dump_lists() ;
  246. #endif    DEBUG
  247.  
  248.     rehash_netlists() ;
  249.     net_flush() ;
  250. }
  251.  
  252.  
  253.  
  254.  
  255.  
  256.  
  257.  
  258.  
  259.  
  260.  
  261.  
  262. /*
  263.  * INPUT MESSAGE HANDLING:
  264.  *
  265.  * add_new_player(...)        - handle NET_JOINING
  266.  *
  267.  * new_missile(header)        - handle NET_REQUEST_MISSILE
  268.  *
  269.  */
  270.  
  271.  
  272.  
  273.  
  274.  
  275.  
  276. /****
  277.  * add player to database (master only)
  278.  * inform all players of this player's presence
  279.  * inform this player of all other players
  280.  * inform all slave daemons of this player's presence
  281.  ****/
  282.  
  283.  
  284. add_new_player(id,name,address,sequence,class)
  285.     int        id ;
  286.     char            *name ;
  287.     struct sockaddr_in    *address ;
  288.     int            sequence ;
  289.     Object_Class        class ;
  290. {
  291.     int        i ;
  292. register Object        *object ;
  293. extern    fptr        fighter_vector[VECTOR_LENGTH],
  294.             missile_vector[VECTOR_LENGTH],
  295.             static_vector[VECTOR_LENGTH] ;
  296.     Net_welcome    w_msg ;
  297.  
  298.     if(id == -1)
  299.       id = get_free_object() ;
  300.  
  301.     if(id != -1)
  302.     {
  303.       object = &objects[id] ;
  304.       object->id = id ;
  305.       strncpy(object->name, name, NAMELEN) ;
  306.       object->team = (game_type == GAME_FREE ? id : id%2) ;
  307.       object->score = 0 ;
  308.       object->class = class ;
  309.       object->status = OBJ_SLEEPING ;
  310.       object->flags = 0 ;
  311.       object->target = NULL ;
  312.       object->description = -1 ;
  313.       object->address = *address ;
  314.       object->sequence = sequence ;
  315.       object->last_rep = Now ;
  316.       object->net_addr = inet_netof(object->address.sin_addr) ;
  317.       object->net_status = SLAVE ;
  318.       switch(class)
  319.       {
  320.         case OBJ_PLAYER:
  321.           printf("new player: %d, %s\n",id,name) ;
  322.           bcopy(fighter_vector,object->f_vector,sizeof(fighter_vector)) ;
  323.           break ;
  324.         case OBJ_MISSILE:
  325.           bcopy(missile_vector,object->f_vector,sizeof(missile_vector)) ;
  326.           break ;
  327.         case OBJ_STATIC:
  328.           printf("new object: %d, %s\n",id,name) ;
  329.           bcopy(static_vector,object->f_vector,sizeof(static_vector)) ;
  330.           break ;
  331.       }
  332.  
  333.       need_rehash = 1 ;
  334.       special_add_player(object) ;
  335.  
  336.       /* tell player about all players */
  337.  
  338.       w_msg.type = NET_WELCOME ;
  339.       w_msg.len = sizeof(w_msg) ;
  340.       w_msg.id = Me->id ;
  341.       w_msg.sequence = ++sequence_number ;
  342.       w_msg.player_id = id ;
  343.       w_msg.team = (game_type == GAME_FREE ? id : id%2) ;
  344.       w_msg.game_type = game_type ;
  345.  
  346.       net_start_message( object ) ;
  347.       add_message(&w_msg, sizeof(w_msg)) ;
  348.       send_lists(object->id) ;
  349.     }
  350.     else
  351.     {
  352.       printf("too many players, %s is being ignored\n",name) ;
  353.     }
  354.  
  355. #ifdef    DEBUG
  356.     if(status_display)
  357.       status_update() ;
  358.     if(debug_level >= 1)
  359.       dump_lists() ;
  360. #endif    DEBUG
  361. }
  362.  
  363.  
  364.  
  365.  
  366.  
  367.  
  368.  
  369. new_missile(header)
  370. register Net_request_missile    *header ;
  371. {
  372. register Object        *missile, *owner ;
  373.     Net_missile    outmsg ;
  374.     int        id, get_free_object() ;
  375. extern    fptr        missile_vector[VECTOR_LENGTH] ;
  376.  
  377.     owner = &objects[header->id] ;
  378.     id = get_free_object() ;
  379.     if(id >= 0)
  380.     {
  381.       missile = &objects[id] ;
  382.       missile->id = id ;
  383.       strncpy(missile->name, "missileX", NAMELEN) ;
  384.       missile->team = owner->id ;
  385.       missile->score = 0 ;
  386.       missile->class = OBJ_MISSILE ;
  387.       missile->status = OBJ_SLEEPING ;
  388.       missile->flags = 0 ;
  389.       missile->target = NULL ;
  390.       missile->description = -1 ;
  391.       missile->address = owner->address ;
  392.       missile->last_rep = Now ;
  393.       missile->net_status = SLAVE ;
  394.       bcopy(missile_vector, missile->f_vector, sizeof(missile->f_vector)) ;
  395.  
  396.       if(header->id != Me->id)
  397.       {
  398.         outmsg.type = NET_MISSILE ;
  399.         outmsg.len = sizeof(Net_missile) ;
  400.         outmsg.id = Me->id ;
  401.         outmsg.sequence = ++sequence_number ;
  402.         outmsg.missile_id = id ;
  403.         net_start_message( owner ) ;
  404.         add_message(&outmsg, sizeof(outmsg)) ;
  405.         special_add_player(missile) ;
  406.       }
  407.       else
  408.         missile_armed(id) ;
  409.     }
  410.     else
  411.     {
  412.       printf("too many players, missile from %s is being ignored\n",
  413.         owner->name) ;
  414.     }
  415.  
  416. #ifdef    DEBUG
  417.     if(status_display)
  418.       status_update() ;
  419. #endif    DEBUG
  420. }
  421.