src/proto2/NetworkServer.cc
author terom
Sat, 08 Nov 2008 20:34:14 +0000
changeset 22 b70d30e1b0fe
parent 21 32c6cc55256a
child 23 8d802b573cf0
permissions -rw-r--r--
all the network code is now there, although it doesn't quite work
#include "NetworkServer.hh"
#include "Engine.hh"

#include <iostream>
#include <cassert>

NetworkServer::NetworkServer (GameState &state, const std::string &listen_port) : 
	NetworkCore(state), pid_pool(0) {
	
	// connect slots
	slots.connect(netsession.sig_computer_connected(), this, &NetworkServer::on_connect);
	slots.connect(netsession.sig_computer_disconnected(), this, &NetworkServer::on_disconnect);
	
	// and then we listen
	netsession.start_listen(listen_port);
}

void NetworkServer::on_connect (CL_NetComputer &computer) {
	// assign a pid
	uint16_t pid = ++pid_pool;
	
	// log
	std::cout << "[server.on_connect] INFO: " << computer.get_address().get_address() << " -> #" << pid << std::endl;

	// create the player object
	NetworkServerPlayer *player = new NetworkServerPlayer(*this, computer, pid);
	
	// map computer to it
	players[computer] = player;

	// add to GameState
	state.newRemotePlayer(player);
}

void NetworkServer::on_disconnect (CL_NetComputer &computer) {
	std::cout << "NetworkServer.on_disconnect: " << computer.get_address().get_address() << std::endl;

	// XXX: remove the player
	NetworkServerPlayer *player = players[computer];
	
	// remove from players
	players.erase(computer);

	// remove from state
	state.removePlayer(player);

	// remove from game
	player->disconnected();

	// delete
	delete player;
}
		
NetworkServerPlayer::NetworkServerPlayer (NetworkServer &server, CL_NetComputer &computer, uint16_t pid) : 
	RemotePlayer(Coordinate(0, 0), true), server(server), computer(computer), netobj(&server.netobjs), pid(pid) {
	
	// messages
	slots.connect(netobj.sig_received_message(NETMSG_CLIENT_MOVE), this, &NetworkServerPlayer::on_move);	

	// the initial NETMSG_PLAYER_HELLO
	CL_NetPacket hello_pkt;
	hello_pkt.output.write_uint32(position.x);
	hello_pkt.output.write_uint32(position.y);

	netobj.send(computer, NETMSG_SERVER_HELLO, hello_pkt, true);

	// send other player objects
	for (std::map<CL_NetComputer, NetworkServerPlayer*>::iterator it = server.players.begin(); it != server.players.end(); it++) {
		NetworkServerPlayer *player = it->second;
		CL_NetPacket player_pkt;
		
		// player is not in players list yet
		assert(player != this);

		player_pkt.output.write_uint32(player->position.x);
		player_pkt.output.write_uint32(player->position.y);

		player->netobj.send(computer, NETMSG_PLAYER_INFO, player_pkt, true);
	}


	// broadcast NETMSG_PLAYER_JOIN to all clients
	netobj.send(server.netsession.get_all(), NETMSG_PLAYER_JOIN, hello_pkt, true);
}

void NetworkServerPlayer::disconnected (void) {
	CL_NetPacket pkt;

	netobj.send(server.netsession.get_all(), NETMSG_PLAYER_QUIT, pkt, true);
}

void NetworkServerPlayer::on_move (CL_NetComputer &from, CL_NetPacket &pkt) {
	// sanity-check
	if (!(from == computer))
		return;
	
	// read packet
	uint32_t dx = pkt.input.read_uint32();
	uint32_t dy = pkt.input.read_uint32();

	// movement delta
	PositionDelta delta(dx, dy);

	// apply movement
	position += delta;

	// send position update
	send_position_update();
}
		
void NetworkServerPlayer::send_position_update (void) {
	CL_NetPacket pkt;
	pkt.output.write_uint32(position.x);
	pkt.output.write_uint32(position.y);

	netobj.send(server.netsession.get_all(), NETMSG_PLAYER_POSITION, pkt, false);
}