--- a/src/Network/Server.cc Mon Jan 26 19:52:52 2009 +0200
+++ b/src/Network/Server.cc Mon Jan 26 23:03:47 2009 +0200
@@ -5,6 +5,9 @@
#include "../Engine.hh"
#include "../Logger.hh"
+// XXX: move
+#include "Message.hh"
+
#include <cassert>
NetworkServer::NetworkServer (GameState &state, const NetworkEndpoint &listen_addr) :
@@ -23,16 +26,16 @@
Engine::log(INFO, "net.server") << "Client connected, sending terrain data: " << node->getRemoteAddress();
// send the terrain data
- send_terrain_data(node);
+ send_terrain_data(*node);
// create the player object (it logs it)
- NetworkServerPlayer *player = new NetworkServerPlayer(*this, node);
+ NetworkServerPlayer *player = new NetworkServerPlayer(*this, *node);
// add to players
players.push_back(player);
}
-void NetworkServer::send_terrain_data (NetworkNode *node) {
+void NetworkServer::send_terrain_data (NetworkNode &node) {
Terrain &terrain = state.world.terrain;
// dimensions?
@@ -57,7 +60,7 @@
);
// write netsession header
- node->write_packet_header(pkt, NETCHAN_TERRAIN_ARRAY);
+ netsession.write_packet_header(pkt, NETCHAN_TERRAIN_ARRAY);
// write terrain dimensions
pkt.write_uint32(map.x);
@@ -67,7 +70,7 @@
pkt.write_compressed(terrain_buf, terrain_size);
// send
- node->send_raw(pkt, true);
+ node.send_raw(pkt, true);
}
@@ -88,53 +91,64 @@
/*
* NetworkServerPlayer
*/
-NetworkServerPlayer::NetworkServerPlayer (NetworkServer &server, NetworkNode *node) :
+NetworkServerPlayer::NetworkServerPlayer (NetworkServer &server, NetworkNode &node) :
Player(server.state, Vector(PLAYER_INITIAL_X, PLAYER_INITIAL_Y), true), NetworkServerObject(server), node(node)
{
// messages
- slots.connect(node->sig_disconnected(), this, &NetworkServerPlayer::on_disconnected);
+ slots.connect(node.sig_disconnected(), this, &NetworkServerPlayer::on_disconnected);
slots.connect(this->sig_message(NETMSG_CLIENT_INPUT), this, &NetworkServerPlayer::on_input);
// the initial NETMSG_PLAYER_HELLO
- NetworkPacket hello_pkt;
- hello_pkt.write_vector(getPosition());
+ NetworkMessage hello_msg(*this, NETMSG_SERVER_HELLO);
+ hello_msg.write_vector(getPosition());
+ node.send_raw(hello_msg);
- this->send_to(node, NETMSG_SERVER_HELLO, hello_pkt, true);
-
- // send other player objects
+ // sync other players
for (std::list<NetworkServerPlayer*>::iterator it = server.players.begin(); it != server.players.end(); it++) {
- NetworkPacket player_pkt;
+ NetworkMessage player_msg(*this, NETMSG_PLAYER_INFO);
NetworkServerPlayer *player = *it;
// player is not in players list yet
assert(player != this);
// write packet
- player_pkt.write_vector(player->getPosition());
-
- player->send_to(node, NETMSG_PLAYER_INFO, player_pkt, true);
+ player_msg.write_vector(player->getPosition());
+
+ // send message to client
+ node.send_raw(player_msg);
// XXX: send rope info...
}
- // XXX: send projectiles? Or let the client handle the events that the unknown projectiles generate?
+ // sync projectiles
+ for (std::list<Projectile*>::iterator it = server.state.projectiles.begin(); it != server.state.projectiles.end(); it++) {
+ NetworkServerProjectile *proj = dynamic_cast<NetworkServerProjectile*>(*it);
+
+ // all projectiles should be under the control of the server
+ assert(proj);
+
+ // XXX: send info
+ }
// broadcast NETMSG_PLAYER_JOIN to all clients except current
- this->send_all_except(NETMSG_PLAYER_JOIN, hello_pkt, node, true);
-
- Engine::log(INFO, "net.server") << "Player joined: " << this << " from " << node->getRemoteAddress();
-}
+ NetworkMessage join_msg(*this, NETMSG_PLAYER_JOIN);
+ join_msg.write_vector(getPosition());
+ server.netsession.all_nodes_except(node).send_raw(join_msg);
+ Engine::log(INFO, "net.server") << "Player joined: " << this << " from " << node.getRemoteAddress();
+}
+
void NetworkServerPlayer::handleDig (Vector position, float radius) {
- NetworkPacket pkt;
-
- pkt.write_vector(position);
- pkt.write_float32(radius);
+ NetworkMessage msg(*this, NETMSG_PLAYER_DIG);
Engine::log(DEBUG, "server_player.handle_dig") << "position=" << position << ", radius=" << radius;
+
+ // write packet
+ msg.write_vector(position);
+ msg.write_float32(radius);
- // tell everyone... make this reliable...
- this->send_all(NETMSG_PLAYER_DIG, pkt, true);
+ // broadcast packet
+ server.netsession.all_nodes().send_raw(msg);
// and carry out the actual dig on the server as well
Player::handleDig(position, radius);
@@ -151,94 +165,100 @@
}
void NetworkServerPlayer::handleChangeWeapon (unsigned int weaponIndex) {
- NetworkPacket pkt;
+ NetworkMessage msg(*this, NETMSG_PLAYER_WEAPON_CHANGE);
Engine::log(DEBUG, "server_player.change_weapon") << "weaponIndex=" << weaponIndex;
// write packet
- pkt.write_uint8(weaponIndex);
+ msg.write_uint8(weaponIndex);
// XXX: only tell the client itself?
- send_all(NETMSG_PLAYER_WEAPON_CHANGE, pkt, true);
+ server.netsession.all_nodes().send_raw(msg);
// pass through
Player::handleChangeWeapon(weaponIndex);
}
void NetworkServerPlayer::handleRopeState (RopeState state) {
- NetworkPacket pkt;
-
Engine::log(DEBUG, "server_player.rope_state") << "state=" << rope.getState() << ", position=" << rope.getPosition() << ", velocity=" << rope.getVelocity() << ", length=" << rope.getLength() << ", pivotPlayer=" << rope.getPivotPlayer();
switch (state) {
- case ROPE_FLYING:
- pkt.write_vector(rope.getPosition());
- pkt.write_vector(rope.getVelocity());
- pkt.write_float32(rope.getLength());
+ case ROPE_FLYING: {
+ NetworkMessage msg(*this, NETMSG_PLAYER_ROPE_THROW);
- send_all(NETMSG_PLAYER_ROPE_THROW, pkt, true);
+ msg.write_vector(rope.getPosition());
+ msg.write_vector(rope.getVelocity());
+ msg.write_float32(rope.getLength());
- break;
+ server.netsession.all_nodes().send_raw(msg);
+
+ } break;
case ROPE_FIXED: {
+ NetworkMessage msg(*this, NETMSG_PLAYER_ROPE_FIXED);
+
Player *player_base = rope.getPivotPlayer();
NetworkServerPlayer *player = NULL;
if (player_base != NULL && (player = dynamic_cast<NetworkServerPlayer*>(player_base)) == NULL)
throw Error("NetworkServerPlayer::handleRopeState: rope's pivotPlayer is not a NetworkServerPlayer");
- pkt.write_vector(rope.getPosition());
- pkt.write_float32(rope.getLength());
- controller.write_object(pkt, player); // may be NULL
+ msg.write_vector(rope.getPosition());
+ msg.write_float32(rope.getLength());
+ controller.write_object(msg, player); // may be NULL
- send_all(NETMSG_PLAYER_ROPE_FIXED, pkt, true);
+ server.netsession.all_nodes().send_raw(msg);
- } break;
+ } break;
- case ROPE_FOLDED:
- send_all(NETMSG_PLAYER_ROPE_RELEASED, pkt, true);
+ case ROPE_FOLDED: {
+ NetworkMessage msg(*this, NETMSG_PLAYER_ROPE_RELEASED);
- break;
+ server.netsession.all_nodes().send_raw(msg);
+
+ } break;
}
}
void NetworkServerPlayer::handleRopeLength (float length) {
- NetworkPacket pkt;
-
- pkt.write_float32(length);
-
- send_all(NETMSG_PLAYER_ROPE_LENGTH, pkt, true);
+ NetworkMessage msg(*this, NETMSG_PLAYER_ROPE_LENGTH);
+
+ // write packet
+ msg.write_float32(length);
+
+ // send packet
+ server.netsession.all_nodes().send_raw(msg);
}
void NetworkServerPlayer::spawn (Vector position) {
- NetworkPacket pkt;
+ NetworkMessage msg(*this, NETMSG_PLAYER_SPAWN);
// write packet
- pkt.write_vector(position);
+ msg.write_vector(position);
Engine::log(DEBUG, "server_player.spawn") << this << ": position=" << position;
- // send
- send_all(NETMSG_PLAYER_SPAWN, pkt, true);
+ // send packet
+ server.netsession.all_nodes().send_raw(msg);
// super
Player::spawn(position);
}
void NetworkServerPlayer::die (bool start_timer) {
- NetworkPacket pkt;
+ NetworkMessage msg(*this, NETMSG_PLAYER_DIE);
Engine::log(DEBUG, "server_player.die") << this;
- // send
- send_all(NETMSG_PLAYER_DIE, pkt, true);
+ // send packet
+ server.netsession.all_nodes().send_raw(msg);
// super
Player::die(start_timer);
}
void NetworkServerPlayer::on_disconnected (void) {
- NetworkPacket pkt;
+ NetworkMessage msg(*this, NETMSG_PLAYER_QUIT);
Engine::log(INFO, "net.server") << "Player disconnected: " << this;
@@ -246,16 +266,16 @@
server.handle_disconnect(this);
// tell other clients
- send_all(NETMSG_PLAYER_QUIT, pkt, true);
+ server.netsession.all_nodes().send_raw(msg);
- // free
+ // XXX: free
// delete this;
}
void NetworkServerPlayer::on_input (NetworkNode *src, NetworkPacketInput &pkt) {
// sanity-check, other players shouldn't move
- if (src != node) {
- Engine::log(WARN, "server_player.on_input") << "packet from wrong src=" << src << ", node=" << node;
+ if (src != &node) {
+ Engine::log(WARN, "server_player.on_input") << "packet from wrong src=" << src << ", node=" << &node;
return;
}
@@ -273,20 +293,20 @@
}
void NetworkServerPlayer::send_position_update (void) {
- NetworkPacket pkt;
+ NetworkMessage msg(*this, NETMSG_PLAYER_POSITION);
int flags =
(inAir ? NETWORK_PHYSICS_INAIR : 0) |
(facing == FACING_RIGHT ? NETWORK_PHYSICS_FACE_RIGHT : 0);
- pkt.write_vector(getPosition());
- pkt.write_vector(getVelocity());
- pkt.write_uint8(flags);
- pkt.write_float32(aim);
+ msg.write_vector(getPosition());
+ msg.write_vector(getVelocity());
+ msg.write_uint8(flags);
+ msg.write_float32(aim);
// Engine::log(INFO, "server_player.send_position_update") << "obj=" << obj << " -> " << position << "+" << velocity << " [" << flags << "]";
- send_all(NETMSG_PLAYER_POSITION, pkt, false);
+ server.netsession.all_nodes().send_raw(msg);
}
/*
@@ -296,25 +316,29 @@
Vector velocity, Weapon *weapon) :
Projectile(player, position, velocity, weapon, true), NetworkServerObject(server)
{
- NetworkPacket pkt;
+ NetworkMessage msg(*this, NETMSG_PROJECTILE_PLAYER_FIRED);
+
+ // write out packet
+ server.controller.write_object(msg, player);
+ msg.write_vector(getPosition());
+ msg.write_vector(getVelocity());
+ msg.write_uint8(weapon->getID());
- server.controller.write_object(pkt, player);
- pkt.write_vector(position);
- pkt.write_vector(velocity);
- pkt.write_uint8(weapon->getID());
-
- send_all(NETMSG_PROJECTILE_PLAYER_FIRED, pkt, true);
+ // send to given target
+ server.netsession.all_nodes().send_raw(msg);
}
void NetworkServerProjectile::onDestroy (Vector position, bool removeGround) {
- NetworkPacket pkt;
+ NetworkMessage msg(*this, NETMSG_PROJECTILE_DESTROY);
Engine::log(DEBUG, "server_projectile.destroy") << this << "position=" << position << ", removeGround=" << removeGround;
- pkt.write_vector(position);
- pkt.write_uint8(removeGround ? NETWORK_PROJECTILE_REMOVE_GROUND : 0);
-
- send_all(NETMSG_PROJECTILE_DESTROY, pkt, true);
+ // write packet
+ msg.write_vector(position);
+ msg.write_uint8(removeGround ? NETWORK_PROJECTILE_REMOVE_GROUND : 0);
+
+ // broadcast packet
+ server.netsession.all_nodes().send_raw(msg);
// XXX: leak obj, not yet implemented: obj.destory();
@@ -323,7 +347,7 @@
}
void NetworkServerProjectile::onHitPlayer (Player *player_ptr) {
- NetworkPacket pkt;
+ NetworkMessage msg(*this, NETMSG_PROJECTILE_HIT_PLAYER);
NetworkServerPlayer *player = dynamic_cast<NetworkServerPlayer*>(player_ptr);
if (player == NULL)
@@ -332,10 +356,10 @@
Engine::log(DEBUG, "server_projectile.hit_player") << this << ": player=" << player;
// write packet
- controller.write_object(pkt, player);
+ controller.write_object(msg, player);
- // send
- send_all(NETMSG_PROJECTILE_HIT_PLAYER, pkt, true);
+ // send packet
+ server.netsession.all_nodes().send_raw(msg);
// super
Projectile::onHitPlayer(player_ptr);