示例#1
0
/**
 * @brief Callback for subsystem failures. Depending on the severity, we may try to
 * recover, or we may shut the entire engine down and exit.
 */
static void Error(err_t err, const char *msg) {

	if (quetoo.debug_mask & DEBUG_BREAKPOINT) {
		SDL_TriggerBreakpoint();
	}

	Print(va("^1%s\n", msg));

	if (err == ERROR_DROP && !jmp_set) {
		err = ERROR_FATAL;
	}

	switch (err) {
		case ERROR_DROP:
			Sv_ShutdownServer(msg);
			Cl_Disconnect();
			quetoo.recursive_error = false;
			longjmp(env, err);
			break;

		case ERROR_FATAL:
		default:
			Sys_Backtrace();
			Shutdown(msg);
			exit(err);
			break;
	}
}
示例#2
0
/*
 * @brief Entry point for spawning a new server or changing maps / demos. Brings any
 * connected clients along for the ride by broadcasting a reconnect before
 * clearing state. Special effort is made to ensure that a locally connected
 * client sees the reconnect message immediately.
 */
void Sv_InitServer(const char *server, sv_state_t state) {
#ifdef BUILD_CLIENT
	extern void Cl_Disconnect(void);
#endif
	char path[MAX_QPATH];

	Com_Debug("Sv_InitServer: %s (%d)\n", server, state);

	Cbuf_CopyToDefer();

	// ensure that the requested map or demo exists
	if (state == SV_ACTIVE_DEMO)
		g_snprintf(path, sizeof(path), "demos/%s.dem", server);
	else
		g_snprintf(path, sizeof(path), "maps/%s.bsp", server);

	if (!Fs_Exists(path)) {
		Com_Print("Couldn't open %s\n", path);
		return;
	}

	// inform any connected clients to reconnect to us
	Sv_ShutdownMessage("Server restarting...\n", true);

#ifdef BUILD_CLIENT
	// disconnect any local client, they'll immediately reconnect
	Cl_Disconnect();
#endif

	// clear the sv_server_t structure
	Sv_ClearState();

	Com_Print("Server initialization...\n");

	// initialize the clients, loading the game module if we need it
	Sv_InitClients();

	// load the map or demo and related media
	Sv_LoadMedia(server, state);
	sv.state = state;

	Sb_Init(&sv.multicast, sv.multicast_buffer, sizeof(sv.multicast_buffer));

	Com_Print("Server initialized\n");
	Com_InitSubsystem(Q2W_SERVER);

	svs.initialized = true;
}
示例#3
0
文件: cl_main.c 项目: chrisnew/quetoo
/*
 * @brief Re-send a connect message if the last one has timed out.
 */
static void Cl_CheckForResend(void) {

	// if the local server is running and we aren't then connect
	if (Com_WasInit(QUETOO_SERVER) && g_strcmp0(cls.server_name, "localhost")) {

		if (cls.state > CL_DISCONNECTED) {
			Cl_Disconnect();
		}

		g_strlcpy(cls.server_name, "localhost", sizeof(cls.server_name));

		cls.state = CL_CONNECTING;
		cls.connect_time = 0;
	}

	// re-send if we haven't received a reply yet
	if (cls.state != CL_CONNECTING)
		return;

	// don't flood connection packets
	if (cls.connect_time && (quetoo.time - cls.connect_time < 1000))
		return;

	net_addr_t addr;

	if (!Net_StringToNetaddr(cls.server_name, &addr)) {
		Com_Print("Bad server address\n");
		cls.state = CL_DISCONNECTED;
		return;
	}

	if (addr.port == 0)
		addr.port = htons(PORT_SERVER);

	cls.connect_time = quetoo.time; // for retransmit requests

	const char *s = Net_NetaddrToString(&addr);
	if (g_strcmp0(cls.server_name, s)) {
		Com_Print("Connecting to %s (%s)...\n", cls.server_name, s);
	} else {
		Com_Print("Connecting to %s...\n", cls.server_name);
	}

	Netchan_OutOfBandPrint(NS_UDP_CLIENT, &addr, "get_challenge\n");
}
示例#4
0
文件: cl_main.c 项目: chrisnew/quetoo
/*
 * @brief
 */
static void Cl_Connect_f(void) {

	if (Cmd_Argc() != 2) {
		Com_Print("Usage: %s <address>\n", Cmd_Argv(0));
		return;
	}

	if (Com_WasInit(QUETOO_SERVER)) { // if running a local server, kill it
		Sv_ShutdownServer("Server quit\n");
	}

	Cl_Disconnect();

	strncpy(cls.server_name, Cmd_Argv(1), sizeof(cls.server_name));
	cls.server_name[sizeof(cls.server_name) - 1] = '\0';

	cls.state = CL_CONNECTING;
	cls.connect_time = 0; // fire immediately
}