+ ptr[0] = (value >> 24) & 0xff;
+ ptr[1] = (value >> 16) & 0xff;
+ ptr[2] = (value >> 8) & 0xff;
+ ptr[3] = (value >> 0) & 0xff;
+
+ return 4;
+}
+
+char *getNetworkString(byte *ptr)
+{
+ return (char *)ptr;
+}
+
+int putNetworkString(byte *ptr, char *s)
+{
+ strcpy((char *)ptr, s);
+
+ return strlen(s) + 1;
+}
+
+struct NetworkBuffer *newNetworkBuffer(void)
+{
+ struct NetworkBuffer *new = checked_calloc(sizeof(struct NetworkBuffer));
+
+ new->max_size = MAX_BUFFER_SIZE;
+ new->size = 0;
+ new->pos = 0;
+
+ new->buffer = checked_calloc(new->max_size);
+
+ return new;
+}
+
+static void resetNetworkBufferForReading(struct NetworkBuffer *nb)
+{
+ nb->pos = 0;
+}
+
+static void resetNetworkBufferForWriting(struct NetworkBuffer *nb)
+{
+ nb->size = 0;
+ nb->pos = 0;
+}
+
+void initNetworkBufferForReceiving(struct NetworkBuffer *nb)
+{
+ resetNetworkBufferForWriting(nb);
+}
+
+void initNetworkBufferForReading(struct NetworkBuffer *nb)
+{
+ resetNetworkBufferForReading(nb);
+
+ // skip message length header
+ getNetworkBuffer32BitInteger(nb);
+}
+
+void initNetworkBufferForWriting(struct NetworkBuffer *nb, int message_type,
+ int player_nr)
+{
+ resetNetworkBufferForWriting(nb);
+
+ // will be replaced with message length before sending
+ putNetworkBuffer32BitInteger(nb, 0);
+
+ putNetworkBuffer8BitInteger(nb, message_type);
+ putNetworkBuffer8BitInteger(nb, player_nr);
+}
+
+static void copyNetworkBufferForWriting(struct NetworkBuffer *nb_from,
+ struct NetworkBuffer *nb_to,
+ int player_nr)
+{
+ initNetworkBufferForReading(nb_from);
+
+ int message_type = getNetworkBuffer8BitInteger(nb_from);
+
+ // skip player number
+ getNetworkBuffer8BitInteger(nb_from);
+
+ initNetworkBufferForWriting(nb_to, message_type, player_nr);
+
+ while (nb_from->pos < nb_from->size)
+ {
+ int b = getNetworkBuffer8BitInteger(nb_from);
+
+ putNetworkBuffer8BitInteger(nb_to, b);
+ }
+}
+
+static void increaseNetworkBuffer(struct NetworkBuffer *nb, int additional_size)
+{
+ // add some more buffer size than is really required this time
+ nb->max_size += additional_size + MAX_BUFFER_SIZE;
+ nb->buffer = checked_realloc(nb->buffer, nb->max_size);
+}
+
+int receiveNetworkBufferBytes(struct NetworkBuffer *nb, TCPsocket socket,
+ int num_bytes)
+{
+ if (num_bytes > MAX_PACKET_SIZE)
+ {
+ Debug("network:server", "protocol error: invalid packet size %d",
+ num_bytes);
+
+ return -1;
+ }
+
+ if (nb->pos + num_bytes > nb->max_size)
+ increaseNetworkBuffer(nb, num_bytes);
+
+ int result = SDLNet_TCP_Recv(socket, &nb->buffer[nb->pos], num_bytes);
+
+ if (result != num_bytes)
+ return result;
+
+ nb->pos += num_bytes;
+ nb->size = nb->pos;
+
+ return num_bytes;
+}
+
+int receiveNetworkBufferPacket(struct NetworkBuffer *nb, TCPsocket socket)
+{
+ int num_bytes, num_bytes_head, num_bytes_body;
+
+ num_bytes_head = 4;
+ num_bytes = receiveNetworkBufferBytes(nb, socket, num_bytes_head);
+
+ if (num_bytes != num_bytes_head)
+ return num_bytes;
+
+ num_bytes_body = getNetwork32BitInteger(nb->buffer);
+ num_bytes = receiveNetworkBufferBytes(nb, socket, num_bytes_body);
+
+ return num_bytes;
+}
+
+int getNetworkBuffer8BitInteger(struct NetworkBuffer *nb)
+{
+ int num_bytes = 1;
+
+ if (nb->pos + num_bytes > nb->size)
+ return 0;
+
+ int value = getNetwork8BitInteger(&nb->buffer[nb->pos]);
+
+ nb->pos += num_bytes;
+
+ return value;
+}
+
+void putNetworkBuffer8BitInteger(struct NetworkBuffer *nb, int value)
+{
+ int num_bytes = 1;
+
+ if (nb->pos + num_bytes > nb->max_size)
+ increaseNetworkBuffer(nb, num_bytes);
+
+ nb->pos += putNetwork8BitInteger(&nb->buffer[nb->pos], value);
+ nb->size = nb->pos;
+}
+
+int getNetworkBuffer16BitInteger(struct NetworkBuffer *nb)
+{
+ int num_bytes = 2;
+
+ if (nb->pos + num_bytes > nb->size)
+ return 0;
+
+ int value = getNetwork16BitInteger(&nb->buffer[nb->pos]);
+
+ nb->pos += num_bytes;
+
+ return value;
+}
+
+void putNetworkBuffer16BitInteger(struct NetworkBuffer *nb, int value)
+{
+ int num_bytes = 2;
+
+ if (nb->pos + num_bytes > nb->max_size)
+ increaseNetworkBuffer(nb, num_bytes);
+
+ nb->pos += putNetwork16BitInteger(&nb->buffer[nb->pos], value);
+ nb->size = nb->pos;
+}
+
+int getNetworkBuffer32BitInteger(struct NetworkBuffer *nb)
+{
+ int num_bytes = 4;
+
+ if (nb->pos + num_bytes > nb->size)
+ return 0;
+
+ int value = getNetwork32BitInteger(&nb->buffer[nb->pos]);
+
+ nb->pos += num_bytes;
+
+ return value;
+}
+
+void putNetworkBuffer32BitInteger(struct NetworkBuffer *nb, int value)
+{
+ int num_bytes = 4;
+
+ if (nb->pos + num_bytes > nb->max_size)
+ increaseNetworkBuffer(nb, num_bytes);
+
+ nb->pos += putNetwork32BitInteger(&nb->buffer[nb->pos], value);
+ nb->size = nb->pos;
+}
+
+char *getNetworkBufferString(struct NetworkBuffer *nb)
+{
+ char *s = getNetworkString(&nb->buffer[nb->pos]);
+
+ nb->pos += strlen(s) + 1;
+
+ return s;
+}
+
+void putNetworkBufferString(struct NetworkBuffer *nb, char *s)
+{
+ int num_bytes = strlen(s) + 1;
+
+ if (nb->pos + num_bytes > nb->max_size)
+ increaseNetworkBuffer(nb, num_bytes);
+
+ nb->pos += putNetworkString(&nb->buffer[nb->pos], s);
+ nb->size = nb->pos;
+}
+
+int getNetworkBufferFile(struct NetworkBuffer *nb, char *filename)
+{
+ FILE *file;
+ int num_bytes = getNetworkBuffer32BitInteger(nb);
+ int i;
+
+ if (!(file = fopen(filename, MODE_WRITE)))
+ {
+ Warn("cannot write file '%s' from network buffer", filename);
+
+ return 0;
+ }
+
+ for (i = 0; i < num_bytes; i++)
+ {
+ int b = getNetworkBuffer8BitInteger(nb);
+
+ putFile8Bit(file, b);
+ }
+
+ fclose(file);
+
+ return num_bytes;
+}
+
+int putNetworkBufferFile(struct NetworkBuffer *nb, char *filename)
+{
+ File *file;
+ int filesize_pos = nb->pos;
+ int num_bytes = 0;
+
+ // will be replaced with file size
+ putNetworkBuffer32BitInteger(nb, 0);
+
+ if (!(file = openFile(filename, MODE_READ)))
+ {
+ Warn("cannot read file '%s' to network buffer", filename);
+
+ return 0;
+ }
+
+ while (1)
+ {
+ int b = getFile8Bit(file);