Exemplo n.º 1
0
/*
 * @brief
 */
void Sv_KickClient(sv_client_t *cl, const char *msg) {
	char buf[MAX_STRING_CHARS], name[32];

	if (!cl)
		return;

	if (cl->state < SV_CLIENT_CONNECTED)
		return;

	if (*cl->name == '\0') // force a name to kick
		strcpy(name, "player");
	else
		g_strlcpy(name, cl->name, sizeof(name));

	memset(buf, 0, sizeof(buf));

	if (msg && *msg != '\0')
		g_snprintf(buf, sizeof(buf), ": %s", msg);

	Sv_ClientPrint(cl->edict, PRINT_HIGH, "You were kicked%s\n", buf);

	Sv_DropClient(cl);

	Sv_BroadcastPrint(PRINT_HIGH, "%s was kicked%s\n", name, buf);
}
Exemplo n.º 2
0
/*
 * @brief
 */
static void Sv_CheckTimeouts(void) {

	const uint32_t timeout = 1000 * sv_timeout->value;

	if (timeout > quetoo.time)
		return;

	const uint32_t whence = quetoo.time - timeout;

	sv_client_t *cl = svs.clients;
	for (int32_t i = 0; i < sv_max_clients->integer; i++, cl++) {

		if (cl->state == SV_CLIENT_FREE)
			continue;

		if (cl->last_message < whence) {
			Sv_BroadcastPrint(PRINT_MEDIUM, "%s timed out\n", cl->name);
			Sv_DropClient(cl);
		}
	}
}
Exemplo n.º 3
0
/*
 * @brief
 */
static void Sv_CheckTimeouts(void) {
	sv_client_t * cl;
	int32_t i;

	const uint32_t timeout = svs.real_time - 1000 * sv_timeout->value;

	if (timeout > svs.real_time) {
		// the server is just starting, don't bother
		return;
	}

	for (i = 0, cl = svs.clients; i < sv_max_clients->integer; i++, cl++) {

		if (cl->state == SV_CLIENT_FREE)
			continue;

		// enforce timeouts by dropping the client
		if (cl->last_message < timeout) {
			Sv_BroadcastPrint(PRINT_HIGH, "%s timed out\n", cl->name);
			Sv_DropClient(cl);
		}
	}
}
Exemplo n.º 4
0
/*
 * Sv_ParseClientMessage
 *
 * The current net_message is parsed for the given client.
 */
void Sv_ParseClientMessage(sv_client_t *cl) {
	user_cmd_t null_cmd, oldest_cmd, old_cmd, new_cmd;
	int net_drop;
	int strings_issued;
	int moves_issued;
	int last_frame;
	int c;
	char *s;

	sv_client = cl;
	sv_player = sv_client->edict;

	// allow a finite number of moves and strings
	moves_issued = strings_issued = 0;

	while (true) {

		if (net_message.read > net_message.size) {
			Com_Warn("Sv_ParseClientMessage: Bad read from %s\n",
					Sv_NetaddrToString(sv_client));
			Sv_DropClient(cl);
			return;
		}

		c = Msg_ReadByte(&net_message);
		if (c == -1)
			break;

		switch (c) {

		case CL_CMD_USER_INFO:
			strncpy(cl->user_info, Msg_ReadString(&net_message), sizeof(cl->user_info) - 1);
			Sv_UserInfoChanged(cl);
			break;

		case CL_CMD_MOVE:
			if (++moves_issued > CMD_MAX_MOVES) {
				return; // someone is trying to cheat
			}

			last_frame = Msg_ReadLong(&net_message);
			if (last_frame != cl->last_frame) {
				cl->last_frame = last_frame;
				if (cl->last_frame > -1) {
					cl->frame_latency[cl->last_frame & (CLIENT_LATENCY_COUNTS
							- 1)] = svs.real_time - cl->frames[cl->last_frame
							& UPDATE_MASK].sent_time;
				}
			}

			memset(&null_cmd, 0, sizeof(null_cmd));
			Msg_ReadDeltaUsercmd(&net_message, &null_cmd, &oldest_cmd);
			Msg_ReadDeltaUsercmd(&net_message, &oldest_cmd, &old_cmd);
			Msg_ReadDeltaUsercmd(&net_message, &old_cmd, &new_cmd);

			// don't start delta compression until the client is spawned
			// TODO: should this be a little higher up?
			if (cl->state != SV_CLIENT_ACTIVE) {
				cl->last_frame = -1;
				break;
			}

			// catch extremely high msec movements
			if (null_cmd.msec > CMD_MAX_MSEC || oldest_cmd.msec > CMD_MAX_MSEC
					|| old_cmd.msec > CMD_MAX_MSEC || new_cmd.msec
					> CMD_MAX_MSEC) {
				Com_Warn("Sv_ParseClientMessage: Illegal msec from %s\n",
						Sv_NetaddrToString(cl));
				Sv_KickClient(cl, "Illegal movement");
				return;
			}

			net_drop = cl->netchan.dropped;
			if (net_drop < 20) {
				while (net_drop > 2) {
					Sv_ClientThink(cl, &cl->last_cmd);
					net_drop--;
				}
				if (net_drop > 1)
					Sv_ClientThink(cl, &oldest_cmd);
				if (net_drop > 0)
					Sv_ClientThink(cl, &old_cmd);
			}
			Sv_ClientThink(cl, &new_cmd);
			cl->last_cmd = new_cmd;
			break;

		case CL_CMD_STRING:
			s = Msg_ReadString(&net_message);

			// malicious users may try using too many string commands
			if (++strings_issued < CMD_MAX_STRINGS)
				Sv_UserStringCommand(s);
			else {
				Com_Warn(
						"Sv_ParseClientMessage: CMD_MAX_STRINGS exceeded for %s\n",
						Sv_NetaddrToString(cl));
				Sv_KickClient(cl, "Too many commands.");
				return;
			}

			if (cl->state == SV_CLIENT_FREE)
				return; // disconnect command
			break;

		default:
			Com_Print("Sv_ParseClientMessage: unknown command %d\n", c);
			Sv_DropClient(cl);
			return;
		}
	}
}
Exemplo n.º 5
0
/*
 * Sv_Disconnect_f
 *
 * The client is going to disconnect, so remove the connection immediately
 */
static void Sv_Disconnect_f(void) {
	Sv_DropClient(sv_client);
}