--- a/src/Network/Client.cc Mon Dec 08 16:39:20 2008 +0000
+++ b/src/Network/Client.cc Mon Dec 08 16:44:38 2008 +0000
@@ -40,12 +40,7 @@
}
void NetworkClient::player_quit (NetworkClientRemotePlayer *player) {
- // inform state
- state.removePlayer(player);
-
- // delete
- // XXX: leak because deleting the slot while it's being called breaks ClanLib
- // delete player;
+ (void) player;
}
/*
@@ -275,8 +270,15 @@
Engine::log(INFO, "client_player.on_quit") << this;
client.player_quit(this);
+
+ // delete
+ // XXX: leak because deleting the slot while it's being called breaks ClanLib
+ // delete this;
}
+/*
+ * NetworkClientProjectile
+ */
NetworkClientProjectile::NetworkClientProjectile (NetworkClient &client, NetworkObjectID obj_id, Player *player,
Vector position, Vector velocity, Weapon *weapon) :
NetworkClientObject(client, obj_id), Projectile(player, position, velocity, weapon)
--- a/src/Network/Client.hh Mon Dec 08 16:39:20 2008 +0000
+++ b/src/Network/Client.hh Mon Dec 08 16:44:38 2008 +0000
@@ -10,26 +10,56 @@
class NetworkClientLocalPlayer;
class NetworkClientRemotePlayer;
+/**
+ * Our specialized NetworkObject_ClientController that overrides handle_create to create the right kind of
+ * object (a subclass of NetowrkClientObject).
+ */
class NetworkClientController : public NetworkObject_ClientController {
protected:
+ /**
+ * The NetworkClient
+ */
NetworkClient &client;
public:
+ /**
+ * Control objects on the given client using the client.netsession's NETCHAN_CORE channel
+ */
NetworkClientController (NetworkClient &client);
protected:
/**
- * We override handle_create from NetworkObject_ClientController to construct the correct
- * NetworkClientObject-deriving object (LocalPlayer, RemotePlayer, Projectile) ourselves
+ * We override handle_create from NetworkObject_ClientController to call one of the on_* methods, which creates
+ * a NetworkClientObject subclass
+ *
+ * @see NetworkObject_ClientController::handle_create
*/
virtual void handle_create (NetworkObjectID obj_id, NetworkMessageID msg_id, NetworkPacketInput &pkt, NetworkNode *node);
-
+
+ /**
+ * Handle NETMSG_SERVER_HELLO -> NetworkClientLocalPlayer
+ */
void on_server_hello (NetworkObjectID obj_id, NetworkPacketInput &pkt);
+
+ /**
+ * Handle NETMSG_PLAYER_INFO -> NetworkClientRemotePlayer
+ */
void on_player_info (NetworkObjectID obj_id, NetworkPacketInput &pkt);
+
+ /**
+ * Handle NETMSG_PLAYER_JOIN -> NetworkClientRemotePlayer
+ */
void on_player_join (NetworkObjectID obj_id, NetworkPacketInput &pkt);
+
+ /**
+ * Handle NETMSG_PROJECTILE_PLAYER_FIRED -> NetworkClientProjectile
+ */
void on_projectile_player_fired (NetworkObjectID obj_id, NetworkPacketInput &pkt);
};
+/**
+ * Our NetworkClient, that connects to a NetworkServer. This has the GameState, NetworkSession, NetworkClientController, etc.
+ */
class NetworkClient {
friend class NetworkClientController;
friend class NetworkClientObject;
@@ -39,75 +69,175 @@
friend class NetworkClientProjectile;
protected:
+ /**
+ * The GameState
+ */
GameState &state;
+
CL_SlotContainer slots;
+
+ /**
+ * The connect()-mode NetworkSession
+ */
+ NetworkSession netsession;
- NetworkSession netsession;
+ /**
+ * The server NetworkNode from Netsession::connect
+ */
NetworkNode *server;
+
+ /**
+ * Our specialized NetworkObject_ClientController
+ */
NetworkClientController controller;
public:
+ /**
+ * Create a NetworkClient with the given GameState, connecting a server on the given NetworkAddress
+ *
+ * @param state the GameState to use
+ * @param connect_to the address to connect to
+ */
NetworkClient (GameState &state, const NetworkAddress &connect_to);
protected:
-
/**
- * Receive the terrain array from the server and apply it to the state.world's terrain
+ * Receive the NETCHAN_TERRAIN_ARRAY message from the server and apply it to our GameState::world terrain
*/
void on_terrain_array (NetworkPacketInput &pkt, NetworkNode *node);
public:
+ /**
+ * Called by NetworkClientRemotePlayer when they get disconnected. Doesn't do anything currently
+ */
void player_quit (NetworkClientRemotePlayer *player);
};
+/**
+ * Our base NetworkObject_Client object, containing the NetworkClient and a CL_SlotContainer for conveniance
+ */
class NetworkClientObject : public NetworkObject_Client {
protected:
+ /**
+ * The NetworkClient
+ */
NetworkClient &client;
CL_SlotContainer slots;
-
+
+ /**
+ * Construct this using the given client and obj_id, passing the client.controller and obj_id to the
+ * NetworkObject_Client's constructor
+ */
NetworkClientObject (NetworkClient &client, NetworkObjectID obj_id);
};
+/**
+ * Our base class for NetworkClient Players, this implements most of the server -> client messages
+ *
+ * This inherits from NetworkClientObject and virtually from Player, as classes should inherit from both this and
+ * LocalPlayer/RemotePlayer
+ */
class NetworkClientPlayerBase : public NetworkClientObject, public virtual Player {
protected:
+ /**
+ * Dummy-initialize Player, initialize NetworkClientObject, and hook up our signals
+ */
NetworkClientPlayerBase (NetworkClient &client, NetworkObjectID obj_id, Vector position);
private:
+ /**
+ * NETMSG_PLAYER_POSITION -> PhysicsObject::updatePhysics
+ */
void on_position (NetworkPacketInput &pkt);
+
+ /**
+ * NETMSG_PLAYER_DIG -> Player::handleDig
+ */
void on_dig (NetworkPacketInput &pkt);
+
+ /**
+ * NETMSG_PLAYER_WEAPON_CHANGE -> Player::rope.handleChangeWeapon
+ */
void on_weapon_change (NetworkPacketInput &pkt);
+
+ /**
+ * NETMSG_PLAYER_ROPE_THROW -> Player::rope.updateState(ROPE_FLYING)
+ */
void on_rope_throw (NetworkPacketInput &pkt);
+
+ /**
+ * NETMSG_PLAYER_ROPE_FIXED -> Player::rope.updateState(ROPE_FIXED)
+ */
void on_rope_fixed (NetworkPacketInput &pkt);
+
+ /**
+ * NETMSG_PLAYER_ROPE_RELEASED -> Player::rope.updateState(ROPE_FOLDED)
+ */
void on_rope_released (NetworkPacketInput &pkt);
+
+ /**
+ * NETMSG_PLAYER_ROPE_LENGTH -> Player::Rope.updateLength
+ */
void on_rope_length (NetworkPacketInput &pkt);
};
+/**
+ * Our NetworkClientPlayerBase + LocalPlayer specialization, this lets us handle local input
+ */
class NetworkClientLocalPlayer : public NetworkClientPlayerBase, public LocalPlayer {
public:
+ /**
+ * Calls NetworkClientPlayerBase/Player constructors, calls GameState::setLocalPlayer
+ */
NetworkClientLocalPlayer (NetworkClient &client, NetworkObjectID obj_id, Vector position);
+ /**
+ * Overriden from LocalPlayer to send a NETMSG_CLIENT_INPUT message without executing LocalPlayer::handleInput
+ * locally
+ */
virtual void handleInput (PlayerInput input, TimeMS dt);
};
+/**
+ * Our NetworkClientPlayerBase + RemotePlayer specialization, this lets us handle players quitting
+ */
class NetworkClientRemotePlayer : public NetworkClientPlayerBase, public RemotePlayer {
public:
+ /**
+ * Calls NetworkClientPlayerBase/Player constructors and hooks up signals
+ */
NetworkClientRemotePlayer (NetworkClient &client, NetworkObjectID obj_id, Vector position);
private:
+ /**
+ * Calls NetworkClient::player_quit, and then destroys ourselves
+ */
void on_quit (NetworkPacketInput &pkt);
-
};
+/**
+ * A Projectile that was created on the server
+ */
class NetworkClientProjectile : public NetworkClientObject, public Projectile {
public:
+ /**
+ * Call Projectile's constructor, hook up signals and call player->weaponFired
+ */
NetworkClientProjectile (NetworkClient &client, NetworkObjectID obj_id, Player *player, Vector position,
Vector velocity, Weapon *weapon);
protected:
+ /**
+ * Overrides Projectile::onDestroy to ignore this, as we must wait for the server to tell us where it impacted
+ * so that we can remove the ground reliably
+ */
virtual void onDestroy (Vector position, bool removeGround);
private:
+ /**
+ * NETMSG_PROJECTILE_DESTROY -> Projectile::onDestory
+ */
void on_destroy (NetworkPacketInput &pkt);
};