project_files/frontlib/ipc/ipcprotocol.c
changeset 7230 240620f46dd7
parent 7224 5143861c83bd
child 7271 5608ac657362
equal deleted inserted replaced
7227:1c859f572d72 7230:240620f46dd7
     4 
     4 
     5 #include <stdio.h>
     5 #include <stdio.h>
     6 #include <stdbool.h>
     6 #include <stdbool.h>
     7 #include <string.h>
     7 #include <string.h>
     8 #include <inttypes.h>
     8 #include <inttypes.h>
       
     9 #include <stdlib.h>
     9 
    10 
    10 int flib_ipc_append_message(flib_vector *vec, const char *fmt, ...) {
    11 int flib_ipc_append_message(flib_vector *vec, const char *fmt, ...) {
    11 	int result = -1;
    12 	int result = -1;
    12 	if(!vec || !fmt) {
    13 	if(!vec || !fmt) {
    13 		flib_log_e("null parameter in flib_ipc_appendmessage");
    14 		flib_log_e("null parameter in flib_ipc_appendmessage");
    36 		}
    37 		}
    37 	}
    38 	}
    38 	return result;
    39 	return result;
    39 }
    40 }
    40 
    41 
    41 int flib_ipc_append_mapconf(flib_vector *vec, flib_map *map, bool mappreview) {
    42 int flib_ipc_append_mapconf(flib_vector *vec, const flib_map *map, bool mappreview) {
    42 	int result = -1;
    43 	int result = -1;
    43 	flib_vector *tempvector = flib_vector_create();
    44 	flib_vector *tempvector = flib_vector_create();
    44 	if(!vec || !map) {
    45 	if(!vec || !map) {
    45 		flib_log_e("null parameter in flib_ipc_append_mapconf");
    46 		flib_log_e("null parameter in flib_ipc_append_mapconf");
    46 	} else if(tempvector) {
    47 	} else if(tempvector) {
    94 	} else {
    95 	} else {
    95 		return flib_ipc_append_message(vec, "eseed %s", seed);
    96 		return flib_ipc_append_message(vec, "eseed %s", seed);
    96 	}
    97 	}
    97 }
    98 }
    98 
    99 
    99 int flib_ipc_append_gamescheme(flib_vector *vec, flib_cfg *scheme, flib_cfg_meta *meta) {
   100 int flib_ipc_append_gamescheme(flib_vector *vec, const flib_cfg *scheme) {
   100 	int result = -1;
   101 	int result = -1;
   101 	flib_vector *tempvector = flib_vector_create();
   102 	flib_vector *tempvector = flib_vector_create();
   102 	if(!vec || !scheme || !meta) {
   103 	if(!vec || !scheme) {
   103 		flib_log_e("null parameter in flib_ipc_append_gamescheme");
   104 		flib_log_e("null parameter in flib_ipc_append_gamescheme");
   104 	} else if(tempvector) {
   105 	} else if(tempvector) {
       
   106 		const flib_cfg_meta *meta = scheme->meta;
   105 		bool error = false;
   107 		bool error = false;
   106 		uint32_t gamemods = 0;
   108 		uint32_t gamemods = 0;
   107 		for(int i=0; i<meta->modCount; i++) {
   109 		for(int i=0; i<meta->modCount; i++) {
   108 			if(scheme->mods[i]) {
   110 			if(scheme->mods[i]) {
   109 				gamemods |= (1<<meta->mods[i].bitmaskIndex);
   111 				gamemods |= (1<<meta->mods[i].bitmaskIndex);
   110 			}
   112 			}
   111 		}
   113 		}
   112 		error |= flib_ipc_append_message(tempvector, "e$gmflags %"PRIu32, gamemods);
   114 		error |= flib_ipc_append_message(tempvector, "e$gmflags %"PRIu32, gamemods);
   113 		for(int i=0; i<meta->settingCount; i++) {
   115 		for(int i=0; i<meta->settingCount; i++) {
   114 			int value = scheme->settings[i];
   116 			int value = scheme->settings[i];
   115 			if(meta->settings[i].checkOverMax) {
   117 			if(meta->settings[i].maxMeansInfinity) {
   116 				value = value>meta->settings[i].max ? meta->settings[i].max : value;
   118 				value = value>=meta->settings[i].max ? 9999 : value;
   117 			}
   119 			}
   118 			if(meta->settings[i].times1000) {
   120 			if(meta->settings[i].times1000) {
   119 				value *= 1000;
   121 				value *= 1000;
   120 			}
   122 			}
   121 			error |= flib_ipc_append_message(tempvector, "%s %i", meta->settings[i].engineCommand, value);
   123 			error |= flib_ipc_append_message(tempvector, "%s %i", meta->settings[i].engineCommand, value);
   131 	}
   133 	}
   132 	flib_vector_destroy(tempvector);
   134 	flib_vector_destroy(tempvector);
   133 	return result;
   135 	return result;
   134 }
   136 }
   135 
   137 
   136 // FIXME shared ammo will break per-team ammo
   138 static int appendWeaponSet(flib_vector *vec, flib_weaponset *set) {
   137 int flib_ipc_append_addteam(flib_vector *vec, flib_team *team, bool perHogAmmo, bool sharedAmmo) {
   139 	return flib_ipc_append_message(vec, "eammloadt %s", set->loadout)
   138 	int result = -1;
   140 		|| flib_ipc_append_message(vec, "eammprob %s", set->crateprob)
   139 	flib_vector *tempvector = flib_vector_create();
   141 		|| flib_ipc_append_message(vec, "eammdelay %s", set->delay)
   140 	if(!vec || !team || !team->weaponset) {
   142 		|| flib_ipc_append_message(vec, "eammreinf %s", set->crateammo);
       
   143 }
       
   144 
       
   145 int flib_ipc_append_addteam(flib_vector *vec, const flib_team *team, bool perHogAmmo, bool noAmmoStore) {
       
   146 	int result = -1;
       
   147 	flib_vector *tempvector = flib_vector_create();
       
   148 	if(!vec || !team) {
   141 		flib_log_e("invalid parameter in flib_ipc_append_addteam");
   149 		flib_log_e("invalid parameter in flib_ipc_append_addteam");
   142 	} else if(tempvector) {
   150 	} else if(tempvector) {
   143 		bool error = false;
   151 		bool error = false;
   144 		error |= flib_ipc_append_message(tempvector, "eammloadt %s", team->weaponset->loadout);
   152 
   145 		error |= flib_ipc_append_message(tempvector, "eammprob %s", team->weaponset->crateprob);
   153 		if(!perHogAmmo && !noAmmoStore) {
   146 		error |= flib_ipc_append_message(tempvector, "eammdelay %s", team->weaponset->delay);
   154 			error |= appendWeaponSet(tempvector, team->hogs[0].weaponset);
   147 		error |= flib_ipc_append_message(tempvector, "eammreinf %s", team->weaponset->crateammo);
       
   148 		if(!perHogAmmo) {
       
   149 			error |= flib_ipc_append_message(tempvector, "eammstore");
   155 			error |= flib_ipc_append_message(tempvector, "eammstore");
   150 		}
   156 		}
   151 
   157 
   152 		char *hash = team->hash ? team->hash : "00000000000000000000000000000000";
   158 		char *hash = team->hash ? team->hash : "00000000000000000000000000000000";
   153 		error |= flib_ipc_append_message(tempvector, "eaddteam %s %"PRIu32" %s", hash, team->color, team->name);
   159 		error |= flib_ipc_append_message(tempvector, "eaddteam %s %"PRIu32" %s", hash, team->color, team->name);
   164 		for(int i=0; i<team->bindingCount; i++) {
   170 		for(int i=0; i<team->bindingCount; i++) {
   165 			error |= flib_ipc_append_message(tempvector, "ebind %s %s", team->bindings[i].binding, team->bindings[i].action);
   171 			error |= flib_ipc_append_message(tempvector, "ebind %s %s", team->bindings[i].binding, team->bindings[i].action);
   166 		}
   172 		}
   167 
   173 
   168 		for(int i=0; i<team->hogsInGame; i++) {
   174 		for(int i=0; i<team->hogsInGame; i++) {
       
   175 			if(perHogAmmo && !noAmmoStore) {
       
   176 				error |= appendWeaponSet(tempvector, team->hogs[i].weaponset);
       
   177 			}
   169 			error |= flib_ipc_append_message(tempvector, "eaddhh %i %i %s", team->hogs[i].difficulty, team->hogs[i].initialHealth, team->hogs[i].name);
   178 			error |= flib_ipc_append_message(tempvector, "eaddhh %i %i %s", team->hogs[i].difficulty, team->hogs[i].initialHealth, team->hogs[i].name);
   170 			error |= flib_ipc_append_message(tempvector, "ehat %s", team->hogs[i].hat);
   179 			error |= flib_ipc_append_message(tempvector, "ehat %s", team->hogs[i].hat);
   171 		}
   180 		}
   172 
   181 
   173 		if(!error) {
   182 		if(!error) {
   179 		}
   188 		}
   180 	}
   189 	}
   181 	flib_vector_destroy(tempvector);
   190 	flib_vector_destroy(tempvector);
   182 	return result;
   191 	return result;
   183 }
   192 }
       
   193 
       
   194 static bool getGameMod(const flib_cfg *conf, int maskbit) {
       
   195 	for(int i=0; i<conf->meta->modCount; i++) {
       
   196 		if(conf->meta->mods[i].bitmaskIndex == maskbit) {
       
   197 			return conf->mods[i];
       
   198 		}
       
   199 	}
       
   200 	flib_log_e("Unable to find game mod with mask bit %i", maskbit);
       
   201 	return false;
       
   202 }
       
   203 
       
   204 int flib_ipc_append_fullconfig(flib_vector *vec, const flib_gamesetup *setup, bool netgame) {
       
   205 	int result = -1;
       
   206 	flib_vector *tempvector = flib_vector_create();
       
   207 	if(!vec || !setup) {
       
   208 		flib_log_e("null parameter in flib_ipc_append_fullconfig");
       
   209 	} else if(tempvector) {
       
   210 		bool error = false;
       
   211 		bool perHogAmmo = false;
       
   212 		bool sharedAmmo = false;
       
   213 
       
   214 		error |= flib_ipc_append_message(vec, netgame ? "TN" : "TL");
       
   215 		error |= flib_ipc_append_seed(vec, setup->seed);
       
   216 		if(setup->map) {
       
   217 			error |= flib_ipc_append_mapconf(tempvector, setup->map, false);
       
   218 		}
       
   219 		if(setup->script) {
       
   220 			error |= flib_ipc_append_message(tempvector, "escript %s", setup->script);
       
   221 		}
       
   222 		if(setup->gamescheme) {
       
   223 			error |= flib_ipc_append_gamescheme(tempvector, setup->gamescheme);
       
   224 			sharedAmmo = getGameMod(setup->gamescheme, GAMEMOD_SHAREDAMMO_MASKBIT);
       
   225 			// Shared ammo has priority over per-hog ammo
       
   226 			perHogAmmo = !sharedAmmo && getGameMod(setup->gamescheme, GAMEMOD_PERHOGAMMO_MASKBIT);
       
   227 		}
       
   228 		if(setup->teams && setup->teamcount>0) {
       
   229 			uint32_t *clanColors = flib_calloc(setup->teamcount, sizeof(uint32_t));
       
   230 			if(!clanColors) {
       
   231 				error = true;
       
   232 			} else {
       
   233 				int clanCount = 0;
       
   234 				for(int i=0; i<setup->teamcount; i++) {
       
   235 					flib_team *team = setup->teams[i];
       
   236 					bool newClan = false;
       
   237 
       
   238 					// Find the clan index of this team (clans are identified by color).
       
   239 					// The upper 8 bits (alpha) are ignored in the engine as well.
       
   240 					uint32_t color = team->color&UINT32_C(0x00ffffff);
       
   241 					int clan = 0;
       
   242 					while(clan<clanCount && clanColors[clan] != color) {
       
   243 						clan++;
       
   244 					}
       
   245 					if(clan==clanCount) {
       
   246 						newClan = true;
       
   247 						clanCount++;
       
   248 						clanColors[clan] = color;
       
   249 					}
       
   250 
       
   251 					// If shared ammo is active, only add an ammo store for the first team in each clan.
       
   252 					bool noAmmoStore = sharedAmmo&&!newClan;
       
   253 					error |= flib_ipc_append_addteam(tempvector, setup->teams[i], perHogAmmo, noAmmoStore);
       
   254 				}
       
   255 			}
       
   256 			free(clanColors);
       
   257 		}
       
   258 		error |= flib_ipc_append_message(tempvector, "!");
       
   259 
       
   260 		if(!error) {
       
   261 			// Message created, now we can copy everything.
       
   262 			flib_constbuffer constbuf = flib_vector_as_constbuffer(tempvector);
       
   263 			if(flib_vector_append(vec, constbuf.data, constbuf.size) == constbuf.size) {
       
   264 				result = 0;
       
   265 			}
       
   266 		}
       
   267 	}
       
   268 	return result;
       
   269 }