10017
+ − 1
/*
+ − 2
* Hedgewars, a free turn based strategy game
+ − 3
* Copyright (C) 2012 Simeon Maxein <smaxein@googlemail.com>
+ − 4
*
+ − 5
* This program is free software; you can redistribute it and/or
+ − 6
* modify it under the terms of the GNU General Public License
+ − 7
* as published by the Free Software Foundation; either version 2
+ − 8
* of the License, or (at your option) any later version.
+ − 9
*
+ − 10
* This program is distributed in the hope that it will be useful,
+ − 11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
+ − 12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ − 13
* GNU General Public License for more details.
+ − 14
*
+ − 15
* You should have received a copy of the GNU General Public License
+ − 16
* along with this program; if not, write to the Free Software
+ − 17
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ − 18
*/
+ − 19
+ − 20
#include "netprotocol.h"
+ − 21
+ − 22
#include "../util/util.h"
+ − 23
#include "../util/logging.h"
+ − 24
+ − 25
#include "../base64/base64.h"
+ − 26
+ − 27
#include <zlib.h>
+ − 28
+ − 29
#include <string.h>
+ − 30
#include <stdio.h>
+ − 31
#include <errno.h>
+ − 32
#include <stdlib.h>
+ − 33
+ − 34
static int fillTeamFromMsg(flib_team *team, char **parts) {
+ − 35
team->name = flib_strdupnull(parts[0]);
+ − 36
team->grave = flib_strdupnull(parts[1]);
+ − 37
team->fort = flib_strdupnull(parts[2]);
+ − 38
team->voicepack = flib_strdupnull(parts[3]);
+ − 39
team->flag = flib_strdupnull(parts[4]);
+ − 40
team->ownerName = flib_strdupnull(parts[5]);
+ − 41
if(!team->name || !team->grave || !team->fort || !team->voicepack || !team->flag || !team->ownerName) {
+ − 42
return -1;
+ − 43
}
+ − 44
+ − 45
errno = 0;
+ − 46
long difficulty = strtol(parts[6], NULL, 10);
+ − 47
if(errno) {
+ − 48
return -1;
+ − 49
}
+ − 50
+ − 51
for(int i=0; i<HEDGEHOGS_PER_TEAM; i++) {
+ − 52
flib_hog *hog = &team->hogs[i];
+ − 53
hog->difficulty = difficulty;
+ − 54
hog->name = flib_strdupnull(parts[7+2*i]);
+ − 55
hog->hat = flib_strdupnull(parts[8+2*i]);
+ − 56
if(!hog->name || !hog->hat) {
+ − 57
return -1;
+ − 58
}
+ − 59
}
+ − 60
+ − 61
// Set some default assumptions as well
+ − 62
team->colorIndex = DEFAULT_COLOR_INDEX;
+ − 63
team->hogsInGame = DEFAULT_HEDGEHOG_COUNT;
+ − 64
team->remoteDriven = true;
+ − 65
return 0;
+ − 66
}
+ − 67
+ − 68
flib_team *flib_team_from_netmsg(char **parts) {
+ − 69
flib_team *result = NULL;
+ − 70
flib_team *tmpTeam = flib_calloc(1, sizeof(flib_team));
+ − 71
if(tmpTeam) {
+ − 72
if(!fillTeamFromMsg(tmpTeam, parts)) {
+ − 73
result = tmpTeam;
+ − 74
tmpTeam = NULL;
+ − 75
} else {
+ − 76
flib_log_e("Error parsing team from net.");
+ − 77
}
+ − 78
}
+ − 79
flib_team_destroy(tmpTeam);
+ − 80
return result;
+ − 81
}
+ − 82
+ − 83
flib_scheme *flib_scheme_from_netmsg(char **parts) {
+ − 84
flib_scheme *result = flib_scheme_create(parts[0]);
+ − 85
if(result) {
+ − 86
for(int i=0; i<flib_meta.modCount; i++) {
+ − 87
result->mods[i] = !strcmp(parts[i+1], "true");
+ − 88
}
+ − 89
for(int i=0; i<flib_meta.settingCount; i++) {
+ − 90
result->settings[i] = atoi(parts[i+flib_meta.modCount+1]);
+ − 91
}
+ − 92
}
+ − 93
return result;
+ − 94
}
+ − 95
+ − 96
flib_map *flib_map_from_netmsg(char **parts) {
+ − 97
flib_map *result = flib_map_create_named(parts[3], parts[0]);
+ − 98
if(result) {
+ − 99
result->mapgen = atoi(parts[1]);
+ − 100
result->mazeSize = atoi(parts[2]);
+ − 101
result->templateFilter = atoi(parts[4]);
+ − 102
}
+ − 103
return result;
+ − 104
}
+ − 105
+ − 106
int flib_drawnmapdata_from_netmsg(char *netmsg, uint8_t** outbuf, size_t *outlen) {
+ − 107
int result = -1;
+ − 108
+ − 109
// First step: base64 decoding
+ − 110
char *base64decout = NULL;
+ − 111
size_t base64declen;
+ − 112
bool ok = base64_decode_alloc(netmsg, strlen(netmsg), &base64decout, &base64declen);
+ − 113
if(ok && base64declen>3) {
+ − 114
// Second step: unzip with the QCompress header. That header is just a big-endian
+ − 115
// uint32 indicating the length of the uncompressed data.
+ − 116
uint8_t *ubyteBuf = (uint8_t*)base64decout;
+ − 117
uint32_t unzipLen =
+ − 118
(((uint32_t)ubyteBuf[0])<<24)
+ − 119
+ (((uint32_t)ubyteBuf[1])<<16)
+ − 120
+ (((uint32_t)ubyteBuf[2])<<8)
+ − 121
+ ubyteBuf[3];
+ − 122
if(unzipLen==0) {
+ − 123
*outbuf = NULL;
+ − 124
*outlen = 0;
+ − 125
result = 0;
+ − 126
} else {
+ − 127
uint8_t *out = flib_malloc(unzipLen);
+ − 128
if(out) {
+ − 129
uLongf actualUnzipLen = unzipLen;
+ − 130
int resultcode = uncompress(out, &actualUnzipLen, (Bytef*)(base64decout+4), base64declen-4);
+ − 131
if(resultcode == Z_OK) {
+ − 132
*outbuf = out;
+ − 133
*outlen = actualUnzipLen;
+ − 134
out = NULL;
+ − 135
result = 0;
+ − 136
} else {
+ − 137
flib_log_e("Uncompressing drawn map failed. Code: %i", resultcode);
+ − 138
}
+ − 139
}
+ − 140
free(out);
+ − 141
}
+ − 142
} else {
+ − 143
flib_log_e("base64 decoding of drawn map failed.");
+ − 144
}
+ − 145
free(base64decout);
+ − 146
return result;
+ − 147
}
+ − 148
+ − 149
flib_room *flib_room_from_netmsg(char **params) {
+ − 150
flib_room *result = NULL;
+ − 151
flib_room *tmpRoom = flib_calloc(1, sizeof(flib_room));
+ − 152
if(tmpRoom) {
+ − 153
tmpRoom->inProgress = !strcmp(params[0], "True");
+ − 154
tmpRoom->name = flib_strdupnull(params[1]);
+ − 155
tmpRoom->playerCount = atoi(params[2]);
+ − 156
tmpRoom->teamCount = atoi(params[3]);
+ − 157
tmpRoom->owner = flib_strdupnull(params[4]);
+ − 158
tmpRoom->map = flib_strdupnull(params[5]);
+ − 159
tmpRoom->scheme = flib_strdupnull(params[6]);
+ − 160
tmpRoom->weapons = flib_strdupnull(params[7]);
+ − 161
if(tmpRoom->name && tmpRoom->owner && tmpRoom->map && tmpRoom->scheme && tmpRoom->weapons) {
+ − 162
result = tmpRoom;
+ − 163
tmpRoom = NULL;
+ − 164
}
+ − 165
}
+ − 166
flib_room_destroy(tmpRoom);
+ − 167
return result;
+ − 168
}
+ − 169
+ − 170
int fillRoomArray(flib_room **array, char **params, int count) {
+ − 171
for(int i=0; i<count; i++) {
+ − 172
array[i] = flib_room_from_netmsg(params + 8*i);
+ − 173
if(!array[i]) {
+ − 174
return -1;
+ − 175
}
+ − 176
}
+ − 177
return 0;
+ − 178
}
+ − 179
+ − 180
flib_room **flib_room_array_from_netmsg(char **params, int count) {
+ − 181
flib_room **result = flib_calloc(count, sizeof(flib_room*));
+ − 182
if(result) {
+ − 183
if(fillRoomArray(result, params, count)) {
+ − 184
for(int i=0; i<count; i++) {
+ − 185
flib_room_destroy(result[i]);
+ − 186
}
+ − 187
free(result);
+ − 188
result = NULL;
+ − 189
}
+ − 190
}
+ − 191
return result;
+ − 192
}