send initial terrain data to clients using a new NETCHAN_TERRAIN_ARRAY channel using raw BigNetworkPacket
--- a/src/Network/Client.cc Thu Dec 04 22:14:45 2008 +0000
+++ b/src/Network/Client.cc Thu Dec 04 22:33:43 2008 +0000
@@ -12,6 +12,7 @@
// connect slots
slots.connect(netobjs.sig_create(), this, &NetworkClient::on_create);
+ slots.connect(netsession.sig_chan_message(NETCHAN_TERRAIN_ARRAY), this, &NetworkClient::on_terrain_array);
// XXX: sig_disconnected
}
@@ -78,6 +79,28 @@
state.newRemotePlayer(player);
}
+void NetworkClient::on_terrain_array (NetworkPacketInput &pkt, NetworkNode *node) {
+ // ignore if not from server
+ if (node != server)
+ return;
+
+ Terrain &terrain = state.world;
+
+ // read map width/height
+ uint32_t map_w = pkt.read_uint32();
+ uint32_t map_h = pkt.read_uint32();
+
+ // read map data
+ for (int x = 0; x < map_w; x++) {
+ for (int y = 0; y < map_h; y++) {
+ terrain.terrain[x][y] = (TerrainType) pkt.read_uint8();
+ }
+ }
+
+ // update the pixbuf
+ terrain.generatePixelBuffer();
+}
+
void NetworkClient::player_quit (NetworkClientRemotePlayer *player) {
// inform state
state.removePlayer(player);
--- a/src/Network/Client.hh Thu Dec 04 22:14:45 2008 +0000
+++ b/src/Network/Client.hh Thu Dec 04 22:33:43 2008 +0000
@@ -31,6 +31,8 @@
void on_server_hello (NetworkObject_Client *obj, NetworkPacketInput &pkt);
void on_player_info (NetworkObject_Client *obj, NetworkPacketInput &pkt);
void on_player_join (NetworkObject_Client *obj, NetworkPacketInput &pkt);
+
+ void on_terrain_array (NetworkPacketInput &pkt, NetworkNode *node);
public:
void player_quit (NetworkClientRemotePlayer *player);
--- a/src/Network/Packet.hh Thu Dec 04 22:14:45 2008 +0000
+++ b/src/Network/Packet.hh Thu Dec 04 22:33:43 2008 +0000
@@ -153,7 +153,7 @@
BigNetworkPacket (const BigNetworkPacket &pkt);
BigNetworkPacket& operator= (const BigNetworkPacket &pkt);
- protected:
+ public:
virtual ~BigNetworkPacket (void);
};
--- a/src/Network/Protocol.hh Thu Dec 04 22:14:45 2008 +0000
+++ b/src/Network/Protocol.hh Thu Dec 04 22:33:43 2008 +0000
@@ -9,7 +9,16 @@
/*
* Core channel used for NetworkSession
*/
- NETCHAN_CORE = 0x01,
+ NETCHAN_CORE = 0x0001,
+
+ /*
+ * Channel used to send initial terrain array
+ *
+ * uint32_t map_w
+ * uint32_t map_h
+ * uint8_t[map_w][map_h] terrain
+ */
+ NETCHAN_TERRAIN_ARRAY = 0x0010,
};
enum NetworkPhysicsFlags {
--- a/src/Network/Server.cc Thu Dec 04 22:14:45 2008 +0000
+++ b/src/Network/Server.cc Thu Dec 04 22:33:43 2008 +0000
@@ -69,6 +69,9 @@
// broadcast NETMSG_PLAYER_JOIN to all clients except current
obj.send_all_except(NETMSG_PLAYER_JOIN, hello_pkt, node, true);
+
+ // send terrain data...
+ send_terrain_data();
}
void NetworkServerPlayer::handleDig (Vector position, float radius) {
@@ -119,6 +122,33 @@
send_position_update();
}
+void NetworkServerPlayer::send_terrain_data (void) {
+ Terrain &terrain = server.state.world;
+
+ uint32_t map_w = terrain.terrain.size();
+ uint32_t map_h = terrain.terrain[0].size();
+
+ // allocate our packet...
+ BigNetworkPacket pkt (NETWORK_SESSION_HEADER_SIZE + 2 * sizeof(uint32_t) + map_w * map_h);
+
+ // write netsession header
+ node->write_packet_header(pkt, NETCHAN_TERRAIN_ARRAY);
+
+ // write terrain dimensions
+ pkt.write_uint32(map_w);
+ pkt.write_uint32(map_h);
+
+ // write out terrain data
+ for (int x = 0; x < map_w; x++) {
+ for (int y = 0; y < map_h; y++) {
+ pkt.write_uint8((uint8_t) terrain.terrain[x][y]);
+ }
+ }
+
+ // send
+ node->send_raw(pkt, true);
+}
+
void NetworkServerPlayer::send_position_update (void) {
NetworkPacket pkt;
--- a/src/Network/Server.hh Thu Dec 04 22:14:45 2008 +0000
+++ b/src/Network/Server.hh Thu Dec 04 22:33:43 2008 +0000
@@ -49,7 +49,8 @@
private:
void on_disconnected (void);
void on_move (NetworkNode *node, NetworkPacketInput &pkt);
-
+
+ void send_terrain_data (void);
void send_position_update (void);
};
--- a/src/Network/Session.hh Thu Dec 04 22:14:45 2008 +0000
+++ b/src/Network/Session.hh Thu Dec 04 22:33:43 2008 +0000
@@ -12,6 +12,11 @@
*/
typedef uint16_t NetworkChannelID;
+/*
+ * Size of a packet header
+ */
+const size_t NETWORK_SESSION_HEADER_SIZE = sizeof(uint16_t);
+
#include "TCP.hh"
#include "UDP.hh"
#include "Node.hh"
--- a/src/Network/TCP.cc Thu Dec 04 22:14:45 2008 +0000
+++ b/src/Network/TCP.cc Thu Dec 04 22:33:43 2008 +0000
@@ -16,11 +16,11 @@
void NetworkTCPTransport::on_read (void) {
- uint16_t length;
+ uint32_t length;
char *buf_ptr;
// let the in stream read length-prefixed packets and pass them on to handle_packet
- while (in.peek_data<uint16_t>(length, buf_ptr)) {
+ while (in.peek_data<uint32_t>(length, buf_ptr)) {
// allocate the NetworkPacketBuffer with the given buf_ptr/length
NetworkPacketBuffer packet(buf_ptr, length, length);
@@ -28,7 +28,7 @@
_sig_packet(packet);
// flush it
- in.flush_data<uint16_t>();
+ in.flush_data<uint32_t>();
}
}
@@ -43,7 +43,7 @@
}
void NetworkTCPTransport::write_packet (const NetworkPacketBuffer &packet) {
- uint16_t prefix = packet.get_data_size();
+ uint32_t prefix = packet.get_data_size();
if (prefix != packet.get_data_size())
throw CL_Error("send prefix overflow");
--- a/src/Terrain.hh Thu Dec 04 22:14:45 2008 +0000
+++ b/src/Terrain.hh Thu Dec 04 22:33:43 2008 +0000
@@ -30,18 +30,19 @@
* and it uses pixelcoordinates internally.
*/
class Terrain {
-private:
+ public: // XXX: until we fix Network's access to this
std::vector<std::vector<TerrainType> > terrain;
- // Terrain graphic
- CL_PixelBuffer pixbuf;
-
/**
* Generates pixelbuffer from terrain. Should be used only on
* constructors because this is expected to be slow.
*/
void generatePixelBuffer();
+private:
+ // Terrain graphic
+ CL_PixelBuffer pixbuf;
+
/**
* Get pixel location of a point that is in "real" units.
*