project_files/frontlib/net/netprotocol.c
changeset 7271 5608ac657362
parent 7269 5b0aeef8ba2a
child 7275 15f722e0b96f
equal deleted inserted replaced
7269:5b0aeef8ba2a 7271:5608ac657362
     1 #include "netprotocol.h"
     1 #include "netprotocol.h"
     2 
     2 
     3 #include "../util/util.h"
     3 #include "../util/util.h"
     4 #include "../util/logging.h"
     4 #include "../util/logging.h"
       
     5 
       
     6 #include "../base64/base64.h"
       
     7 
       
     8 #include <zlib.h>
     5 
     9 
     6 #include <string.h>
    10 #include <string.h>
     7 #include <stdio.h>
    11 #include <stdio.h>
     8 #include <errno.h>
    12 #include <errno.h>
     9 #include <stdlib.h>
    13 #include <stdlib.h>
    10 
    14 
    11 static int fillTeamFromMsg(flib_team *team, char **parts) {
    15 static int fillTeamFromMsg(flib_team *team, char **parts) {
    12 	team->name = flib_strdupnull(parts[0]);
    16 	team->name = flib_strdupnull(parts[0]);
    13 	team->grave = flib_strdupnull(parts[2]);
    17 	team->grave = flib_strdupnull(parts[1]);
    14 	team->fort = flib_strdupnull(parts[3]);
    18 	team->fort = flib_strdupnull(parts[2]);
    15 	team->voicepack = flib_strdupnull(parts[4]);
    19 	team->voicepack = flib_strdupnull(parts[3]);
    16 	team->flag = flib_strdupnull(parts[5]);
    20 	team->flag = flib_strdupnull(parts[4]);
    17 	if(!team->name || !team->grave || !team->fort || !team->voicepack || !team->flag) {
    21 	team->ownerName = flib_strdupnull(parts[5]);
    18 		return -1;
    22 	if(!team->name || !team->grave || !team->fort || !team->voicepack || !team->flag || !team->ownerName) {
    19 	}
       
    20 
       
    21 	long color;
       
    22 	if(sscanf(parts[1], "#%lx", &color)) {
       
    23 		team->color = color;
       
    24 	} else {
       
    25 		return -1;
    23 		return -1;
    26 	}
    24 	}
    27 
    25 
    28 	errno = 0;
    26 	errno = 0;
    29 	long difficulty = strtol(parts[6], NULL, 10);
    27 	long difficulty = strtol(parts[6], NULL, 10);
    43 	return 0;
    41 	return 0;
    44 }
    42 }
    45 
    43 
    46 flib_team *flib_team_from_netmsg(char **parts) {
    44 flib_team *flib_team_from_netmsg(char **parts) {
    47 	flib_team *result = NULL;
    45 	flib_team *result = NULL;
    48 	flib_team *tmpTeam = flib_calloc(1, sizeof(flib_team));
    46 	flib_team *tmpTeam = flib_team_retain(flib_calloc(1, sizeof(flib_team)));
    49 	if(tmpTeam) {
    47 	if(tmpTeam) {
    50 		if(!fillTeamFromMsg(tmpTeam, parts)) {
    48 		if(!fillTeamFromMsg(tmpTeam, parts)) {
    51 			result = tmpTeam;
    49 			result = tmpTeam;
    52 			tmpTeam = NULL;
    50 			tmpTeam = NULL;
    53 		} else {
    51 		} else {
    54 			flib_log_e("Error parsing team from net.");
    52 			flib_log_e("Error parsing team from net.");
    55 		}
    53 		}
    56 	}
    54 	}
    57 	flib_team_destroy(tmpTeam);
    55 	flib_team_release(tmpTeam);
    58 	return result;
    56 	return result;
    59 }
    57 }
       
    58 
       
    59 flib_cfg *flib_netmsg_to_cfg(flib_cfg_meta *meta, char **parts) {
       
    60 	flib_cfg *result = flib_cfg_create(meta, parts[0]);
       
    61 	if(result) {
       
    62 		for(int i=0; i<meta->modCount; i++) {
       
    63 			result->mods[i] = !strcmp(parts[i+1], "true");
       
    64 		}
       
    65 		for(int i=0; i<meta->settingCount; i++) {
       
    66 			result->settings[i] = atoi(parts[i+meta->modCount+1]);
       
    67 		}
       
    68 	}
       
    69 	return result;
       
    70 }
       
    71 
       
    72 flib_map *flib_netmsg_to_map(char **parts) {
       
    73 	flib_map *result = flib_map_create_named(parts[3], parts[0]);
       
    74 	if(result) {
       
    75 		result->mapgen = atoi(parts[1]);
       
    76 		result->mazeSize = atoi(parts[2]);
       
    77 		result->templateFilter = atoi(parts[4]);
       
    78 	}
       
    79 	return result;
       
    80 }
       
    81 
       
    82 // TODO: Test with empty map
       
    83 uint8_t *flib_netmsg_to_drawnmapdata(size_t *outlen, char *netmsg) {
       
    84 	uint8_t *result = NULL;
       
    85 
       
    86 	// First step: base64 decoding
       
    87 	char *base64decout = NULL;
       
    88 	size_t base64declen;
       
    89 	bool ok = base64_decode_alloc(netmsg, strlen(netmsg), &base64decout, &base64declen);
       
    90 	if(ok && base64declen>3) {
       
    91 		// Second step: unzip with the QCompress header. That header is just a big-endian
       
    92 		// uint32 indicating the length of the uncompressed data.
       
    93 		uint32_t unzipLen =
       
    94 				(((uint32_t)base64decout[0])<<24)
       
    95 				+ (((uint32_t)base64decout[1])<<16)
       
    96 				+ (((uint32_t)base64decout[2])<<8)
       
    97 				+ base64decout[3];
       
    98 		uint8_t *out = flib_malloc(unzipLen);
       
    99 		if(out) {
       
   100 			uLongf actualUnzipLen = unzipLen;
       
   101 			int resultcode = uncompress(out, &actualUnzipLen, (Bytef*)(base64decout+4), base64declen-4);
       
   102 			if(resultcode == Z_OK) {
       
   103 				result = out;
       
   104 				*outlen = actualUnzipLen;
       
   105 				out = NULL;
       
   106 			} else {
       
   107 				flib_log_e("Uncompressing drawn map failed. Code: %i", resultcode);
       
   108 			}
       
   109 		}
       
   110 		free(out);
       
   111 	} else {
       
   112 		flib_log_e("base64 decoding of drawn map failed.");
       
   113 	}
       
   114 	free(base64decout);
       
   115 	return result;
       
   116 }