/* * Retrieve artefact_class for the given id. */ void get_artefact_class_by_artefact_id (db_t *database, int artefactID, struct Artefact_class *artefact_class) { db_result_t *result; dstring_t *ds; ds = dstring_new("SELECT ac.* FROM " DB_TABLE_ARTEFACT_CLASS " ac LEFT JOIN " DB_TABLE_ARTEFACT " a ON ac.ArtefactClassID = a.ArtefactClassID " " WHERE a.artefactID = %d " " AND caveID = 0 " " AND initiated = %d", artefactID, ARTEFACT_UNINITIATED); result = db_query_dstring(database, ds); debug(DEBUG_ARTEFACT, "get_artefact_class_by_artefact_id: %s", dstring_str(ds)); /* Bedingung: ArtefaktID muss vorhanden sein */ if (db_result_num_rows(result) != 1) throw(SQL_EXCEPTION, "get_artefact_class_by_artefact_id: no such artefactID"); db_result_next_row(result); artefact_class->artefactClassID = db_result_get_int(result, "artefactClassID"); artefact_class->name = db_result_get_string(result, "name"); artefact_class->name_initiated = db_result_get_string(result, "name_initiated"); artefact_class->resref = db_result_get_string(result, "resref"); artefact_class->description = db_result_get_string(result, "description"); artefact_class->description_initiated = db_result_get_string(result, "description_initiated"); artefact_class->initiationID = db_result_get_int(result, "initiationID"); artefact_class->noZeroFood = db_result_get_int(result, "noZeroFood"); artefact_class->destroyOnMove = db_result_get_int(result, "destroyOnMove"); get_effect_list(result, artefact_class->effect); }
static void db_getmailbox_count(T M, Connection_T c) { ResultSet_T r; PreparedStatement_T stmt; unsigned result[3]; result[0] = result[1] = result[2] = 0; g_return_if_fail(M->id); /* count messages */ stmt = db_stmt_prepare(c, "SELECT " "SUM( CASE WHEN seen_flag = 0 THEN 1 ELSE 0 END) AS unseen, " "SUM( CASE WHEN seen_flag = 1 THEN 1 ELSE 0 END) AS seen, " "SUM( CASE WHEN recent_flag = 1 THEN 1 ELSE 0 END) AS recent " "FROM %smessages WHERE mailbox_idnr=? AND status IN (%d,%d)", DBPFX, MESSAGE_STATUS_NEW, MESSAGE_STATUS_SEEN); db_stmt_set_u64(stmt, 1, M->id); r = db_stmt_query(stmt); if (db_result_next(r)) { result[0] = (unsigned)db_result_get_int(r,0); // unseen result[1] = (unsigned)db_result_get_int(r,1); // seen result[2] = (unsigned)db_result_get_int(r,2); // recent } M->exists = result[0] + result[1]; M->unseen = result[0]; M->recent = result[2]; TRACE(TRACE_DEBUG, "exists [%d] unseen [%d] recent [%d]", M->exists, M->unseen, M->recent); /* now determine the next message UID * NOTE: * - expunged messages are selected as well in order to be able to restore them * - the next uit MUST NOT change unless messages are added to THIS mailbox * */ if (M->exists == 0) { M->uidnext = 1; return; } db_con_clear(c); stmt = db_stmt_prepare(c, "SELECT MAX(message_idnr)+1 FROM %smessages WHERE mailbox_idnr=?", DBPFX); db_stmt_set_u64(stmt, 1, M->id); r = db_stmt_query(stmt); if (db_result_next(r)) M->uidnext = db_result_get_u64(r,0); else M->uidnext = 1; }
/* * Retrieve cave table information for the given cave id. */ void get_cave_info (db_t *database, int cave_id, struct Cave *cave) { db_result_t *result = db_query(database, "SELECT * FROM " DB_TABLE_CAVE " WHERE caveID = %d", cave_id); if (!db_result_next_row(result)) throwf(SQL_EXCEPTION, "get_cave_info: cave %d not found", cave_id); cave->result = result; cave->cave_id = cave_id; cave->xpos = db_result_get_int(result, "xCoord"); cave->ypos = db_result_get_int(result, "yCoord"); cave->name = db_result_get_string(result, "name"); cave->player_id = db_result_get_int(result, "playerID"); cave->terrain = db_result_get_int(result, "terrain"); cave->takeoverable = db_result_get_int(result, "takeoverable"); cave->artefacts = db_result_get_int(result, "artefacts"); cave->heroID = db_result_get_int(result, "hero"); cave->monster_id = db_result_get_int(result, "monsterID"); cave->secure = db_result_get_int(result, "secureCave"); cave->protect_end = db_result_get_time(result, "protection_end"); get_resource_list(result, cave->resource); get_building_list(result, cave->building); get_science_list(result, cave->science); get_defense_system_list(result, cave->defense_system); get_unit_list(result, cave->unit); get_effect_list(result, cave->effect); }
/* * Function is called to instantiate a wonder's impact. */ void weatherEnd_handler (db_t *database, db_result_t *result) { int region_id; int weather_id; int impact_id; const struct Weather *weather; const struct WeatherImpact *impact; float effect[MAX_EFFECT]; dstring_t *query; int index, len; debug(DEBUG_TICKER, "entering function weatherEnd_handler()"); /* fetch data from event table */ region_id = db_result_get_int(result, "regionID"); weather_id = db_result_get_int(result, "weatherID"); impact_id = db_result_get_int(result, "impactID"); get_effect_list(result, effect); debug(DEBUG_TICKER, "regionID = %d, weatherID = %d", region_id, weather_id); weather = (struct Weather *) weather_type[weather_id]; impact = &weather->impacts[impact_id]; /* prepare update statement */ query = dstring_new("UPDATE " DB_TABLE_CAVE " SET "); for (index = 0; index < MAX_EFFECT; ++index) { double delta = -effect[index]; if (delta != 0) { const char *dbFieldName = effect_type[index]->dbFieldName; dstring_append(query, "%s = %s + %f,", dbFieldName, dbFieldName, delta); } } /* update the cave */ len = dstring_len(query) - 1; if (dstring_str(query)[len] == ',') { dstring_truncate(query, len); dstring_append(query, " WHERE regionID = %d", region_id); debug(DEBUG_SQL, "%s", dstring_str(query)); db_query_dstring(database, query); } debug(DEBUG_TICKER, "leaving function weatherEnd_handler()"); }
int get_artefact_for_caveID(db_t *database, int caveID, int spyableOnly) { dstring_t *ds; db_result_t *result; int artefactID = 0; if (spyableOnly) { ds = dstring_new("SELECT a.artefactID FROM " DB_TABLE_ARTEFACT " a LEFT JOIN " DB_TABLE_ARTEFACT_CLASS " ac ON a.ArtefactClassID = ac.ArtefactClassID " " WHERE a.caveID = %d AND ac.getArtefactBySpy = 1 ORDER BY RAND() LIMIT 1", caveID); } else { ds = dstring_new("SELECT artefactID FROM " DB_TABLE_ARTEFACT " WHERE caveID = %d ORDER BY RAND() LIMIT 1", caveID); } result = db_query_dstring(database, ds); debug(DEBUG_ARTEFACT, "get_artefact_for_caveID: %s", dstring_str(ds)); if (db_result_num_rows(result) == 0) { if (!spyableOnly) { debug(DEBUG_ARTEFACT, "get_artefact_for_caveID: fail... no artefact in cave %d", caveID); } else { debug(DEBUG_ARTEFACT, "get_artefact_for_caveID: no spyable artefact left in cave %d", caveID); } return artefactID; } db_result_next_row(result); artefactID = db_result_get_int(result, "artefactID"); return artefactID; }
static int artefact_loose_to_cave (db_t *database, struct Cave *cave) { db_result_t *result; dstring_t *query; int x, y; int minX, minY, maxX, maxY, rangeX, rangeY; /* number between -ALR <= n <= ALR */ x = (int) ((ARTEFACT_LOST_RANGE * 2 + 1) * drand()) - ARTEFACT_LOST_RANGE; y = (int) ((ARTEFACT_LOST_RANGE * 2 + 1) * drand()) - ARTEFACT_LOST_RANGE; x += cave->xpos; y += cave->ypos; /* these numbers may be out of range */ if (! map_get_bounds(database, &minX, &maxX, &minY, &maxY)) { return 0; } rangeX = maxX - minX +1; rangeY = maxY - minY +1; x = ( (x-minX+rangeX) % (rangeX) ) + minX; y = ( (y-minY+rangeY) % (rangeY) ) + minY; query = dstring_new("SELECT caveID FROM " DB_TABLE_CAVE " WHERE xCoord = %d AND yCoord = %d", x, y); debug(DEBUG_SQL, "%s", dstring_str(query)); result = db_query_dstring(database, query); return db_result_next_row(result) ? db_result_get_int(result, "caveID") : 0; }
/* * Retrieve monster table information for the given monster id. */ void get_monster_info (db_t *database, int monster_id, struct Monster *monster) { db_result_t *result = db_query(database, "SELECT * FROM Monster WHERE monsterID = %d", monster_id); if (!db_result_next_row(result)) throwf(SQL_EXCEPTION, "get_monster_info: monster %d not found", monster_id); monster->monster_id = monster_id; monster->name = db_result_get_string(result, "name"); monster->attack = db_result_get_int(result, "angriff"); monster->defense = db_result_get_int(result, "verteidigung"); monster->mental = db_result_get_int(result, "mental"); monster->strength = db_result_get_int(result, "koerperkraft"); monster->exp_value = db_result_get_int(result, "erfahrung"); monster->attributes = db_result_get_string(result, "eigenschaft"); }
/* * Retrieve relation table information for the given tribe and tribe_target. */ int get_relation_info (db_t *database, const char *tribe, const char *tribe_target, struct Relation *relation) { db_result_t *result = NULL; if (tribe && tribe_target) { debug(DEBUG_BATTLE, "get relation for tribes %s %s", tribe, tribe_target); result = db_query(database, "SELECT * FROM " DB_TABLE_RELATION " WHERE tribe = '%s' AND tribe_target = '%s'", tribe, tribe_target); } if (!result || !db_result_next_row(result)) { debug(DEBUG_BATTLE, "filling dummy relation"); relation->relation_id = 0; relation->tribe = tribe; relation->tribe_target = tribe_target; relation->relationType = RELATION_TYPE_NONE; /* FIXME these values should be read from relation types */ relation->attackerMultiplicator = 0.5; relation->defenderMultiplicator = 1.0; relation->attackerReceivesFame = 0; relation->defenderReceivesFame = 0; return 0; /* no relation entry */ } relation->relation_id = db_result_get_int(result, "relationID"); relation->tribe = tribe; relation->tribe_target = tribe_target; relation->relationType = db_result_get_int(result, "relationType"); relation->defenderMultiplicator = db_result_get_double(result, "defenderMultiplicator"); relation->attackerMultiplicator = db_result_get_double(result, "attackerMultiplicator"); relation->defenderReceivesFame = db_result_get_int(result, "defenderReceivesFame"); relation->attackerReceivesFame = db_result_get_int(result, "attackerReceivesFame"); return 1; }
static int map_get_bounds (db_t *database, int *minX, int *maxX, int *minY, int *maxY) { db_result_t *result = db_query(database, "SELECT MIN(xCoord) AS minX, " " MAX(xCoord) AS maxX, " " MIN(yCoord) AS minY, " " MAX(yCoord) AS maxY " "FROM Cave"); if (!db_result_next_row(result)) return 0; *minX = db_result_get_int(result, "minX"); *maxX = db_result_get_int(result, "maxX"); *minY = db_result_get_int(result, "minY"); *maxY = db_result_get_int(result, "maxY"); return 1; }
/* * Retrieve artefact for the given id. */ void get_artefact_by_id (db_t *database, int artefactID, struct Artefact *artefact) { db_result_t *result = db_query(database, "SELECT * FROM " DB_TABLE_ARTEFACT " WHERE artefactID = %d", artefactID); /* Bedingung: Artefakt muss vorhanden sein */ if (db_result_num_rows(result) != 1) throw(SQL_EXCEPTION, "get_artefact_by_id: no such artefactID"); db_result_next_row(result); artefact->artefactID = artefactID; artefact->artefactClassID = db_result_get_int(result, "artefactClassID"); artefact->caveID = db_result_get_int(result, "caveID"); artefact->initiated = db_result_get_int(result, "initiated"); }
/* * Retrieve the game object list from the result set. */ static void get_object_list (db_result_t *result, int list[], const struct GameObject *object[], int num) { int type; memset(list, 0, num * sizeof (int)); for (type = 0; type < num; ++type) list[type] = db_result_get_int(result, object[type]->dbFieldName); }
int dm_sievescript_rename(uint64_t user_idnr, char *scriptname, char *newname) { int active = 0; Connection_T c; ResultSet_T r; PreparedStatement_T s; volatile int t = FALSE; assert(scriptname); /* * According to the draft RFC, a script with the same * name as an existing script should *atomically* replace it. */ c = db_con_get(); TRY db_begin_transaction(c); s = db_stmt_prepare(c,"SELECT active FROM %ssievescripts WHERE owner_idnr = ? AND name = ?", DBPFX); db_stmt_set_u64(s,1, user_idnr); db_stmt_set_str(s,2, newname); r = db_stmt_query(s); if (db_result_next(r)) { active = db_result_get_int(r,0); db_con_clear(c); s = db_stmt_prepare(c, "DELETE FROM %ssievescripts WHERE owner_idnr = ? AND name = ?", DBPFX); db_stmt_set_u64(s, 1, user_idnr); db_stmt_set_str(s, 2, newname); db_stmt_exec(s); } db_con_clear(c); s = db_stmt_prepare(c, "UPDATE %ssievescripts SET name = ?, active = ? WHERE owner_idnr = ? AND name = ?", DBPFX); db_stmt_set_str(s, 1, newname); db_stmt_set_int(s, 2, active); db_stmt_set_u64(s, 3, user_idnr); db_stmt_set_str(s, 4, scriptname); db_stmt_exec(s); t = db_commit_transaction(c); CATCH(SQLException) LOG_SQLERROR; t = DM_EQUERY; db_rollback_transaction(c); FINALLY db_con_close(c); END_TRY; return t; }
/* * This function is called to update a unit's entry in the database. * The unit number is increased by quantity, result contains information * about which cave the units belong to and the unit's type and quantity. */ void unit_handler (db_t *database, db_result_t *result) { int objectID; int caveID; int quantity; debug(DEBUG_TICKER, "entering function unit_handler()"); /* get unit and cave id */ objectID = db_result_get_int(result, "unitID"); caveID = db_result_get_int(result, "caveID"); /* get unit quantity */ quantity = db_result_get_int(result, "quantity"); db_query(database, "UPDATE " DB_TABLE_CAVE " SET %s = %s + %d" " WHERE caveID = %d", unit_type[objectID]->dbFieldName, unit_type[objectID]->dbFieldName, quantity, caveID); debug(DEBUG_TICKER, "leaving function unit_handler()"); }
void db_getmailbox_permission(T M, Connection_T c) { ResultSet_T r; PreparedStatement_T stmt; g_return_if_fail(M->id); stmt = db_stmt_prepare(c, "SELECT permission FROM %smailboxes WHERE mailbox_idnr = ?", DBPFX); db_stmt_set_u64(stmt, 1, M->id); r = db_stmt_query(stmt); if (db_result_next(r)) M->permission = db_result_get_int(r, 0); }
/* * Retrieve player table information for the given player id. */ void get_player_info (db_t *database, int player_id, struct Player *player) { db_result_t *result = db_query(database, "SELECT * FROM " DB_TABLE_PLAYER " WHERE playerID = %d", player_id); if (!db_result_next_row(result)) throwf(SQL_EXCEPTION, "get_player_info: player %d not found", player_id); player->player_id = player_id; player->name = db_result_get_string(result, "name"); player->tribe = db_result_get_string(result, "tribe"); player->max_caves = db_result_get_int(result, "takeover_max_caves"); player->locale = db_result_get_string(result, "language"); player->locale_id = get_locale_id(player->locale); get_science_list(result, player->science); }
static int db_count_deleted(u64_t * rows) { C c; R r; volatile int t = TRUE; assert(rows != NULL); *rows = 0; c = db_con_get(); TRY r = db_query(c, "SELECT COUNT(*) FROM %smessages WHERE status = %d", DBPFX, MESSAGE_STATUS_DELETE); if (db_result_next(r)) *rows = db_result_get_int(r,0); CATCH(SQLException) LOG_SQLERROR; t = DM_EQUERY; FINALLY db_con_close(c); END_TRY; return t; }
static int db_deleted_count(u64_t * rows) { C c; R r; volatile int t = FALSE; assert(rows); *rows = 0; c = db_con_get(); r = db_query(c, "SELECT COUNT(*) FROM %smessages WHERE status=%d", DBPFX, MESSAGE_STATUS_PURGE); TRY if (db_result_next(r)) { *rows = db_result_get_int(r,0); t = TRUE; } CATCH(SQLException) LOG_SQLERROR; FINALLY db_con_close(c); END_TRY; return t; }
/* * Retrieve artefact_class for the given id. */ void get_artefact_class_by_id (db_t *database, int artefactClassID, struct Artefact_class *artefact_class) { db_result_t *result = db_query(database, "SELECT * FROM Artefact_class" " WHERE artefactClassID = %d", artefactClassID); /* Bedingung: Artefaktklasse muss vorhanden sein */ if (db_result_num_rows(result) != 1) throw(SQL_EXCEPTION, "get_artefact_class_by_id: no such artefactClassID"); db_result_next_row(result); artefact_class->artefactClassID = artefactClassID; artefact_class->name = db_result_get_string(result, "name"); artefact_class->resref = db_result_get_string(result, "resref"); artefact_class->description = db_result_get_string(result, "description"); artefact_class->description_initiated = db_result_get_string(result, "description_initiated"); artefact_class->initiationID = db_result_get_int(result, "initiationID"); get_effect_list(result, artefact_class->effect); }
int dm_sievescript_list(uint64_t user_idnr, GList **scriptlist) { Connection_T c; ResultSet_T r; volatile int t = FALSE; c = db_con_get(); TRY r = db_query(c,"SELECT name,active FROM %ssievescripts WHERE owner_idnr = %" PRIu64 "", DBPFX,user_idnr); while (db_result_next(r)) { sievescript_info *info = g_new0(sievescript_info,1); strncpy(info->name, db_result_get(r,0), sizeof(info->name)-1); info->active = db_result_get_int(r,1); *(GList **)scriptlist = g_list_prepend(*(GList **)scriptlist, info); } CATCH(SQLException) LOG_SQLERROR; t = DM_EQUERY; FINALLY db_con_close(c); END_TRY; return t; }
/* * This function is responsible for all the movement. * * @params database the function needs this link to the DB * @params result current movement event (from DB) */ void movement_handler (db_t *database, db_result_t *result) { int movementID; int target_caveID; int source_caveID; const char *speed_factor; time_t event_start; time_t event_end; const char *return_start; char return_end[TIMESTAMP_LEN]; struct Cave cave1; struct Cave cave2; struct Player player1; struct Player player2; struct Relation relation1; struct Relation relation2; int i; int units[MAX_UNIT]; int resources[MAX_RESOURCE]; int takeover_multiplier; int change_owner; int isFarming = 0; Battle *battle; dstring_t *ds; double spy_result; /* time related issues */ const float *battle_bonus; /* artefacts */ int artefact = 0; int artefact_def = 0; int artefact_id = 0; int lostTo = 0; int body_count = 0; int attacker_lose = 0; int defender_lose = 0; int defender_va_lose = 0; int war_points_attacker = 0; int war_points_defender = 0; int war_points_sender = 0; int war_points_show = 0; int takeover = 0; debug(DEBUG_TICKER, "entering function movement_handler()"); /* get movement id and target/source cave id */ movementID = db_result_get_int(result, "movementID"); target_caveID = db_result_get_int(result, "target_caveID"); source_caveID = db_result_get_int(result, "source_caveID"); speed_factor = db_result_get_string(result, "speedFactor"); /* get event_start and event_end */ event_start = db_result_get_gmtime(result, "start"); return_start = db_result_get_string(result, "end"); event_end = make_time_gm(return_start); make_timestamp_gm(return_end, event_end + (event_end - event_start)); /* get resources, units and artefact id */ get_resource_list(result, resources); get_unit_list(result, units); artefact = db_result_get_int(result, "artefactID"); /* TODO reduce number of queries */ get_cave_info(database, source_caveID, &cave1); get_cave_info(database, target_caveID, &cave2); if (cave1.player_id) get_player_info(database, cave1.player_id, &player1); else{ /* System */ memset(&player1, 0, sizeof player1); player1.tribe = ""; } if (cave2.player_id == cave1.player_id) player2 = player1; else if (cave2.player_id) get_player_info(database, cave2.player_id, &player2); else{ /* System */ memset(&player2, 0, sizeof player2); player2.tribe = ""; } debug(DEBUG_TICKER, "caveID = %d, movementID = %d", target_caveID, movementID); /**********************************************************************/ /*** THE INFAMOUS GIANT SWITCH ****************************************/ /**********************************************************************/ switch (movementID) { /**********************************************************************/ /*** ROHSTOFFE BRINGEN ************************************************/ /**********************************************************************/ case ROHSTOFFE_BRINGEN: /* record in takeover table */ ds = dstring_new("UPDATE " DB_TABLE_CAVE_TAKEOVER " SET "); for (i = 0; i < MAX_RESOURCE; ++i) dstring_append(ds, "%s%s = %s + %d", i > 0 ? "," : "", resource_type[i]->dbFieldName, resource_type[i]->dbFieldName, resources[i]); dstring_append(ds, " WHERE caveID = %d AND playerID = %d", target_caveID, cave1.player_id); db_query_dstring(database, ds); if(db_affected_rows(database)!=0){ takeover=1; } /* put resources into cave */ dstring_set(ds, "UPDATE " DB_TABLE_CAVE " SET "); for (i = 0; i < MAX_RESOURCE; ++i) dstring_append(ds, "%s%s = LEAST(%s + %d, %s)", i > 0 ? "," : "", resource_type[i]->dbFieldName, resource_type[i]->dbFieldName, (takeover==1)?resources[i] * TAKEOVER_RESOURCE_SAVE_PERCENTAGE / 100:resources[i], function_to_sql(resource_type[i]->maxLevel)); dstring_append(ds, " WHERE caveID = %d", target_caveID); db_query_dstring(database, ds); if (artefact > 0) put_artefact_into_cave(database, artefact, target_caveID); /* send all units back */ dstring_set(ds, "INSERT INTO Event_movement" " (caveID, target_caveID, source_caveID, movementID," " speedFactor, start, end"); for (i = 0; i < MAX_UNIT; ++i) dstring_append(ds, ",%s", unit_type[i]->dbFieldName); dstring_append(ds, ") VALUES (%d, %d, %d, %d, %s, '%s', '%s'", source_caveID, source_caveID, target_caveID, RUECKKEHR, speed_factor, return_start, return_end); for (i = 0; i < MAX_UNIT; ++i) dstring_append(ds, ",%d", units[i]); dstring_append(ds, ")"); db_query_dstring(database, ds); /* generate trade report and receipt for sender */ trade_report(database, &cave1, &player1, &cave2, &player2, resources, NULL, artefact); break; /**********************************************************************/ /*** EINHEITEN/ROHSTOFFE VERSCHIEBEN **********************************/ /**********************************************************************/ case VERSCHIEBEN: get_relation_info(database, player1.tribe, player2.tribe, &relation1); /*überprüfen ob sender und versender eine kriegsbeziehung haben */ if(!(isVerschiebenAllowed(database, &player1, &player2, &relation1) || isTakeoverableCave(database, target_caveID))){ //bewegung umdrehen// /* send remaining units back */ ds = dstring_new("INSERT INTO Event_movement" " (caveID, target_caveID, source_caveID, movementID," " speedFactor, start, end, artefactID"); for (i = 0; i < MAX_RESOURCE; ++i) dstring_append(ds, ",%s", resource_type[i]->dbFieldName); for (i = 0; i < MAX_UNIT; ++i) dstring_append(ds, ",%s", unit_type[i]->dbFieldName); dstring_append(ds, ") VALUES (%d, %d, %d, %d, %s, '%s', '%s', %d", source_caveID, source_caveID, target_caveID, RUECKKEHR, speed_factor, return_start, return_end, artefact); for (i = 0; i < MAX_RESOURCE; ++i) dstring_append(ds, ",%d", resources[i]); for (i = 0; i < MAX_UNIT; ++i) dstring_append(ds, ",%d", units[i]); dstring_append(ds, ")"); db_query_dstring(database, ds); break; } /* record in takeover table */ ds = dstring_new("UPDATE " DB_TABLE_CAVE_TAKEOVER " SET "); for (i = 0; i < MAX_RESOURCE; ++i) dstring_append(ds, "%s%s = %s + %d", i > 0 ? "," : "", resource_type[i]->dbFieldName, resource_type[i]->dbFieldName, resources[i]); dstring_append(ds, " WHERE caveID = %d AND playerID = %d", target_caveID, cave1.player_id); db_query_dstring(database, ds); if(db_affected_rows(database)!=0){ takeover=1; } /* put resources and units into cave */ dstring_set(ds, "UPDATE " DB_TABLE_CAVE " SET "); for (i = 0; i < MAX_RESOURCE; ++i) dstring_append(ds, "%s%s = LEAST(%s + %d, %s)", i > 0 ? "," : "", resource_type[i]->dbFieldName, resource_type[i]->dbFieldName, (takeover==1)?resources[i] * TAKEOVER_RESOURCE_SAVE_PERCENTAGE / 100:resources[i], function_to_sql(resource_type[i]->maxLevel)); for (i = 0; i < MAX_UNIT; ++i){ war_points_sender += ((struct Unit *)unit_type[i])->warpoints * units[i]; dstring_append(ds, ",%s = %s + %d", unit_type[i]->dbFieldName, unit_type[i]->dbFieldName, units[i]); } if(relation1.relationType == RELATION_TYPE_PRE_WAR || relation1.relationType == RELATION_TYPE_WAR){ war_points_update_verschieben(database, player1.tribe, player2.tribe, -1* war_points_sender); } dstring_append(ds, " WHERE caveID = %d", target_caveID); db_query_dstring(database, ds); if (artefact > 0) put_artefact_into_cave(database, artefact, target_caveID); /* generate trade report and receipt for sender */ trade_report(database, &cave1, &player1, &cave2, &player2, resources, units, artefact); break; /**********************************************************************/ /*** RUECKKEHR ********************************************************/ /**********************************************************************/ case RUECKKEHR: /* put resources into cave */ ds = dstring_new("UPDATE " DB_TABLE_CAVE " SET "); for (i = 0; i < MAX_RESOURCE; ++i) dstring_append(ds, "%s%s = LEAST(%s + %d, %s)", i > 0 ? "," : "", resource_type[i]->dbFieldName, resource_type[i]->dbFieldName, resources[i], function_to_sql(resource_type[i]->maxLevel)); for (i = 0; i < MAX_UNIT; ++i) dstring_append(ds, ",%s = %s + %d", unit_type[i]->dbFieldName, unit_type[i]->dbFieldName, units[i]); dstring_append(ds, " WHERE caveID = %d", target_caveID); db_query_dstring(database, ds); if (artefact > 0) put_artefact_into_cave(database, artefact, target_caveID); /* generate return report */ return_report(database, &cave1, &player1, &cave2, &player2, resources, units, artefact); break; /**********************************************************************/ /*** ANGREIFEN ********************************************************/ /**********************************************************************/ case ANGREIFEN: /* beginner protection active in target cave? */ if (cave_is_protected(&cave2)) { debug(DEBUG_BATTLE, "Is protected Cave"); /* send remaining units back */ ds = dstring_new("INSERT INTO Event_movement" " (caveID, target_caveID, source_caveID, movementID," " speedFactor, start, end, artefactID"); for (i = 0; i < MAX_RESOURCE; ++i) dstring_append(ds, ",%s", resource_type[i]->dbFieldName); for (i = 0; i < MAX_UNIT; ++i) dstring_append(ds, ",%s", unit_type[i]->dbFieldName); dstring_append(ds, ") VALUES (%d, %d, %d, %d, %s, '%s', '%s', %d", source_caveID, source_caveID, target_caveID, RUECKKEHR, speed_factor, return_start, return_end, artefact); for (i = 0; i < MAX_RESOURCE; ++i) dstring_append(ds, ",%d", resources[i]); for (i = 0; i < MAX_UNIT; ++i) dstring_append(ds, ",%d", units[i]); dstring_append(ds, ")"); db_query_dstring(database, ds); debug(DEBUG_BATTLE,"End Handle Protected Cave attack"); /* create and send reports */ protected_report(database, &cave1, &player1, &cave2, &player2); break; } /* get relations between the two players' tribes */ get_relation_info(database, player1.tribe, player2.tribe, &relation1); get_relation_info(database, player2.tribe, player1.tribe, &relation2); debug(DEBUG_BATTLE, "Relationtypes: %d and %d", relation1.relationType, relation2.relationType); battle = battle_create(1, 1); battle_bonus = get_battle_bonus(); debug(DEBUG_BATTLE, "entering prepare_battle"); /* prepare structs for battle, exceptions are uncaught! */ prepare_battle(database, battle, &player1, &player2, &cave1, &cave2, battle_bonus, 0, units, resources, &artefact, &artefact_def, &relation1, &relation2); /* calculate the fame */ /* Calculatin is diferent if the battle was just pure farming*/ isFarming = check_farming(database, cave2.artefacts, &player1, &player2, &relation1); if( relation1.relationType == RELATION_TYPE_WAR){ battle->isWar = 1; } /* calculate battle result */ calcBattleResult(battle, &cave2, 0); /* change artefact ownership */ debug(DEBUG_BATTLE, "entering change artefact"); after_battle_change_artefact_ownership( database, battle->winner, &artefact, &artefact_id, &artefact_def, target_caveID, &cave2, &lostTo); /* attackers artefact (if any) is stored in variable artefact, artefact_id is id of the artefact that changed owner (or 0) */ /* no relation -> attacker get negative fame*/ debug(DEBUG_BATTLE, "Relation Type %d",relation1.relationType); /* construct attacker update */ debug(DEBUG_BATTLE, "entering attacker update"); after_battle_attacker_update(database, player1.player_id, battle, source_caveID, target_caveID, speed_factor, return_start, return_end, artefact, &relation1); /* defender update: exception still uncaught (better leave) */ debug(DEBUG_BATTLE, "entering defender update"); after_battle_defender_update(database, player2.player_id, battle, target_caveID, &relation2); /* Farming update */ if(isFarming){ increaseFarming(database, player1.player_id); } /* reset DB_TABLE_CAVE_TAKEOVER */ ds = dstring_new("UPDATE " DB_TABLE_CAVE_TAKEOVER " SET status = 0"); for (i = 0; i < MAX_RESOURCE; ++i) dstring_append(ds, ",%s = 0", resource_type[i]->dbFieldName); dstring_append(ds, " WHERE caveID = %d AND playerID = %d", target_caveID, cave1.player_id); db_query_dstring(database, ds); /* cave takeover by battle */ if (battle->winner == FLAG_ATTACKER && ((struct Terrain *)terrain_type[cave2.terrain])->takeoverByCombat) { db_query(database, "UPDATE " DB_TABLE_CAVE " SET playerID = %d" " WHERE caveID = %d", cave1.player_id, target_caveID); db_query(database, "DELETE FROM Event_science WHERE caveID = %d", target_caveID); science_update_caves(database, cave1.player_id); } //bodycount calculate attacker_lose = bodycount_calculate(battle, FLAG_DEFENDER); defender_lose = bodycount_calculate(battle, FLAG_ATTACKER); defender_va_lose = bodycount_va_calculate(battle); bodycount_update( database, player1.player_id, defender_lose); bodycount_update( database, player2.player_id, attacker_lose); if(relation1.relationType == RELATION_TYPE_PRE_WAR || relation1.relationType == RELATION_TYPE_WAR){ war_points_show = 1; war_points_attacker = (defender_lose>10||defender_va_lose>5?war_points_calculate(battle,FLAG_ATTACKER):0); war_points_defender = (attacker_lose>10?war_points_calculate(battle,FLAG_DEFENDER):0); war_points_update(database, player1.tribe, player2.tribe, war_points_attacker, war_points_defender); } /* create and send reports */ battle_report(database, &cave1, &player1, &cave2, &player2, battle, artefact_id, lostTo, 0, 0, &relation1, &relation2, war_points_show, war_points_attacker, war_points_defender); break; /**********************************************************************/ /*** Spionieren *******************************************************/ /**********************************************************************/ case SPIONAGE: /* generate spy report */ spy_result = spy_report(database, &cave1, &player1, &cave2, &player2, resources, units, artefact); if (spy_result == 1) { /* send all units back */ ds = dstring_new("INSERT INTO Event_movement" " (caveID, target_caveID, source_caveID, movementID," " speedFactor, start, end, artefactID"); for (i = 0; i < MAX_RESOURCE; ++i) dstring_append(ds, ",%s", resource_type[i]->dbFieldName); for (i = 0; i < MAX_UNIT; ++i) dstring_append(ds, ",%s", unit_type[i]->dbFieldName); dstring_append(ds, ") VALUES (%d, %d, %d, %d, %s, '%s', '%s', %d", source_caveID, source_caveID, target_caveID, RUECKKEHR, speed_factor, return_start, return_end, artefact); for (i = 0; i < MAX_RESOURCE; ++i) dstring_append(ds, ",%d", resources[i]); for (i = 0; i < MAX_UNIT; ++i) dstring_append(ds, ",%d", units[i]); dstring_append(ds, ")"); db_query_dstring(database, ds); } else { /* send remaining units back */ int count = 0; ds = dstring_new("INSERT INTO Event_movement" " (caveID, target_caveID, source_caveID, movementID," " speedFactor, start, end, artefactID"); for (i = 0; i < MAX_UNIT; ++i) dstring_append(ds, ",%s", unit_type[i]->dbFieldName); dstring_append(ds, ") VALUES (%d, %d, %d, %d, %s, '%s', '%s', %d", source_caveID, source_caveID, target_caveID, RUECKKEHR, speed_factor, return_start, return_end, artefact); for (i = 0; i < MAX_UNIT; ++i) { int num = units[i] * spy_result; dstring_append(ds, ",%d", num); count += num; body_count += units[i] - num; } dstring_append(ds, ")"); if (count) db_query_dstring(database, ds); /* put resources into cave */ ds = dstring_new("UPDATE " DB_TABLE_CAVE " SET "); for (i = 0; i < MAX_RESOURCE; ++i) dstring_append(ds, "%s%s = LEAST(%s + %d, %s)", i > 0 ? "," : "", resource_type[i]->dbFieldName, resource_type[i]->dbFieldName, resources[i], function_to_sql(resource_type[i]->maxLevel)); dstring_append(ds, " WHERE caveID = %d", target_caveID); db_query_dstring(database, ds); if (artefact > 0) put_artefact_into_cave(database, artefact, target_caveID); } bodycount_update(database, player2.player_id, body_count); break; /**********************************************************************/ /*** UEBERNEHMEN ******************************************************/ /**********************************************************************/ case TAKEOVER: /* secure or protected target gave? */ if (cave2.secure || cave_is_protected(&cave2)) { /* send remaining units back */ ds = dstring_new("INSERT INTO Event_movement" " (caveID, target_caveID, source_caveID, movementID," " speedFactor, start, end, artefactID"); for (i = 0; i < MAX_RESOURCE; ++i) dstring_append(ds, ",%s", resource_type[i]->dbFieldName); for (i = 0; i < MAX_UNIT; ++i) dstring_append(ds, ",%s", unit_type[i]->dbFieldName); dstring_append(ds, ") VALUES (%d, %d, %d, %d, %s, '%s', '%s', %d", source_caveID, source_caveID, target_caveID, RUECKKEHR, speed_factor, return_start, return_end, artefact); for (i = 0; i < MAX_RESOURCE; ++i) dstring_append(ds, ",%d", resources[i]); for (i = 0; i < MAX_UNIT; ++i) dstring_append(ds, ",%d", units[i]); dstring_append(ds, ")"); db_query_dstring(database, ds); /* create and send reports */ /* FIXME use different message in report (protected -> secure) */ protected_report(database, &cave1, &player1, &cave2, &player2); break; } get_relation_info(database, player1.tribe, player2.tribe, &relation1); get_relation_info(database, player2.tribe, player1.tribe, &relation2); battle = battle_create(1, 1); battle_bonus = get_battle_bonus(); takeover_multiplier = get_takeover_multiplier(&cave2); /* prepare structs for battle, exceptions are uncaught! */ prepare_battle(database, battle, &player1, &player2, &cave1, &cave2, battle_bonus, takeover_multiplier, units, resources, &artefact, &artefact_def, &relation1, &relation2); /* calculate battle result */ /*bei ner übernahme kein resi klau möglich*/ calcBattleResult(battle, &cave2, 1); /* change artefact ownership */ after_battle_change_artefact_ownership( database, battle->winner, &artefact, &artefact_id, &artefact_def, target_caveID, &cave2, &lostTo); /* attackers artefact (if any) is stored in variable artefact, artefact_id is id of the artefact that changed owner (or 0) */ /* defender update: exception still uncaught (better leave) */ after_battle_defender_update(database, player2.player_id, battle, target_caveID, &relation2); int war1 = get_tribe_at_war(database,player1.tribe); int war2 = get_tribe_at_war(database,player2.tribe); /* attacker won: put survivors into cave, change owner * attacker lost: send back survivors */ change_owner = battle->winner == FLAG_ATTACKER && cave2.player_id != PLAYER_SYSTEM && player1.max_caves > get_number_of_caves(database, player1.player_id) && ((relation1.relationType == RELATION_TYPE_WAR && relation2.relationType == RELATION_TYPE_WAR) || (!war1 && !war2) || (strcasecmp(player1.tribe, player2.tribe) == 0)); // Spieler im selben stamm //bodycount calculate attacker_lose = bodycount_calculate(battle, FLAG_DEFENDER); defender_lose = bodycount_calculate(battle, FLAG_ATTACKER); defender_va_lose = bodycount_va_calculate(battle); bodycount_update( database, player1.player_id, defender_lose); bodycount_update( database, player2.player_id, attacker_lose); if(relation1.relationType == RELATION_TYPE_PRE_WAR || relation1.relationType == RELATION_TYPE_WAR){ war_points_show = 1; war_points_attacker = (defender_lose>10||defender_va_lose>5?war_points_calculate(battle,FLAG_ATTACKER):0); war_points_defender = (attacker_lose>10?war_points_calculate(battle,FLAG_DEFENDER):0); } if (change_owner){ debug(DEBUG_TAKEOVER, "change owner of cave %d to new owner %d", target_caveID, cave1.player_id); takeover_cave(database, target_caveID, cave1.player_id,return_start); after_takeover_attacker_update(database, player1.player_id, battle, target_caveID, artefact, &relation1); if(relation1.relationType == RELATION_TYPE_PRE_WAR || relation1.relationType == RELATION_TYPE_WAR){ war_points_attacker += WAR_POINTS_FOR_TAKEOVER; } } else { /* send survivors back */ debug(DEBUG_TAKEOVER, "send back attacker's suvivors"); after_battle_attacker_update(database, player1.player_id, battle, source_caveID, target_caveID, speed_factor, return_start, return_end, artefact, &relation1); } if(relation1.relationType == RELATION_TYPE_PRE_WAR || relation1.relationType == RELATION_TYPE_WAR){ war_points_update(database, player1.tribe, player2.tribe, war_points_attacker, war_points_defender); } /* create and send reports */ battle_report(database, &cave1, &player1, &cave2, &player2, battle, artefact_id, lostTo, change_owner, 1 + takeover_multiplier, &relation1, &relation2,war_points_show, war_points_attacker, war_points_defender); //bodycount calculate bodycount_update( database, player1.player_id, defender_lose); bodycount_update( database, player2.player_id, attacker_lose); break; default: throw(BAD_ARGUMENT_EXCEPTION, "movement_handler: unknown movementID"); } /**********************************************************************/ /*** END OF THE INFAMOUS GIANT SWITCH *********************************/ /**********************************************************************/ debug(DEBUG_TICKER, "leaving function movement_handler()"); }
static void db_getmailbox_info(T M, Connection_T c) { /* query mailbox for LIST results */ ResultSet_T r; char *mbxname, *name, *pattern; struct mailbox_match *mailbox_like = NULL; GString *fqname, *qs; int i=0, prml; PreparedStatement_T stmt; stmt = db_stmt_prepare(c, "SELECT " "CASE WHEN user_id IS NULL THEN 0 ELSE 1 END, " // subscription "owner_idnr, name, no_select, no_inferiors " "FROM %smailboxes b LEFT OUTER JOIN %ssubscription s ON " "b.mailbox_idnr = s.mailbox_id WHERE b.mailbox_idnr = ?", DBPFX, DBPFX); db_stmt_set_u64(stmt, 1, M->id); r = db_stmt_query(stmt); if (db_result_next(r)) { /* subsciption */ M->is_subscribed = db_result_get_bool(r, i++); /* owner_idnr */ M->owner_id = db_result_get_u64(r, i++); /* name */ name = g_strdup(db_result_get(r,i++)); if (MATCH(name, "INBOX")) { M->is_inbox = TRUE; M->is_subscribed = TRUE; } mbxname = mailbox_add_namespace(name, M->owner_id, M->owner_id); fqname = g_string_new(mbxname); fqname = g_string_truncate(fqname,IMAP_MAX_MAILBOX_NAMELEN); MailboxState_setName(M, fqname->str); g_string_free(fqname,TRUE); g_free(mbxname); /* no_select */ M->no_select=db_result_get_bool(r,i++); /* no_inferior */ M->no_inferiors=db_result_get_bool(r,i++); /* no_children search pattern*/ pattern = g_strdup_printf("%s/%%", name); mailbox_like = mailbox_match_new(pattern); g_free(pattern); g_free(name); } db_con_clear(c); qs = g_string_new(""); g_string_printf(qs, "SELECT COUNT(*) AS nr_children FROM %smailboxes WHERE owner_idnr = ? ", DBPFX); if (mailbox_like && mailbox_like->insensitive) g_string_append_printf(qs, "AND name %s ? ", db_get_sql(SQL_INSENSITIVE_LIKE)); if (mailbox_like && mailbox_like->sensitive) g_string_append_printf(qs, "AND name %s ? ", db_get_sql(SQL_SENSITIVE_LIKE)); stmt = db_stmt_prepare(c, qs->str); prml = 1; db_stmt_set_u64(stmt, prml++, M->owner_id); if (mailbox_like && mailbox_like->insensitive) db_stmt_set_str(stmt, prml++, mailbox_like->insensitive); if (mailbox_like && mailbox_like->sensitive) db_stmt_set_str(stmt, prml++, mailbox_like->sensitive); r = db_stmt_query(stmt); if (db_result_next(r)) { int nr_children = db_result_get_int(r,0); M->no_children=nr_children ? 0 : 1; } else { M->no_children=1; } mailbox_match_free(mailbox_like); g_string_free(qs, TRUE); }
static T state_load_messages(T M, Connection_T c) { unsigned nrows = 0, i = 0, j; const char *query_result, *keyword; MessageInfo *result; GTree *msginfo; uint64_t *uid, id = 0; ResultSet_T r; PreparedStatement_T stmt; Field_T frag; INIT_QUERY; date2char_str("internal_date", &frag); snprintf(query, DEF_QUERYSIZE-1, "SELECT seen_flag, answered_flag, deleted_flag, flagged_flag, " "draft_flag, recent_flag, %s, rfcsize, seq, message_idnr, status FROM %smessages m " "LEFT JOIN %sphysmessage p ON p.id = m.physmessage_id " "WHERE m.mailbox_idnr = ? AND m.status IN (%d,%d,%d) ORDER BY message_idnr ASC", frag, DBPFX, DBPFX, MESSAGE_STATUS_NEW, MESSAGE_STATUS_SEEN, MESSAGE_STATUS_DELETE); msginfo = g_tree_new_full((GCompareDataFunc)ucmpdata, NULL,(GDestroyNotify)g_free,(GDestroyNotify)MessageInfo_free); stmt = db_stmt_prepare(c, query); db_stmt_set_u64(stmt, 1, M->id); r = db_stmt_query(stmt); i = 0; while (db_result_next(r)) { i++; id = db_result_get_u64(r, IMAP_NFLAGS + 3); uid = g_new0(uint64_t,1); *uid = id; result = g_new0(MessageInfo,1); /* id */ result->uid = id; /* mailbox_id */ result->mailbox_id = M->id; /* flags */ for (j = 0; j < IMAP_NFLAGS; j++) result->flags[j] = db_result_get_bool(r,j); /* internal date */ query_result = db_result_get(r,IMAP_NFLAGS); strncpy(result->internaldate, (query_result) ? query_result : "01-Jan-1970 00:00:01 +0100", IMAP_INTERNALDATE_LEN-1); /* rfcsize */ result->rfcsize = db_result_get_u64(r,IMAP_NFLAGS + 1); /* modseq */ result->seq = db_result_get_u64(r,IMAP_NFLAGS + 2); /* status */ result->status = db_result_get_int(r, IMAP_NFLAGS + 4); g_tree_insert(msginfo, uid, result); } if (! i) { // empty mailbox MailboxState_setMsginfo(M, msginfo); return M; } db_con_clear(c); memset(query,0,sizeof(query)); snprintf(query, DEF_QUERYSIZE-1, "SELECT k.message_idnr, keyword FROM %skeywords k " "LEFT JOIN %smessages m ON k.message_idnr=m.message_idnr " "LEFT JOIN %smailboxes b ON m.mailbox_idnr=b.mailbox_idnr " "WHERE b.mailbox_idnr = ? AND m.status IN (%d,%d)", DBPFX, DBPFX, DBPFX, MESSAGE_STATUS_NEW, MESSAGE_STATUS_SEEN); nrows = 0; stmt = db_stmt_prepare(c, query); db_stmt_set_u64(stmt, 1, M->id); r = db_stmt_query(stmt); while (db_result_next(r)) { nrows++; id = db_result_get_u64(r,0); keyword = db_result_get(r,1); if ((result = g_tree_lookup(msginfo, &id)) != NULL) result->keywords = g_list_append(result->keywords, g_strdup(keyword)); } if (! nrows) TRACE(TRACE_DEBUG, "no keywords"); MailboxState_setMsginfo(M, msginfo); return M; }
/* * merge_artefacts_general * Throws exception if needed conditions are not as they should have been. */ int merge_artefacts_general (db_t *database, const struct Artefact *key_artefact, struct Artefact *lock_artefact, struct Artefact *result_artefact) { db_result_t *result; db_result_t *temp_result; int row; dstring_t *ds; /* now get possible merging formulas */ ds = dstring_new("SELECT * FROM Artefact_merge_general " "WHERE keyClassID = %d", key_artefact->artefactClassID); result = db_query_dstring(database, ds); debug(DEBUG_ARTEFACT, "merge_artefact_general: %s", dstring_str(ds)); /* check for a suitable merging */ while ((row = db_result_next_row(result))) { /* special rules: * * lockClassID = 0 * no lock artefact needed * * keyClassID = lockClassID * unlocks if at least one other initiated artefact * of the same class exists * * resultClassID = 0 * key artefact and one present instance of the lockClass vanish */ /* lock artefact */ lock_artefact->artefactClassID = db_result_get_int(result, "lockClassID"); if (lock_artefact->artefactClassID == 0) break; /* implicit checks: * - lock artefact has to be different from the key artefact * - lock artefact has to be in the same cave as the key artefact * - lock artefact has to be initiated * - lock artefact has be of the specified class */ ds = dstring_new("SELECT artefactID FROM " DB_TABLE_ARTEFACT " WHERE artefactID != %d" " AND artefactClassID = %d" " AND caveID = %d" " AND initiated = %d", key_artefact->artefactID, lock_artefact->artefactClassID, key_artefact->caveID, ARTEFACT_INITIATED); temp_result = db_query_dstring(database, ds); debug(DEBUG_ARTEFACT, "merge_artefact_general: %s", dstring_str(ds)); /* is there a suitable lock artefact? */ if (db_result_next_row(temp_result)) { lock_artefact->artefactID = db_result_get_int(temp_result, "artefactID"); lock_artefact->caveID = key_artefact->caveID; lock_artefact->initiated = ARTEFACT_INITIATED; break; } } if (row) { /* result artefact */ result_artefact->artefactClassID = db_result_get_int(result, "resultClassID"); if (result_artefact->artefactClassID != 0) result_artefact->artefactID = new_artefact(database, result_artefact->artefactClassID); /* now merge them */ merge_artefacts(database, key_artefact->caveID, key_artefact->artefactID, lock_artefact->artefactID, result_artefact->artefactID); return 1; } return 0; }
/* * merge_artefacts_special * Throws exception if needed conditions are not as they should have been. */ int merge_artefacts_special (db_t *database, const struct Artefact *key_artefact, struct Artefact *lock_artefact, struct Artefact *result_artefact) { db_result_t *result; db_result_t *temp_result; int row; dstring_t *ds; /* get merging formulas */ ds = dstring_new("SELECT * FROM Artefact_merge_special " "WHERE keyID = %d", key_artefact->artefactID); result = db_query_dstring(database, ds); debug(DEBUG_ARTEFACT, "merge_artefact_special: %s", dstring_str(ds)); /* check for a suitable merging formula */ while ((row = db_result_next_row(result))) { /* some special cases: * * lockID == 0 || keyID == lockID * no lock artefact needed; key artefact transforms directly * * resultID == 0 * key and lock artefacts just vanish */ /* lock artefact */ lock_artefact->artefactID = db_result_get_int(result, "lockID"); /* special cases: lockID == 0 || keyID == lockID (no lock required) */ if (lock_artefact->artefactID == 0 || lock_artefact->artefactID == key_artefact->artefactID) break; /* get lock_artefact */ /* throws exception, if that artefact is missing */ get_artefact_by_id(database, lock_artefact->artefactID, lock_artefact); /* check: key and lock have to be in the same cave and initiated */ if (lock_artefact->caveID == key_artefact->caveID && lock_artefact->initiated == ARTEFACT_INITIATED) break; } if (row) { /* result artefact */ result_artefact->artefactID = db_result_get_int(result, "resultID"); /* special case: resultID == 0 */ if (result_artefact->artefactID != 0) { /* get result_artefact */ /* throws exception, if that artefact is missing */ get_artefact_by_id(database, result_artefact->artefactID, result_artefact); /* check: result_artefact must not be in any cave */ if (result_artefact->caveID != 0) throwf(BAD_ARGUMENT_EXCEPTION, "merge_artefacts_special: result artefact %d is in cave %d", result_artefact->artefactID, result_artefact->caveID); /* result_artefact must not be in any movement */ temp_result = db_query(database, "SELECT * FROM Event_movement" " WHERE artefactID = %d", result_artefact->artefactID); if (db_result_num_rows(temp_result) != 0) throwf(BAD_ARGUMENT_EXCEPTION, "merge_artefacts_special: result artefact %d is moving", result_artefact->artefactID); /* check: result_artefact has to be uninitiated */ /* XXX can this ever happen (it is not in a cave)? */ if (result_artefact->initiated != ARTEFACT_UNINITIATED) uninitiate_artefact(database, result_artefact->artefactID); } /* now merge them */ merge_artefacts(database, key_artefact->caveID, key_artefact->artefactID, lock_artefact->artefactID, result_artefact->artefactID); return 1; } return 0; }