4 #include "Config.hh" |
4 #include "Config.hh" |
5 #include "../Engine.hh" |
5 #include "../Engine.hh" |
6 #include "../Logger.hh" |
6 #include "../Logger.hh" |
7 |
7 |
8 #include <cassert> |
8 #include <cassert> |
|
9 #include <zlib.h> |
9 |
10 |
10 NetworkServer::NetworkServer (GameState &state, const NetworkEndpoint &listen_addr) : |
11 NetworkServer::NetworkServer (GameState &state, const NetworkEndpoint &listen_addr) : |
11 state(state), netsession(NETWORK_MAGIC_ID), controller(netsession, NETCHAN_CORE) { |
12 state(state), netsession(NETWORK_MAGIC_ID), controller(netsession, NETCHAN_CORE) { |
12 |
13 |
13 // connect slots |
14 // connect slots |
233 } |
234 } |
234 |
235 |
235 void NetworkServerPlayer::send_terrain_data (void) { |
236 void NetworkServerPlayer::send_terrain_data (void) { |
236 Terrain &terrain = server.state.world; |
237 Terrain &terrain = server.state.world; |
237 |
238 |
238 // XXX: over 2**31? |
239 // dimensions? |
239 PixelDimension map_w = terrain.terrain.size(); |
240 PixelCoordinate map = terrain.getDimensions(); |
240 PixelDimension map_h = terrain.terrain[0].size(); |
241 |
241 |
242 // translate to a byte array |
|
243 size_t terrain_size = map.x * map.y; |
|
244 uint8_t terrain_buf[map.x][map.y]; |
|
245 |
|
246 // copy over from terrain vector |
|
247 for (PixelDimension x = 0; x < map.x; x++) { |
|
248 for (PixelDimension y = 0; y < map.y; y++) { |
|
249 terrain_buf[x][y] = (uint8_t) terrain.terrain[x][y]; |
|
250 } |
|
251 } |
|
252 |
|
253 // compress the terrain buffer |
|
254 unsigned long deflate_size = compressBound(terrain_size); |
|
255 uint8_t deflate_buf[deflate_size]; |
|
256 |
|
257 // and compress |
|
258 if (compress(deflate_buf, &deflate_size, (const uint8_t *) terrain_buf, terrain_size) != Z_OK) |
|
259 throw Error("compress failed"); |
|
260 |
242 // allocate our packet... |
261 // allocate our packet... |
243 BigNetworkPacket pkt (NETWORK_SESSION_HEADER_SIZE + 2 * sizeof(uint32_t) + map_w * map_h); |
262 BigNetworkPacket pkt ( |
|
263 NETWORK_SESSION_HEADER_SIZE // NetworkChannel header |
|
264 + 3 * sizeof(uint32_t) // our own header |
|
265 + deflate_size // compressed terrain buffer |
|
266 ); |
244 |
267 |
245 // write netsession header |
268 // write netsession header |
246 node->write_packet_header(pkt, NETCHAN_TERRAIN_ARRAY); |
269 node->write_packet_header(pkt, NETCHAN_TERRAIN_ARRAY); |
247 |
270 |
248 // write terrain dimensions |
271 // write terrain dimensions |
249 pkt.write_uint32(map_w); |
272 pkt.write_uint32(map.x); |
250 pkt.write_uint32(map_h); |
273 pkt.write_uint32(map.y); |
251 |
274 |
252 // write out terrain data |
275 // write compressed data |
253 for (PixelDimension x = 0; x < map_w; x++) { |
276 pkt.write(deflate_buf, deflate_size); |
254 for (PixelDimension y = 0; y < map_h; y++) { |
|
255 pkt.write_uint8((uint8_t) terrain.terrain[x][y]); |
|
256 } |
|
257 } |
|
258 |
277 |
259 // send |
278 // send |
260 node->send_raw(pkt, true); |
279 node->send_raw(pkt, true); |
261 } |
280 } |
262 |
281 |