reorganize Terrain/PhysicsWorld/GameState/Engine to use NetworkClientConnect, and hence handle the connection process asynchronously, and finally properly implement receiving the terrain data from the server
#ifndef NETWORKSERVER_HH
#define NETWORKSERVER_HH
/**
* @file
*
* Game server implementation
*/
#include "../GameState.hh"
#include "Session.hh"
#include "Object.hh"
#include <list>
#include <map>
#include <ClanLib/core.h>
// forward-declare
class NetworkServerPlayer;
/**
* Our game's NetworkServer... this has the GameState, NetworkSession, etc
*/
class NetworkServer {
friend class NetworkServerObject;
friend class NetworkServerPlayer;
friend class NetworkServerProjectile;
protected:
/**
* The GameState
*/
GameState &state;
CL_SlotContainer slots;
/**
* The server-mode NetworkSession
*/
NetworkSession netsession;
/**
* The NetworkObject_ServerController that we use
*/
NetworkObject_ServerController controller;
/**
* A list of NetworkServerPlayer's, used when a new player connects to send it information about existing
* NetworkServerPlayer objects
*/
std::list<NetworkServerPlayer *> players;
public:
/**
* Construct a NetworkServer, using the given GameState and listening on the given address
*/
NetworkServer (GameState &state, const NetworkEndpoint &listen_addr);
protected:
/**
* Called by NetworkServerPlayer when it disconnects, this removes it from our list
*/
void handle_disconnect (NetworkServerPlayer *player);
private:
/**
* Our NetworkSession::sig_node_connected handler, this creates a new NetworkServerPlayer and adds it to
* our list of players
*/
void on_node_connected (NetworkNode *node);
/**
* Called from on_node_connected to send the initial Terrain data using the NETCHAN_TERRAIN_ARRAY channel to
* the given node.
*/
void send_terrain_data (NetworkNode *node);
};
/**
* Our base NetworkObject_Server class, that also holds the NetworkServer reference and a CL_SlotContainer for
* conveniance.
*/
class NetworkServerObject : public NetworkObject_Server {
protected:
/**
* Our NetworkServer
*/
NetworkServer &server;
CL_SlotContainer slots;
/**
* Constructs this NetworkServerObject, passing the server's controller to the NetworkObject_Server constructor
*/
NetworkServerObject (NetworkServer &server);
};
/**
* A remote player on this server, this is both a LocalPlayer and a NetworkServerObject
*/
class NetworkServerPlayer : public LocalPlayer, public NetworkServerObject {
protected:
/**
* The remote node that represents this actual player
*/
NetworkNode *node;
public:
/**
* Construct this using the given server (for NetworkServerObject) and node (for node).
*
* We send the initial NETMSG_SERVER_HELLO to the client, then a set of NETMSG_PLAYER_INFOs
* for all the other players, a NETMSG_PLAYER_JOIN to all the other clients, and then calls
* send_terrain_data to sync the initial terrain.
*
* @see NetworkServerObject
*/
NetworkServerPlayer (NetworkServer &server, NetworkNode *node);
protected:
// @{
/**
* These methods are overriden from Player to replicate events to our clients
*/
virtual void handleDig (Vector position, float radius);
virtual void handleFireWeapon (Weapon *weapon, Vector position, Vector velocity);
virtual void handleChangeWeapon (unsigned int weaponIndex);
virtual void handleRopeState (RopeState state);
virtual void handleRopeLength (float length);
virtual void spawn (Vector position);
virtual void die (bool start_timer = true);
// @}
//
private:
/**
* Our NetworkNode::sig_disconnected handler. This calls NetworkServer::handle_disconnect, sends a
* NETMSG_PLAYER_QUIT message to all remaining clients, and destroys this player.
*/
void on_disconnected (void);
/*
* Our NETMSG_PLAYER_INPUT handler. This calls our superclass LocalPlayer::handleInput, which may then call
* the various handle* methods. After this, we call send_position_update
*/
void on_input (NetworkNode *node, NetworkPacketInput &pkt);
/**
* Called from on_input to broadcast an unreliable position update with this player's physics state
*/
void send_position_update (void);
};
/**
* A Projectile, replicated across the network.
*
* These are created by NetworkServerPlayer::handleFireWeapon
*/
class NetworkServerProjectile : public Projectile, public NetworkServerObject {
public:
/**
* Call the Projectile construtor, and then send NETMSG_PROJECTILE_PLAYER_FIRED
*
* @param server the NetworkServer
* @param player the NetworkServerPlayer that fired the weapon
* @param position the Projectile's initial position
* @param velocity the Projectile's initial velocity
* @param weapon the Player's Weapon that was fired
*/
NetworkServerProjectile (NetworkServer &server, NetworkServerPlayer *player, Vector position, Vector velocity, Weapon *weapon);
protected:
/**
* Overriden from Projectile to send a NETMSG_PROJECTILE_DESTROY with the given position and flags
*
* @param position the Projectile's final position, where the ground gets removed
* @param removeGround controls the NETWORK_PROJECTILE_REMOVE_GROUND flag
*/
virtual void onDestroy (Vector position, bool removeGround);
/**
* Overriden from Projectile to send a NETMSG_PROJECTILE_HIT_PLAYER with the given player
*
* @param player the NetworkServerPlayer that got hit
*/
virtual void onHitPlayer (Player *player_ptr);
};
#endif