project_files/frontlib/net/netprotocol.c
changeset 10017 de822cd3df3a
parent 7566 57d343ee382f
equal deleted inserted replaced
10015:4feced261c68 10017:de822cd3df3a
    30 #include <stdio.h>
    30 #include <stdio.h>
    31 #include <errno.h>
    31 #include <errno.h>
    32 #include <stdlib.h>
    32 #include <stdlib.h>
    33 
    33 
    34 static int fillTeamFromMsg(flib_team *team, char **parts) {
    34 static int fillTeamFromMsg(flib_team *team, char **parts) {
    35 	team->name = flib_strdupnull(parts[0]);
    35     team->name = flib_strdupnull(parts[0]);
    36 	team->grave = flib_strdupnull(parts[1]);
    36     team->grave = flib_strdupnull(parts[1]);
    37 	team->fort = flib_strdupnull(parts[2]);
    37     team->fort = flib_strdupnull(parts[2]);
    38 	team->voicepack = flib_strdupnull(parts[3]);
    38     team->voicepack = flib_strdupnull(parts[3]);
    39 	team->flag = flib_strdupnull(parts[4]);
    39     team->flag = flib_strdupnull(parts[4]);
    40 	team->ownerName = flib_strdupnull(parts[5]);
    40     team->ownerName = flib_strdupnull(parts[5]);
    41 	if(!team->name || !team->grave || !team->fort || !team->voicepack || !team->flag || !team->ownerName) {
    41     if(!team->name || !team->grave || !team->fort || !team->voicepack || !team->flag || !team->ownerName) {
    42 		return -1;
    42         return -1;
    43 	}
    43     }
    44 
    44 
    45 	errno = 0;
    45     errno = 0;
    46 	long difficulty = strtol(parts[6], NULL, 10);
    46     long difficulty = strtol(parts[6], NULL, 10);
    47 	if(errno) {
    47     if(errno) {
    48 		return -1;
    48         return -1;
    49 	}
    49     }
    50 
    50 
    51 	for(int i=0; i<HEDGEHOGS_PER_TEAM; i++) {
    51     for(int i=0; i<HEDGEHOGS_PER_TEAM; i++) {
    52 		flib_hog *hog = &team->hogs[i];
    52         flib_hog *hog = &team->hogs[i];
    53 		hog->difficulty = difficulty;
    53         hog->difficulty = difficulty;
    54 		hog->name = flib_strdupnull(parts[7+2*i]);
    54         hog->name = flib_strdupnull(parts[7+2*i]);
    55 		hog->hat = flib_strdupnull(parts[8+2*i]);
    55         hog->hat = flib_strdupnull(parts[8+2*i]);
    56 		if(!hog->name || !hog->hat) {
    56         if(!hog->name || !hog->hat) {
    57 			return -1;
    57             return -1;
    58 		}
    58         }
    59 	}
    59     }
    60 
    60 
    61 	// Set some default assumptions as well
    61     // Set some default assumptions as well
    62 	team->colorIndex = DEFAULT_COLOR_INDEX;
    62     team->colorIndex = DEFAULT_COLOR_INDEX;
    63 	team->hogsInGame = DEFAULT_HEDGEHOG_COUNT;
    63     team->hogsInGame = DEFAULT_HEDGEHOG_COUNT;
    64 	team->remoteDriven = true;
    64     team->remoteDriven = true;
    65 	return 0;
    65     return 0;
    66 }
    66 }
    67 
    67 
    68 flib_team *flib_team_from_netmsg(char **parts) {
    68 flib_team *flib_team_from_netmsg(char **parts) {
    69 	flib_team *result = NULL;
    69     flib_team *result = NULL;
    70 	flib_team *tmpTeam = flib_calloc(1, sizeof(flib_team));
    70     flib_team *tmpTeam = flib_calloc(1, sizeof(flib_team));
    71 	if(tmpTeam) {
    71     if(tmpTeam) {
    72 		if(!fillTeamFromMsg(tmpTeam, parts)) {
    72         if(!fillTeamFromMsg(tmpTeam, parts)) {
    73 			result = tmpTeam;
    73             result = tmpTeam;
    74 			tmpTeam = NULL;
    74             tmpTeam = NULL;
    75 		} else {
    75         } else {
    76 			flib_log_e("Error parsing team from net.");
    76             flib_log_e("Error parsing team from net.");
    77 		}
    77         }
    78 	}
    78     }
    79 	flib_team_destroy(tmpTeam);
    79     flib_team_destroy(tmpTeam);
    80 	return result;
    80     return result;
    81 }
    81 }
    82 
    82 
    83 flib_scheme *flib_scheme_from_netmsg(char **parts) {
    83 flib_scheme *flib_scheme_from_netmsg(char **parts) {
    84 	flib_scheme *result = flib_scheme_create(parts[0]);
    84     flib_scheme *result = flib_scheme_create(parts[0]);
    85 	if(result) {
    85     if(result) {
    86 		for(int i=0; i<flib_meta.modCount; i++) {
    86         for(int i=0; i<flib_meta.modCount; i++) {
    87 			result->mods[i] = !strcmp(parts[i+1], "true");
    87             result->mods[i] = !strcmp(parts[i+1], "true");
    88 		}
    88         }
    89 		for(int i=0; i<flib_meta.settingCount; i++) {
    89         for(int i=0; i<flib_meta.settingCount; i++) {
    90 			result->settings[i] = atoi(parts[i+flib_meta.modCount+1]);
    90             result->settings[i] = atoi(parts[i+flib_meta.modCount+1]);
    91 		}
    91         }
    92 	}
    92     }
    93 	return result;
    93     return result;
    94 }
    94 }
    95 
    95 
    96 flib_map *flib_map_from_netmsg(char **parts) {
    96 flib_map *flib_map_from_netmsg(char **parts) {
    97 	flib_map *result = flib_map_create_named(parts[3], parts[0]);
    97     flib_map *result = flib_map_create_named(parts[3], parts[0]);
    98 	if(result) {
    98     if(result) {
    99 		result->mapgen = atoi(parts[1]);
    99         result->mapgen = atoi(parts[1]);
   100 		result->mazeSize = atoi(parts[2]);
   100         result->mazeSize = atoi(parts[2]);
   101 		result->templateFilter = atoi(parts[4]);
   101         result->templateFilter = atoi(parts[4]);
   102 	}
   102     }
   103 	return result;
   103     return result;
   104 }
   104 }
   105 
   105 
   106 int flib_drawnmapdata_from_netmsg(char *netmsg, uint8_t** outbuf, size_t *outlen) {
   106 int flib_drawnmapdata_from_netmsg(char *netmsg, uint8_t** outbuf, size_t *outlen) {
   107 	int result = -1;
   107     int result = -1;
   108 
   108 
   109 	// First step: base64 decoding
   109     // First step: base64 decoding
   110 	char *base64decout = NULL;
   110     char *base64decout = NULL;
   111 	size_t base64declen;
   111     size_t base64declen;
   112 	bool ok = base64_decode_alloc(netmsg, strlen(netmsg), &base64decout, &base64declen);
   112     bool ok = base64_decode_alloc(netmsg, strlen(netmsg), &base64decout, &base64declen);
   113 	if(ok && base64declen>3) {
   113     if(ok && base64declen>3) {
   114 		// Second step: unzip with the QCompress header. That header is just a big-endian
   114         // Second step: unzip with the QCompress header. That header is just a big-endian
   115 		// uint32 indicating the length of the uncompressed data.
   115         // uint32 indicating the length of the uncompressed data.
   116 		uint8_t *ubyteBuf = (uint8_t*)base64decout;
   116         uint8_t *ubyteBuf = (uint8_t*)base64decout;
   117 		uint32_t unzipLen =
   117         uint32_t unzipLen =
   118 				(((uint32_t)ubyteBuf[0])<<24)
   118                 (((uint32_t)ubyteBuf[0])<<24)
   119 				+ (((uint32_t)ubyteBuf[1])<<16)
   119                 + (((uint32_t)ubyteBuf[1])<<16)
   120 				+ (((uint32_t)ubyteBuf[2])<<8)
   120                 + (((uint32_t)ubyteBuf[2])<<8)
   121 				+ ubyteBuf[3];
   121                 + ubyteBuf[3];
   122 		if(unzipLen==0) {
   122         if(unzipLen==0) {
   123 			*outbuf = NULL;
   123             *outbuf = NULL;
   124 			*outlen = 0;
   124             *outlen = 0;
   125 			result = 0;
   125             result = 0;
   126 		} else {
   126         } else {
   127 			uint8_t *out = flib_malloc(unzipLen);
   127             uint8_t *out = flib_malloc(unzipLen);
   128 			if(out) {
   128             if(out) {
   129 				uLongf actualUnzipLen = unzipLen;
   129                 uLongf actualUnzipLen = unzipLen;
   130 				int resultcode = uncompress(out, &actualUnzipLen, (Bytef*)(base64decout+4), base64declen-4);
   130                 int resultcode = uncompress(out, &actualUnzipLen, (Bytef*)(base64decout+4), base64declen-4);
   131 				if(resultcode == Z_OK) {
   131                 if(resultcode == Z_OK) {
   132 					*outbuf = out;
   132                     *outbuf = out;
   133 					*outlen = actualUnzipLen;
   133                     *outlen = actualUnzipLen;
   134 					out = NULL;
   134                     out = NULL;
   135 					result = 0;
   135                     result = 0;
   136 				} else {
   136                 } else {
   137 					flib_log_e("Uncompressing drawn map failed. Code: %i", resultcode);
   137                     flib_log_e("Uncompressing drawn map failed. Code: %i", resultcode);
   138 				}
   138                 }
   139 			}
   139             }
   140 			free(out);
   140             free(out);
   141 		}
   141         }
   142 	} else {
   142     } else {
   143 		flib_log_e("base64 decoding of drawn map failed.");
   143         flib_log_e("base64 decoding of drawn map failed.");
   144 	}
   144     }
   145 	free(base64decout);
   145     free(base64decout);
   146 	return result;
   146     return result;
   147 }
   147 }
   148 
   148 
   149 flib_room *flib_room_from_netmsg(char **params) {
   149 flib_room *flib_room_from_netmsg(char **params) {
   150 	flib_room *result = NULL;
   150     flib_room *result = NULL;
   151 	flib_room *tmpRoom = flib_calloc(1, sizeof(flib_room));
   151     flib_room *tmpRoom = flib_calloc(1, sizeof(flib_room));
   152 	if(tmpRoom) {
   152     if(tmpRoom) {
   153 		tmpRoom->inProgress = !strcmp(params[0], "True");
   153         tmpRoom->inProgress = !strcmp(params[0], "True");
   154 		tmpRoom->name = flib_strdupnull(params[1]);
   154         tmpRoom->name = flib_strdupnull(params[1]);
   155 		tmpRoom->playerCount = atoi(params[2]);
   155         tmpRoom->playerCount = atoi(params[2]);
   156 		tmpRoom->teamCount = atoi(params[3]);
   156         tmpRoom->teamCount = atoi(params[3]);
   157 		tmpRoom->owner = flib_strdupnull(params[4]);
   157         tmpRoom->owner = flib_strdupnull(params[4]);
   158 		tmpRoom->map = flib_strdupnull(params[5]);
   158         tmpRoom->map = flib_strdupnull(params[5]);
   159 		tmpRoom->scheme = flib_strdupnull(params[6]);
   159         tmpRoom->scheme = flib_strdupnull(params[6]);
   160 		tmpRoom->weapons = flib_strdupnull(params[7]);
   160         tmpRoom->weapons = flib_strdupnull(params[7]);
   161 		if(tmpRoom->name && tmpRoom->owner && tmpRoom->map && tmpRoom->scheme && tmpRoom->weapons) {
   161         if(tmpRoom->name && tmpRoom->owner && tmpRoom->map && tmpRoom->scheme && tmpRoom->weapons) {
   162 			result = tmpRoom;
   162             result = tmpRoom;
   163 			tmpRoom = NULL;
   163             tmpRoom = NULL;
   164 		}
   164         }
   165 	}
   165     }
   166 	flib_room_destroy(tmpRoom);
   166     flib_room_destroy(tmpRoom);
   167 	return result;
   167     return result;
   168 }
   168 }
   169 
   169 
   170 int fillRoomArray(flib_room **array, char **params, int count) {
   170 int fillRoomArray(flib_room **array, char **params, int count) {
   171 	for(int i=0; i<count; i++) {
   171     for(int i=0; i<count; i++) {
   172 		array[i] = flib_room_from_netmsg(params + 8*i);
   172         array[i] = flib_room_from_netmsg(params + 8*i);
   173 		if(!array[i]) {
   173         if(!array[i]) {
   174 			return -1;
   174             return -1;
   175 		}
   175         }
   176 	}
   176     }
   177 	return 0;
   177     return 0;
   178 }
   178 }
   179 
   179 
   180 flib_room **flib_room_array_from_netmsg(char **params, int count) {
   180 flib_room **flib_room_array_from_netmsg(char **params, int count) {
   181 	flib_room **result = flib_calloc(count, sizeof(flib_room*));
   181     flib_room **result = flib_calloc(count, sizeof(flib_room*));
   182 	if(result) {
   182     if(result) {
   183 		if(fillRoomArray(result, params, count)) {
   183         if(fillRoomArray(result, params, count)) {
   184 			for(int i=0; i<count; i++) {
   184             for(int i=0; i<count; i++) {
   185 				flib_room_destroy(result[i]);
   185                 flib_room_destroy(result[i]);
   186 			}
   186             }
   187 			free(result);
   187             free(result);
   188 			result = NULL;
   188             result = NULL;
   189 		}
   189         }
   190 	}
   190     }
   191 	return result;
   191     return result;
   192 }
   192 }