示例#1
0
/**
 * Looks up an option in the option dictionary by the given name.  Creates a new option and adds it to
 * the options dictionary if not found
 */
static _option* _query_or_new(hashtable* options, const char* name)   {
    _option_wrapper* option_wrapper;
    _option* option;
    
    option = _query(options, name);
    if (!option)    {
        /* Not found, create and insert */
        option = (_option*)malloc(sizeof(_option));
        memset(option, 0, sizeof(_option));
        option->name = xp_strdup(name);
        
        /* Key by the long name */
        option_wrapper = (_option_wrapper*)malloc(sizeof(_option_wrapper));
        memset(option_wrapper, 0, sizeof(_option_wrapper));
        option_wrapper->key = xp_strdup(name);
        option_wrapper->alias = 0;              /* We own the option */
        option_wrapper->o = option;
        ht_insert(options, (void*)option_wrapper);
        
        /* Key by the short name */
        _set_shortname(options, name, name[0]);
    }
    
    return option;
}
示例#2
0
/**
 * Adds the given option to the options list
 * 
 * options      - The options dictionary to which to add the option
 * name         - The long name of the option (example "velocity")
 * description  - The human readable description, used to print usage
 * has_default  - 1 if the value in intptr has a valid default at startup, 0 if a value must be supplied
 * option_type  - The data type of the option (OPTION_INT/OPTION_FLOAT/...)
 * valptr       - Pointer to a variable that will receive the parsed option
 *
 * NOTES:
 *  - Calling the function with a null options dictionary has no effect
 *  - If the option has already been added, it will be replaced
 */
static void _add_option(hashtable* options, const char* name, const char* description, int has_default, int option_type, void* valptr)   {
    _option* option;
    
    if (!options) {
        return;
    }
    
    option = _query_or_new(options, name);
    option->type = option_type;
    option->has_default = has_default;
    
    option->accepts_value = option->type == OPTION_INT || 
                            option->type == OPTION_FLOAT || 
                            option->type == OPTION_STRING;
    
    if (option->description) {
        /* Free previous description */
        free(option->description);
        option->description = 0;
    }
    
    if (description)    {
        option->description = xp_strdup(description);
    }
    
    option->value.valptr = valptr;
}
示例#3
0
/**
 * Sets the one-character shortname of the given option
 *
 * options      - The options dictionary which contains the option
 * name         - The (full) name of the option
 * shortname    - The one-character short name of the option
 *
 * NOTES:
 *  - It is not necessary to call this function unless you wish to override the default short name, which
 *    is the first letter of the long name
 *  - If an existing short name exists (including the default), it will be removed and replaced
 *  - If an identical short name exists, it will be replaced with this one, even if it is for a different
 *    option
 */
void _set_shortname(hashtable* options, const char* name, char shortname)    {
    _option* option;
    _option_wrapper* wrapper, *query_wrapper;
    char* str_shortname;
    
    if (!options) {
        return;
    }
    
    option = _query(options, name);
    if (!option)    {
        return;
    }
    
    xp_asprintf(&str_shortname, "%c", shortname);
    
    wrapper = (_option_wrapper*)malloc(sizeof(_option_wrapper));
    wrapper->key = str_shortname;
    wrapper->alias = 1;             /* We don't own the option */
    query_wrapper = wrapper;
    if (ht_lookup(options, (void*)&wrapper) != 0)    {
        /* It's not in there, just add it */
        wrapper->key = xp_strdup(str_shortname);
        ht_insert(options, (void*)wrapper);
    } else {
        /* Already in there */
        free(query_wrapper->key);
        free(query_wrapper);
    }
    
    wrapper->o = option;
}
示例#4
0
/**
 * Sets the given usage text that will be shown when arguments do not match and as the top line of the
 * help
 */
void optin_set_usage_text(optin* o, const char* usage)  {
    if (!o) {
        return;
    }
    
    if (o->usage)   {
        free(o->usage);
    }
    
    if (usage)  {
        o->usage = xp_strdup(usage);
    }
}
示例#5
0
/*
 * Modify an option during the game.
 *
 * Options which can be modified have a so called tuner function,
 * which checks the validity of the new option value, and possibly
 * does something extra depending upon the option in question.
 * Options which don't need such a tuner function set it to 'tuner_dummy'.
 * Options which cannot be modified have the tuner set to 'tuner_none'.
 */
int Tune_option(char *name, char *val)
{
    int ival;
    double fval;
    option_desc *opt;

    if (!(opt = Find_option_by_name(name)))
	return -2;	/* Variable not found */

    if (opt->tuner == tuner_none)
	return -1;	/* Operation undefined */

    switch (opt->type) {
    case valInt:
	if (Convert_string_to_int(val, &ival) != true)
	    return 0;
	*(int *)opt->variable = ival;
	(*opt->tuner)();
	return 1;
    case valBool:
	if (ON(val))
	    *(bool *)opt->variable = true;
	else if (OFF(val))
	    *(bool *)opt->variable = false;
	else
	    return 0;
	(*opt->tuner)();
	return 1;
    case valReal:
	if (Convert_string_to_float(val, &fval) != true)
	    return 0;
	*(double *)opt->variable = fval;
	(*opt->tuner)();
	return 1;
    case valString:
	{
	    char *s = xp_strdup(val);

	    if (!s)
		return 0;
	    if (*(char **)(opt->variable) != opt->defaultValue)
		free(*(char **)opt->variable);
	    *(char **)opt->variable = s;
	    (*opt->tuner)();
	    return 1;
	}
    default:
	return -1;	/* Operation undefined */
    }
}
示例#6
0
/**
 * Processes the given option as if it had been given on the command line
 *
 * o        - The optin object that contains the option
 * opt      - The long or short option name (e.g. "velocity" or "v"), do not include dashes
 * value    - The value that the option takes (e.g "35").  Pass NULL if the option takes no value
 *
 * RETURNS: zero if the option was processed successfully, nonzero if there was an error
 */
int optin_process_option(optin* o, const char* opt, const char* value)  {
    _option* option;
    
    /*fprintf(stderr, "Processing option: %s, value: %s\n", opt, value);*/
    
    option = _query(o->options, opt);
    if (!option)    {
        fprintf(stderr, "Unrecognized option: %s\n", opt);
        return OPTIN_ERR_INVALID_OPTION;
    }
    
    switch(option->type)    {
    case OPTION_FLAG:
        if (option->value.intptr != 0)  {
            *option->value.intptr = 1;
        }
        break;
    case OPTION_INT:
        if (option->value.intptr != 0)  {
            *option->value.intptr = atoi(value);
        }
        break;
    case OPTION_FLOAT:
        if (option->value.floatptr != 0)    {
            *option->value.floatptr = atof(value);
        }
        break;
    case OPTION_STRING:
        if (option->value.stringptr != 0)   {
            *option->value.stringptr = xp_strdup(value);
        }
        break;
    }
    
    option->set = 1;
    
    return 0;
}
示例#7
0
文件: server.c 项目: kekyo/xpilot-ng
int main(int argc, char **argv)
{
    int timer_tick_rate;
    char *addr;

    /* world is a global now */
    world = &World;

    if (sock_startup() < 0) {
    	warn("Error initializing sockets\n");
	return 1;
    }

    if (World_init() < 0) {
	warn("Error initializing world\n");
	return 1;
    }

    /*
     * Make output always linebuffered.  By default pipes
     * and remote shells cause stdout to be fully buffered.
     */
    setvbuf(stdout, NULL, _IOLBF, BUFSIZ);
    setvbuf(stderr, NULL, _IOLBF, BUFSIZ);

    /*
     * --- Output copyright notice ---
     */

    xpprintf("  " COPYRIGHT ".\n"
	   "  " TITLE " comes with ABSOLUTELY NO WARRANTY; "
	      "for details see the\n"
	   "  provided COPYING file.\n\n");

    init_error(argv[0]);

    /*seedMT((unsigned)time(NULL) * Get_process_id());*/
    /* Removed seeding random number generator because of server recordings. */

    Groups_init();

    /* Make trigonometric tables */
    Make_table();

    if (!Parser(argc, argv))
	exit(1);

    Init_recording();
    /* Lock the server into memory */
    plock_server(options.pLockServer);

    Asteroid_line_init();
    Wormhole_line_init();
    Walls_init();

    /* Allocate memory for players, shots and messages */
    Alloc_players(Num_bases() + MAX_PSEUDO_PLAYERS + MAX_SPECTATORS);
    spectatorStart = Num_bases() + MAX_PSEUDO_PLAYERS;
    Alloc_shots(MAX_TOTAL_SHOTS);
    Alloc_cells();

    Move_init();
    Robot_init();
    Treasure_init();
    Hitmasks_init();

    Rank_init_saved_scores();

    /*
     * Get server's official name.
     */
    if (options.serverHost) {
	addr = sock_get_addr_by_name(options.serverHost);
	if (addr == NULL) {
	    warn("Failed name lookup on: %s", options.serverHost);
	    exit(1);
	}
	serverAddr = xp_strdup(addr);
	strlcpy(Server.host, options.serverHost, sizeof(Server.host));
    } else
	sock_get_local_hostname(Server.host, sizeof Server.host,
				(options.reportToMetaServer != 0 &&
				 options.searchDomainForXPilot != 0));

    Get_login_name(Server.owner, sizeof Server.owner);

    /* Log, if enabled. */
    Log_game("START");

    if (!Contact_init())
	End_game();

    Meta_init();

    Timing_setup();
    Check_playerlimit();

    if (Setup_net_server() == -1)
	End_game();

#ifndef _WINDOWS
    if (options.NoQuit)
	signal(SIGHUP, SIG_IGN);
    else
	signal(SIGHUP, Handle_signal);
    signal(SIGTERM, Handle_signal);
    signal(SIGINT, Handle_signal);
    signal(SIGPIPE, SIG_IGN);
#ifdef IGNORE_FPE
    signal(SIGFPE, SIG_IGN);
#endif
#endif	/* _WINDOWS */

    /*
     * Set the time the server started
     */
    serverStartTime = time(NULL);

    xpprintf("%s Server runs at %d frames per second\n",
	     showtime(), options.framesPerSecond);

    teamcup_init();

#ifdef SELECT_SCHED
    install_timer_tick(Main_loop, FPS);
#else
    if (options.timerResolution > 0)
	timer_tick_rate = options.timerResolution;
    else
	timer_tick_rate = FPS;

# ifdef _WINDOWS
    /* Windows returns here, we let the worker thread call sched() */
    install_timer_tick(ServerThreadTimerProc, timer_tick_rate);
# else
    install_timer_tick(Main_loop, timer_tick_rate);

# endif
#endif

    sched();
    End_game();

    /* NOT REACHED */
    abort();
}