Example #1
0
File: server.cpp Project: elipp/car
int server_post_peer_list() {
	
	// <horrible workaround>
	std::string peer_list_str = "TT;";
	peer_list_str[0] = S_PEER_LIST;
	peer_list_str[1] = (char)clients.size();
	// </horrible workaround>

	id_client_map::iterator iter = clients.begin();
	while (true) {
		struct client &itclient = (*iter).second;
		peer_list_str = peer_list_str + int_to_string(itclient.id) + ":" + itclient.name + ":" + itclient.ip_string;
		++iter;
		if (iter != clients.end()) {
			peer_list_str = peer_list_str + ';';
		}
		else {
			break;
		}
	}
	iter = clients.begin();
	while (iter != clients.end()) {
		std::cerr << "server_post_peer_list: peer_list_str = \"" << peer_list_str << "\"\n";
		server_send_packet((unsigned char*)peer_list_str.c_str(), peer_list_str.length(), &(*iter).second);
		++iter;
	}
	return 1;
}
Example #2
0
File: server.cpp Project: elipp/car
int server_post_quit_message() {

	interm_buf[0] = S_QUIT;
	interm_buf[1] = '\0';

	id_client_map::iterator iter = clients.begin();
	while (iter != clients.end()) {
		server_send_packet(interm_buf, 1, &(*iter).second);
		++iter;
	}
	return 1;
}
Example #3
0
static void initial_update(client_t *client) {
    // Protokoll Version senden
    packet_t packet;
    packet_init(&packet, PACKET_HANDSHAKE);
    packet_write08(&packet, PROTOCOL_VERSION);
    server_send_packet(&packet, client);

    server_start_compression(client);

    game_send_initial_update(client);
    world_send_initial_update(client);
    player_send_initial_update(client);
    creature_send_initial_update(client);
}
Example #4
0
File: server.cpp Project: elipp/car
int server_process_packet(struct sockaddr_in *from) {

	unsigned int from_address = ntohl(from->sin_addr.s_addr);
	unsigned short from_port = ntohs(from->sin_port);
	char *inet_addr = inet_ntoa(from->sin_addr);

	if (packet_data[0] == C_HANDSHAKE) {
		std::cerr << "client @ " << inet_addr << ":" << from_port << " :handshake request\n";
		int newclient_id = server_add_client(from);
		if (newclient_id < 0) { std::cerr << "server_add_client: error.\n"; return -1; }
		interm_buf[0] = S_HANDSHAKE_OK;
		interm_buf[1] = newclient_id;
		interm_buf[2] = 0;
		struct client *newclient = get_client_by_id(newclient_id);
		server_send_packet(interm_buf, 2, newclient);
		server_post_peer_list();
	}
	else if (packet_data[0] == C_QUIT) {
		unsigned short id = packet_data[1];
		struct client *quitting_client = get_client_by_id(id);
		if (quitting_client) {
			std::cerr << "Client " << quitting_client->name << " with id " << quitting_client->id << " quitting.\n";
			server_remove_client(id);
		}
		else {
			std::cerr << "client with id " << id << "not found.\n";
		}
	}
	else if (packet_data[0] == C_KEYSTATE) {
		unsigned short id = packet_data[1];
		client *c = get_client_by_id(id);
		if (c) {
			c->keystate = packet_data[2];
			server_update_client_status(c);
			server_post_position_update(c);
		}
	}	
	else { 
		return 0;
	}
}
Example #5
0
File: server.cpp Project: elipp/car
int server_post_position_update(client *c) {
	//time_t ms = timer.get_ms();
	//std::cerr << "time since last pupd: " << ms << " ms.\n";
	//timer.begin();
	//memset(posupd_packet_buffer, 0, maximum_packet_size); ***
	interm_buf[0] = S_PUPD;
	interm_buf[1] = c->id;

	struct car_serialized cs = c->lcar.serialize();
	memcpy(&interm_buf[2], (const void*)&cs, sizeof(cs));

	size_t total_packet_size = 2 + sizeof(cs);
	interm_buf[total_packet_size] = '\0';


	id_client_map::iterator iter = clients.begin();
	while (iter != clients.end()) {
		server_send_packet(interm_buf, total_packet_size, &(*iter).second);
		++iter;
	}
}
Example #6
0
void server_start_compression(client_t *client) {
    // Kompression bereits aktiviert?
    if (client->compress)
        return;

    // Demos sind immer unkomprimiert. Eine Kompression ueber 
    // die erstellte Datei macht wesentlich mehr Sinn.
    if (client->is_file_writer)
        return; 

    client->strm.zalloc = Z_NULL;
    client->strm.zfree  = Z_NULL;
    client->strm.opaque = NULL;
    if (deflateInit(&client->strm, 9) != Z_OK) {
        fprintf(stderr, "cannot alloc new zstream\n");
        return;
    }

    packet_t packet;
    packet_init(&packet, PACKET_START_COMPRESS);
    server_send_packet(&packet, client);
    client->compress  = 1;
}
Example #7
0
static void server_mainloop(void) {
	atexit(server_atexit_handler);
	fd_set new_readfds, new_writefds;
	FD_ZERO(&new_readfds);
	FD_ZERO(&new_writefds);
	FD_SET(server.socket, &new_readfds);
	int new_fdmax = server.socket;
	bool exit_packet_delivered = false;

	if (server.read_pty)
		FD_SET_MAX(server.pty, &new_readfds, new_fdmax);

	while (server.clients || !exit_packet_delivered) {
		int fdmax = new_fdmax;
		fd_set readfds = new_readfds;
		fd_set writefds = new_writefds;
		FD_SET_MAX(server.socket, &readfds, fdmax);

		if (select(fdmax+1, &readfds, &writefds, NULL, NULL) == -1) {
			if (errno == EINTR)
				continue;
			die("server-mainloop");
		}

		FD_ZERO(&new_readfds);
		FD_ZERO(&new_writefds);
		new_fdmax = server.socket;

		bool pty_data = false;

		Packet server_packet, client_packet;

		if (FD_ISSET(server.socket, &readfds))
			server_accept_client();

		if (FD_ISSET(server.pty, &readfds))
			pty_data = server_read_pty(&server_packet);

		for (Client **prev_next = &server.clients, *c = server.clients; c;) {
			if (FD_ISSET(c->socket, &readfds) && server_recv_packet(c, &client_packet)) {
				switch (client_packet.type) {
				case MSG_CONTENT:
					server_write_pty(&client_packet);
					break;
				case MSG_ATTACH:
					c->flags = client_packet.u.i;
					if (c->flags & CLIENT_LOWPRIORITY)
						server_sink_client();
					break;
				case MSG_RESIZE:
					c->state = STATE_ATTACHED;
				case MSG_REDRAW:
					if (!(c->flags & CLIENT_READONLY) && (client_packet.type == MSG_REDRAW || c == server.clients)) {
						debug("server-ioct: TIOCSWINSZ\n");
						ioctl(server.pty, TIOCSWINSZ, &client_packet.u.ws);
					}
					kill(-server.pid, SIGWINCH);
					break;
				case MSG_EXIT:
					exit_packet_delivered = true;
					/* fall through */
				case MSG_DETACH:
					c->state = STATE_DISCONNECTED;
					break;
				default: /* ignore package */
					break;
				}
			}

			if (c->state == STATE_DISCONNECTED) {
				bool first = (c == server.clients);
				Client *t = c->next;
				client_free(c);
				*prev_next = c = t;
				if (first && server.clients) {
					Packet pkt = {
						.type = MSG_RESIZE,
						.len = 0,
					};
					server_send_packet(server.clients, &pkt);
				} else if (!server.clients) {
					server_mark_socket_exec(false, true);
				}
				continue;
			}

			FD_SET_MAX(c->socket, &new_readfds, new_fdmax);

			if (pty_data)
				server_send_packet(c, &server_packet);
			if (!server.running) {
				if (server.exit_status != -1) {
					Packet pkt = {
						.type = MSG_EXIT,
						.u.i = server.exit_status,
						.len = sizeof(pkt.u.i),
					};
					if (!server_send_packet(c, &pkt))
						FD_SET_MAX(c->socket, &new_writefds, new_fdmax);
				} else {
					FD_SET_MAX(c->socket, &new_writefds, new_fdmax);
				}
			}
Example #8
0
void game_send_intermission(client_t *client) {
    packet_t packet;
    packet_init(&packet, PACKET_INTERMISSION);
    packet_writeXX(&packet, intermission, strlen(intermission));
    server_send_packet(&packet, client);
}
Example #9
0
void game_send_round_info(client_t *client, int delta) {
    packet_t packet;
    packet_init(&packet, PACKET_ROUND);
    packet_write08(&packet, delta);
    server_send_packet(&packet, client);
}
Example #10
0
void game_send_info(client_t *client) {
    packet_t packet;
    packet_init(&packet, PACKET_GAME_INFO);
    packet_write32(&packet, game_time);
    server_send_packet(&packet, client);
}
Example #11
0
void server_destroy(client_t *client, const char *reason) {
    lua_pushliteral(L, "on_client_close");
    lua_rawget(L, LUA_GLOBALSINDEX);
    lua_pushnumber(L, client_num(client));
    lua_pushstring(L, reason);
    if (lua_pcall(L, 2, 0, 0) != 0) {
        fprintf(stderr, "error calling on_client_close: %s\n", lua_tostring(L, -1));
        lua_pop(L, 1);
    }

    // Quitmeldung senden
    if (client->is_gui_client) {
        packet_t packet;
        packet_init(&packet, PACKET_QUIT_MSG);
        packet_writeXX(&packet, reason, strlen(reason));
        server_send_packet(&packet, client);
    } else {
        server_writeto(client, "connection terminated: ", 23);
        server_writeto(client, reason, strlen(reason));
        server_writeto(client, "\r\n", 2);
    }

    // Kompressionsrest flushen
    server_flush_compression(client);

    // Rest rausschreiben (hier keine Fehlerbehandlung mehr, da eh egal).
    // Bei Filewritern muss nichts geschrieben werden, da deren Daten
    // immer direkt rausgeschrieben werden.
    if (!client->is_file_writer) 
        evbuffer_write(client->out_buf, client->fd);

    evbuffer_free(client->in_buf);
    evbuffer_free(client->out_buf);

    free(client->kill_me);

    if (client->compress)
        deflateEnd(&client->strm);
    
    event_del(&client->rd_event);
    event_del(&client->wr_event);
    client->in_buf  = NULL;
    client->out_buf = NULL;

    if (client->player) 
        player_detach_client(client, client->player);

    assert(client->next == NULL);
    assert(client->prev == NULL);

    if (client->is_gui_client) {
        if (client->next_gui == client) {
            assert(client->prev_gui == client);
            guiclients = NULL;
        } else {
            client->next_gui->prev_gui = client->prev_gui;
            client->prev_gui->next_gui = client->next_gui;
            guiclients = client->next_gui;
        }
    }

    num_clients--;
    
#ifndef NO_CONSOLE_CLIENT    
    if (client->fd != STDIN_FILENO)
#endif
#ifdef WIN32
        if (client->is_file_writer) {
            close(client->fd);
        } else {
            closesocket(client->fd);
        }
#else
        close(client->fd);
#endif
}