int flib_ipc_append_script(flib_vector *vec, const char *script) { int result = -1; if(!log_badargs_if2(vec==NULL, script==NULL)) { result = flib_ipc_append_message(vec, "escript %s", script); } return result; }
int flib_teamlist_insert(flib_teamlist *list, flib_team *team, int pos) { if(!log_badargs_if2(list==NULL, team==NULL) && !insertTeam(&list->teams, &list->teamCount, team, pos)) { return 0; } return -1; }
int flib_weaponsetlist_insert(flib_weaponsetlist *list, flib_weaponset *set, int pos) { if(!log_badargs_if2(list==NULL, set==NULL) && !insertWeaponset(&list->weaponsets, &list->weaponsetCount, set, pos)) { return 0; } return -1; }
int flib_ipc_append_gamescheme(flib_vector *vec, const flib_scheme *scheme) { int result = -1; flib_vector *tempvector = flib_vector_create(); if(!log_badargs_if2(vec==NULL, scheme==NULL) && tempvector) { bool error = false; error |= flib_ipc_append_message(tempvector, "e$gmflags %"PRIu32, buildModFlags(scheme)); for(int i=0; i<flib_meta.settingCount; i++) { if(flib_meta.settings[i].engineCommand) { int value = scheme->settings[i]; if(flib_meta.settings[i].maxMeansInfinity) { value = value>=flib_meta.settings[i].max ? 9999 : value; } if(flib_meta.settings[i].times1000) { value *= 1000; } error |= flib_ipc_append_message(tempvector, "%s %i", flib_meta.settings[i].engineCommand, value); } } if(!error) { // Message created, now we can copy everything. flib_constbuffer constbuf = flib_vector_as_constbuffer(tempvector); if(!flib_vector_append(vec, constbuf.data, constbuf.size)) { result = 0; } } } flib_vector_destroy(tempvector); return result; }
int flib_ipc_append_fullconfig(flib_vector *vec, const flib_gamesetup *setup, bool netgame) { int result = -1; flib_vector *tempvector = flib_vector_create(); if(!log_badargs_if2(vec==NULL, setup==NULL) && tempvector) { bool error = false; bool perHogAmmo = false; bool sharedAmmo = false; error |= flib_ipc_append_message(vec, netgame ? "TN" : "TL"); if(setup->map) { error |= flib_ipc_append_mapconf(tempvector, setup->map, false); } if(setup->style) { error |= flib_ipc_append_style(tempvector, setup->style); } if(setup->gamescheme) { error |= flib_ipc_append_gamescheme(tempvector, setup->gamescheme); sharedAmmo = flib_scheme_get_mod(setup->gamescheme, "sharedammo"); // Shared ammo has priority over per-hog ammo perHogAmmo = !sharedAmmo && flib_scheme_get_mod(setup->gamescheme, "perhogammo"); } if(setup->teamlist->teams && setup->teamlist->teamCount>0) { int *clanColors = flib_calloc(setup->teamlist->teamCount, sizeof(int)); if(!clanColors) { error = true; } else { int clanCount = 0; for(int i=0; !error && i<setup->teamlist->teamCount; i++) { flib_team *team = setup->teamlist->teams[i]; // Find the clan index of this team (clans are identified by color). bool newClan = false; int clan = 0; while(clan<clanCount && clanColors[clan] != team->colorIndex) { clan++; } if(clan==clanCount) { newClan = true; clanCount++; clanColors[clan] = team->colorIndex; } // If shared ammo is active, only add an ammo store for the first team in each clan. bool noAmmoStore = sharedAmmo&&!newClan; error |= flib_ipc_append_addteam(tempvector, setup->teamlist->teams[i], perHogAmmo, noAmmoStore); } } free(clanColors); } error |= flib_ipc_append_message(tempvector, "!"); if(!error) { // Message created, now we can copy everything. flib_constbuffer constbuf = flib_vector_as_constbuffer(tempvector); if(!flib_vector_append(vec, constbuf.data, constbuf.size)) { result = 0; } } } return result; }
flib_map *flib_map_create_named(const char *seed, const char *name) { if(log_badargs_if2(seed==NULL, name==NULL)) { return NULL; } flib_map newmap = {0}; newmap.mapgen = MAPGEN_NAMED; newmap.name = (char*)name; newmap.seed = (char*)seed; return flib_map_copy(&newmap); }
flib_team *flib_teamlist_find(const flib_teamlist *list, const char *name) { flib_team *result = NULL; if(!log_badargs_if2(list==NULL, name==NULL)) { int itemid = findTeam(list, name); if(itemid>=0) { result = list->teams[itemid]; } } return result; }
int flib_scheme_get_setting(const flib_scheme *scheme, const char *name, int def) { if(!log_badargs_if2(scheme==NULL, name==NULL)) { for(int i=0; i<flib_meta.settingCount; i++) { if(!strcmp(flib_meta.settings[i].name, name)) { return scheme->settings[i]; } } flib_log_e("Unable to find game setting %s", name); } return def; }
bool flib_scheme_get_mod(const flib_scheme *scheme, const char *name) { if(!log_badargs_if2(scheme==NULL, name==NULL)) { for(int i=0; i<flib_meta.modCount; i++) { if(!strcmp(flib_meta.mods[i].name, name)) { return scheme->mods[i]; } } flib_log_e("Unable to find game mod %s", name); } return false; }
flib_map *flib_map_create_maze(const char *seed, const char *theme, int mazeSize) { if(log_badargs_if2(seed==NULL, theme==NULL)) { return NULL; } flib_map newmap = {0}; newmap.mapgen = MAPGEN_MAZE; newmap.name = "+maze+"; newmap.seed = (char*)seed; newmap.theme = (char*)theme; newmap.mazeSize = mazeSize; return flib_map_copy(&newmap); }
flib_map *flib_map_create_regular(const char *seed, const char *theme, int templateFilter) { if(log_badargs_if2(seed==NULL, theme==NULL)) { return NULL; } flib_map newmap = {0}; newmap.mapgen = MAPGEN_REGULAR; newmap.name = "+rnd+"; newmap.seed = (char*)seed; newmap.theme = (char*)theme; newmap.templateFilter = templateFilter; return flib_map_copy(&newmap); }
static int flib_ipc_append_addteam(flib_vector *vec, const flib_team *team, bool perHogAmmo, bool noAmmoStore) { int result = -1; flib_vector *tempvector = flib_vector_create(); if(!log_badargs_if2(vec==NULL, team==NULL) && tempvector) { bool error = false; if(!perHogAmmo && !noAmmoStore) { error = error || appendWeaponSet(tempvector, team->hogs[0].weaponset) || flib_ipc_append_message(tempvector, "eammstore"); } char md5Hex[33]; calculateMd5Hex(team->ownerName ? team->ownerName : "", md5Hex); if(team->colorIndex<0 || team->colorIndex>=flib_teamcolor_count) { flib_log_e("Color index out of bounds for team %s: %i", team->name, team->colorIndex); error = true; } else { error |= flib_ipc_append_message(tempvector, "eaddteam %s %"PRIu32" %s", md5Hex, flib_teamcolors[team->colorIndex], team->name); } if(team->remoteDriven) { error |= flib_ipc_append_message(tempvector, "erdriven"); } error |= flib_ipc_append_message(tempvector, "egrave %s", team->grave); error |= flib_ipc_append_message(tempvector, "efort %s", team->fort); error |= flib_ipc_append_message(tempvector, "evoicepack %s", team->voicepack); error |= flib_ipc_append_message(tempvector, "eflag %s", team->flag); for(int i=0; i<team->bindingCount; i++) { error |= flib_ipc_append_message(tempvector, "ebind %s %s", team->bindings[i].binding, team->bindings[i].action); } for(int i=0; i<team->hogsInGame; i++) { if(perHogAmmo && !noAmmoStore) { error |= appendWeaponSet(tempvector, team->hogs[i].weaponset); } error |= flib_ipc_append_message(tempvector, "eaddhh %i %i %s", team->hogs[i].difficulty, team->hogs[i].initialHealth, team->hogs[i].name); error |= flib_ipc_append_message(tempvector, "ehat %s", team->hogs[i].hat); } if(!error) { // Message created, now we can copy everything. flib_constbuffer constbuf = flib_vector_as_constbuffer(tempvector); if(!flib_vector_append(vec, constbuf.data, constbuf.size)) { result = 0; } } } flib_vector_destroy(tempvector); return result; }
flib_weaponset *flib_weaponset_from_ammostring(const char *name, const char *ammostring) { flib_weaponset *result = NULL; if(!log_badargs_if2(name==NULL, ammostring==NULL)) { result = flib_weaponset_create(name); if(result) { int fieldlen = strlen(ammostring)/4; setField(result->loadout, ammostring, fieldlen, false); setField(result->crateprob, ammostring + fieldlen, fieldlen, true); setField(result->delay, ammostring + 2*fieldlen, fieldlen, true); setField(result->crateammo, ammostring + 3*fieldlen, fieldlen, true); } } return result; }
int flib_ipcbase_recv_map(flib_ipcbase *ipc, void *data) { if(log_badargs_if2(ipc==NULL, data==NULL)) { return -1; } receiveToBuffer(ipc); if(ipc->readBufferSize >= IPCBASE_MAPMSG_BYTES) { popFromReadBuffer(ipc, data, IPCBASE_MAPMSG_BYTES); return IPCBASE_MAPMSG_BYTES; } else { return -1; } }
int flib_teamlist_delete(flib_teamlist *list, const char *name) { int result = -1; if(!log_badargs_if2(list==NULL, name==NULL)) { int itemid = findTeam(list, name); if(itemid>=0) { flib_team *team = list->teams[itemid]; if(!deleteTeam(&list->teams, &list->teamCount, itemid)) { flib_team_destroy(team); result = 0; } } } return result; }
int flib_ipc_append_mapconf(flib_vector *vec, const flib_map *map, bool mappreview) { int result = -1; flib_vector *tempvector = flib_vector_create(); if(!log_badargs_if2(vec==NULL, map==NULL)) { bool error = false; if(map->mapgen == MAPGEN_NAMED) { error |= log_e_if(!map->name, "Missing map name") || flib_ipc_append_message(tempvector, "emap %s", map->name); } if(!mappreview) { error |= log_e_if(!map->theme, "Missing map theme") || flib_ipc_append_message(tempvector, "etheme %s", map->theme); } error |= flib_ipc_append_seed(tempvector, map->seed); error |= flib_ipc_append_message(tempvector, "e$template_filter %i", map->templateFilter); error |= flib_ipc_append_message(tempvector, "e$mapgen %i", map->mapgen); if(map->mapgen == MAPGEN_MAZE) { error |= flib_ipc_append_message(tempvector, "e$maze_size %i", map->mazeSize); } if(map->mapgen == MAPGEN_DRAWN) { /* * We have to split the drawn map data into several edraw messages here because * it can be longer than the maximum message size. */ const char *edraw = "edraw "; int edrawlen = strlen(edraw); for(size_t offset=0; offset<map->drawDataSize; offset+=200) { size_t bytesRemaining = map->drawDataSize-offset; int fragmentsize = bytesRemaining < 200 ? bytesRemaining : 200; uint8_t messagesize = edrawlen + fragmentsize; error |= flib_vector_append(tempvector, &messagesize, 1); error |= flib_vector_append(tempvector, edraw, edrawlen); error |= flib_vector_append(tempvector, map->drawData+offset, fragmentsize); } } if(!log_e_if(error, "Error generating map config")) { // Message created, now we can copy everything. flib_constbuffer constbuf = flib_vector_as_constbuffer(tempvector); if(!flib_vector_append(vec, constbuf.data, constbuf.size)) { result = 0; } } } flib_vector_destroy(tempvector); return result; }
int flib_ini_create_section(flib_ini *ini, const char *section) { int result = INI_ERROR_OTHER; if(!log_badargs_if2(ini==NULL, section==NULL)) { result = flib_ini_enter_section(ini, section); if(result == INI_ERROR_NOTFOUND) { if(iniparser_set(ini->inidict, section, NULL)) { flib_log_e("Error creating ini section %s", section); result = INI_ERROR_OTHER; } else { result = flib_ini_enter_section(ini, section); } } } return result; }
int flib_ipcbase_send_raw(flib_ipcbase *ipc, const void *data, size_t len) { if(log_badargs_if2(ipc==NULL, data==NULL && len>0) || log_w_if(!ipc->sock, "flib_ipcbase_send_raw: Not connected.")) { return -1; } if(flib_socket_send(ipc->sock, data, len) == len) { logSentMsg(data, len); return 0; } else { flib_log_w("Failed or incomplete IPC write: engine connection lost."); flib_socket_close(ipc->sock); ipc->sock = NULL; return -1; } }
int flib_team_to_ini(const char *filename, const flib_team *team) { int result = -1; if(!log_badargs_if2(filename==NULL, team==NULL)) { flib_ini *ini = flib_ini_create(filename); bool error = false; error |= writeTeamSection(team, ini); error |= writeHogSections(team, ini); error |= writeBindingSection(team, ini); if(!error) { result = flib_ini_save(ini, filename); } flib_ini_destroy(ini); } return result; }
int flib_ini_save(flib_ini *ini, const char *filename) { int result = INI_ERROR_OTHER; if(!log_badargs_if2(ini==NULL, filename==NULL)) { FILE *file = fopen(filename, "wb"); if(!file) { flib_log_e("Error opening file \"%s\" for writing.", filename); } else { iniparser_dump_ini(ini->inidict, file); if(fclose(file)) { flib_log_e("Write error on ini file \"%s\"", filename); } else { result = 0; } } } return result; }
int flib_weaponsetlist_to_ini(const char *filename, const flib_weaponsetlist *list) { int result = -1; if(!log_badargs_if2(filename==NULL, list==NULL)) { flib_ini *ini = flib_ini_create(NULL); if(ini && !flib_ini_create_section(ini, "General")) { bool error = false; for(int i=0; i<list->weaponsetCount && !error; i++) { error |= writeWeaponsetToIni(ini, list->weaponsets[i]); } if(!error) { result = flib_ini_save(ini, filename); } } flib_ini_destroy(ini); } return result; }
int flib_ini_enter_section(flib_ini *ini, const char *section) { int result = INI_ERROR_OTHER; if(ini) { free(ini->currentSection); ini->currentSection = NULL; } if(!log_badargs_if2(ini==NULL, section==NULL)) { if(!iniparser_find_entry(ini->inidict, section)) { flib_log_d("Ini section %s not found", section); result = INI_ERROR_NOTFOUND; } else { ini->currentSection = flib_strdupnull(section); if(ini->currentSection) { // Usually iniparser ignores case, but some section-handling functions don't, // so we set it to lowercase manually strToLower(ini->currentSection); result = 0; } } } return result; }
int flib_ipcbase_recv_message(flib_ipcbase *ipc, void *data) { if(log_badargs_if2(ipc==NULL, data==NULL)) { return -1; } if(!isMessageReady(ipc)) { receiveToBuffer(ipc); } if(isMessageReady(ipc)) { int msgsize = ipc->readBuffer[0]+1; popFromReadBuffer(ipc, data, msgsize); logRecvMsg(data); return msgsize; } else if(!ipc->sock && ipc->readBufferSize>0) { flib_log_w("Last message from engine data stream is incomplete (received %u of %u bytes)", (unsigned)ipc->readBufferSize, (unsigned)(ipc->readBuffer[0])+1); ipc->readBufferSize = 0; return -1; } else { return -1; } }
int flib_ipc_append_message(flib_vector *vec, const char *fmt, ...) { int result = -1; if(!log_badargs_if2(vec==NULL, fmt==NULL)) { // 1 byte size prefix, 255 bytes max message length, 1 0-byte for vsnprintf char msgbuffer[257]; // Format the message, leaving one byte at the start for the length va_list argp; va_start(argp, fmt); int msgSize = vsnprintf(msgbuffer+1, 256, fmt, argp); va_end(argp); if(!log_e_if(msgSize > 255, "Message too long (%u bytes)", (unsigned)msgSize) && !log_e_if(msgSize < 0, "printf error")) { // Add the length prefix ((uint8_t*)msgbuffer)[0] = msgSize; // Append it to the vector result = flib_vector_append(vec, msgbuffer, msgSize+1); } } return result; }
int flib_ini_get_keycount(flib_ini *ini) { if(!log_badargs_if2(ini==NULL, ini->currentSection==NULL)) { return iniparser_getsecnkeys(ini->inidict, ini->currentSection); } return INI_ERROR_OTHER; }
char *flib_ini_get_sectionname(flib_ini *ini, int number) { if(!log_badargs_if2(ini==NULL, number<0)) { return flib_strdupnull(iniparser_getsecname(ini->inidict, number)); } return NULL; }
int flib_ipc_append_seed(flib_vector *vec, const char *seed) { if(log_badargs_if2(vec==NULL, seed==NULL)) { return -1; } return flib_ipc_append_message(vec, "eseed %s", seed); }