Gobligine/metaserver/main.cpp
Tim Felgentreff b743ec9456 basic help
2016-11-10 15:25:33 +01:00

311 lines
6.9 KiB
C++

// _________ __ __
// / _____// |_____________ _/ |______ ____ __ __ ______
// \_____ \\ __\_ __ \__ \\ __\__ \ / ___\| | \/ ___/
// / \| | | | \// __ \| | / __ \_/ /_/ > | /\___ |
// /_______ /|__| |__| (____ /__| (____ /\___ /|____//____ >
// \/ \/ \//_____/ \/
// ______________________ ______________________
// T H E W A R B E G I N S
// Stratagus - A free fantasy real time strategy game engine
//
/**@name main.cpp - Primary functionality. */
//
// (c) Copyright 2005-2011 by Edward Haase and Pali Rohár
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; only version 2 of the License.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
// 02111-1307, USA.
//
//@{
/*----------------------------------------------------------------------------
-- Includes
----------------------------------------------------------------------------*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "SDL.h"
#include "stratagus.h"
#include "util.h"
#include "netdriver.h"
#include "cmd.h"
#include "db.h"
#ifndef _MSC_VER
#include <unistd.h>
#include <errno.h>
#endif
#ifdef __CYGWIN__
#include <getopt.h>
#endif
#if defined(_MSC_VER) || defined(__MINGW32__)
extern char *optarg;
extern int optopt;
extern int getopt(int argc, char *const *argv, const char *opt);
#endif
/*----------------------------------------------------------------------------
-- Functions
----------------------------------------------------------------------------*/
/// @todo Needs code cleanup.
/// @todo Needs compatibility checks.
/// @todo Needs error message unification.
#if 1 // from stratagus.cpp, to avoid link issues.
bool EnableDebugPrint; /// if enabled, print the debug messages
bool EnableAssert; /// if enabled, halt on assertion failures
bool EnableUnitDebug; /// if enabled, a unit info dump will be created
void PrintLocation(const char *file, int line, const char *funcName)
{
fprintf(stdout, "%s:%d: %s: ", file, line, funcName);
}
void AbortAt(const char *file, int line, const char *funcName, const char *conditionStr)
{
fprintf(stderr, "Assertion failed at %s:%d: %s: %s\n", file, line, funcName, conditionStr);
abort();
}
void PrintOnStdOut(const char *format, ...)
{
va_list valist;
va_start(valist, format);
vprintf(format, valist);
va_end(valist);
}
// from util.cpp
#ifndef HAVE_GETOPT
int opterr = 1;
int optind = 1;
int optopt;
char *optarg;
static void getopt_err(const char *argv0, const char *str, char opt)
{
if (opterr) {
const char *x;
while ((x = strchr(argv0, '/'))) {
argv0 = x + 1;
}
fprintf(stderr, "%s%s%c\n", argv0, str, opt);
}
}
int getopt(int argc, char *const *argv, const char *opts)
{
static int sp = 1;
register int c;
register const char *cp;
optarg = NULL;
if (sp == 1) {
if (optind >= argc || argv[optind][0] != '-' || argv[optind][1] == '\0') {
return EOF;
} else if (!strcmp(argv[optind], "--")) {
optind++;
return EOF;
}
}
optopt = c = argv[optind][sp];
if (c == ':' || (cp = strchr(opts, c)) == NULL) {
getopt_err(argv[0], ": illegal option -", (char)c);
cp = "xx"; /* make the next if false */
c = '?';
}
if (*++cp == ':') {
if (argv[optind][++sp] != '\0') {
optarg = &argv[optind++][sp];
} else if (++optind < argc) {
optarg = argv[optind++];
} else {
getopt_err(argv[0], ": option requires an argument -", (char)c);
c = (*opts == ':') ? ':' : '?';
}
sp = 1;
} else if (argv[optind][++sp] == '\0') {
optind++;
sp = 1;
}
return c;
}
#endif
#endif
/**
** Main loop
*/
static void MainLoop(void)
{
Uint32 ticks[2];
int delay;
int done;
//
// Start the transactions.
//
done = 0;
while (!done) {
ticks[0] = SDL_GetTicks();
//
// Update sessions and buffers.
//
UpdateSessions();
UpdateParser();
ticks[1] = SDL_GetTicks();
//
// Idle out the remainder of this loop.
//
if ((int)(ticks[1] - ticks[0]) > Server.PollingDelay) {
delay = 0;
} else {
delay = Server.PollingDelay - (ticks[1] - ticks[0]);
}
if (delay > 2000) {
delay = 2000;
}
SDL_Delay(delay);
}
}
/**
** The main program: initialize, parse options and arguments.
*/
int main(int argc, char **argv)
{
int status;
int i;
Server.Port = DEFAULT_PORT;
Server.MaxConnections = DEFAULT_MAX_CONN;
Server.IdleTimeout = DEFAULT_SESSION_TIMEOUT;
Server.PollingDelay = DEFAULT_POLLING_DELAY;
//
// Standard SDL Init.
//
if (SDL_Init(0) == -1) {
printf("SDL_Init: %s\n", SDL_GetError());
exit(1);
}
atexit(SDL_Quit);
//
// Parse the command line.
//
while ((i = getopt(argc, argv, "aP:pm:i:d:h")) != -1) {
switch (i) {
case 'a':
EnableAssert = true;
continue;
case 'P':
Server.Port = atoi(optarg);
if (Server.Port <= 0) {
Server.Port = DEFAULT_PORT;
}
break;
case 'p':
EnableDebugPrint = true;
continue;
case 'm':
Server.MaxConnections = atoi(optarg);
break;
case 'i':
Server.IdleTimeout = atoi(optarg);
break;
case 'd':
Server.PollingDelay = atoi(optarg);
break;
case ':':
printf("Missing argument for %c\n", optopt);
exit(0);
break;
case 'h':
printf("Arguments:\n"
"-a\tEnable asserts\n"
"-P\tSet port\n"
"-p\tEnable debug print\n"
"-m\tMax connections\n"
"-i\tIdle timeout\n"
"-d\tPolling delay\n");
exit(0);
break;
case '?':
printf("Unrecognized option: -%c\n", optopt);
break;
}
}
// Initialize the database
if (DBInit()) {
fprintf(stderr, "DBInit failed\n");
exit(1);
}
atexit(DBQuit);
//
// Initialize server.
//
// Open the server to connections.
//
if ((status = ServerInit(Server.Port)) != 0) {
if (status > 0) {
fprintf(stderr, "ERROR %d: %s\n", errno, strerror(errno)); // > 0
} else {
fprintf(stderr, "ERROR: %s\n", SDL_GetError()); // < 0
}
exit(status);
}
atexit(ServerQuit);
printf("Stratagus Metaserver Initialized on port %d.\n", Server.Port);
//
// Uncomment this line for MSVC (or other default)
// debugging of segmentation violations.
//
// signal(SIGSEGV, SIG_DFL);
MainLoop();
//
// Server tasks done.
//
// "atexit" will take over from here for cleanup.
//
printf("Stratagus Metaserver Done.\n");
return 0;
}
//@}