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