301 lines
6.7 KiB
C++
301 lines
6.7 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:")) != -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 '?':
|
|
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;
|
|
}
|
|
|
|
//@}
|