<commit_before><?php declare(strict_types=1);

/**
 * Defines enhanced weapon sale events for weapon shops.
 */
class SmrEnhancedWeaponEvent {

	protected const GRACE_PERIOD = 3600; // 1 hour
	protected const DURATION = 21600; // 6 hours

	protected int $gameID;
	protected int $sectorID;
	protected int $locationTypeID;
	protected int $expires;
	protected SmrWeapon $weapon;

	/**
	 * Return all the valid events for the given location in a sector.
	 */
	public static function getShopEvents(int $gameID, int $sectorID, int $locationID): array {
		$events = [];
		$db = Smr\Database::getInstance();
		$dbResult = $db->read('SELECT * FROM location_sells_special WHERE sector_id = ' . $db->escapeNumber($sectorID) . ' AND location_type_id = ' . $db->escapeNumber($locationID) . ' AND game_id = ' . $db->escapeNumber($gameID) . ' AND expires > ' . $db->escapeNumber(Smr\Epoch::time()));
		foreach ($dbResult->records() as $dbRecord) {
			$events[] = self::getEventFromDatabase($dbRecord);
		}
		return $events;
	}

	/**
	 * Get the most recent event.
	 *
	 * This function also does the work of cleaning up expired events and
	 * creating new ones when necessary.
	 */
	public static function getLatestEvent(int $gameID): self {
		// First, remove any expired events from the database
		$db = Smr\Database::getInstance();
		$db->write('DELETE FROM location_sells_special WHERE expires < ' . $db->escapeNumber(Smr\Epoch::time()));

		// Next, check if an existing event can be advertised
		$db = Smr\Database::getInstance();
		$dbResult = $db->read('SELECT * FROM location_sells_special WHERE game_id = ' . $db->escapeNumber($gameID) . ' ORDER BY expires DESC LIMIT 1');
		if ($dbResult->hasRecord()) {
			$event = self::getEventFromDatabase($dbResult->record());
			// Don't advertise if the event expires within one GRACE_PERIOD
			if (Smr\Epoch::time() < $event->getExpireTime() - self::GRACE_PERIOD) {
				return $event;
			}
		}

		// Otherwise, create a new event
		return self::createEvent($gameID);
	}

	/**
	 * Create a new event.
	 *
	 * Events are generated randomly across all weapon types available in the
	 * game, and then randomly across locations that offer that weapon type.
	 */
	private static function createEvent(int $gameID): self {
		// First, randomly select a weapon type to enhance
		$weaponTypeID = array_rand(SmrWeaponType::getAllSoldWeaponTypes($gameID));

		$db = Smr\Database::getInstance();
		$dbResult = $db->read('SELECT location_type_id, sector_id FROM location JOIN location_sells_weapons USING (location_type_id) WHERE game_id = ' . $db->escapeNumber($gameID) . ' AND weapon_type_id = ' . $db->escapeNumber($weaponTypeID) . ' ORDER BY RAND() LIMIT 1');
		$dbRecord = $dbResult->record();
		$locationTypeID = $dbRecord->getInt('location_type_id');
		$sectorID = $dbRecord->getInt('sector_id');

		$expires = Smr\Epoch::time() + self::DURATION;

		// Determine which bonuses the weapon should have
		$random = rand(1, 100);
		if ($random <= 40) {
			$bonusAccuracy = false;
			$bonusDamage = true;
		} elseif ($random <= 80) {
			$bonusAccuracy = true;
			$bonusDamage = false;
		} else {
			$bonusAccuracy = true;
			$bonusDamage = true;
		}

		$db->insert('location_sells_special', [
			'game_id' => $db->escapeNumber($gameID),
			'sector_id' => $db->escapeNumber($sectorID),
			'location_type_id' => $db->escapeNumber($locationTypeID),
			'weapon_type_id' => $db->escapeNumber($weaponTypeID),
			'expires' => $db->escapeNumber($expires),
			'bonus_accuracy' => $db->escapeBoolean($bonusAccuracy),
			'bonus_damage' => $db->escapeBoolean($bonusDamage),
		]);

		return new self($gameID, $weaponTypeID, $locationTypeID, $sectorID, $expires, $bonusAccuracy, $bonusDamage);
	}
<commit_msg>SmrEnhancedWeaponEvent: handle unlikely duplicates<commit_after><?php declare(strict_types=1);

/**
 * Defines enhanced weapon sale events for weapon shops.
 */
class SmrEnhancedWeaponEvent {

	protected const GRACE_PERIOD = 3600; // 1 hour
	protected const DURATION = 21600; // 6 hours

	protected int $gameID;
	protected int $sectorID;
	protected int $locationTypeID;
	protected int $expires;
	protected SmrWeapon $weapon;

	/**
	 * Return all the valid events for the given location in a sector.
	 */
	public static function getShopEvents(int $gameID, int $sectorID, int $locationID): array {
		$events = [];
		$db = Smr\Database::getInstance();
		$dbResult = $db->read('SELECT * FROM location_sells_special WHERE sector_id = ' . $db->escapeNumber($sectorID) . ' AND location_type_id = ' . $db->escapeNumber($locationID) . ' AND game_id = ' . $db->escapeNumber($gameID) . ' AND expires > ' . $db->escapeNumber(Smr\Epoch::time()));
		foreach ($dbResult->records() as $dbRecord) {
			$events[] = self::getEventFromDatabase($dbRecord);
		}
		return $events;
	}

	/**
	 * Get the most recent event.
	 *
	 * This function also does the work of cleaning up expired events and
	 * creating new ones when necessary.
	 */
	public static function getLatestEvent(int $gameID): self {
		// First, remove any expired events from the database
		$db = Smr\Database::getInstance();
		$db->write('DELETE FROM location_sells_special WHERE expires < ' . $db->escapeNumber(Smr\Epoch::time()));

		// Next, check if an existing event can be advertised
		$db = Smr\Database::getInstance();
		$dbResult = $db->read('SELECT * FROM location_sells_special WHERE game_id = ' . $db->escapeNumber($gameID) . ' ORDER BY expires DESC LIMIT 1');
		if ($dbResult->hasRecord()) {
			$event = self::getEventFromDatabase($dbResult->record());
			// Don't advertise if the event expires within one GRACE_PERIOD
			if (Smr\Epoch::time() < $event->getExpireTime() - self::GRACE_PERIOD) {
				return $event;
			}
		}

		// Otherwise, create a new event
		return self::createEvent($gameID);
	}

	/**
	 * Create a new event.
	 *
	 * Events are generated randomly across all weapon types available in the
	 * game, and then randomly across locations that offer that weapon type.
	 */
	private static function createEvent(int $gameID): self {
		// First, randomly select a weapon type to enhance
		$weaponTypeID = array_rand(SmrWeaponType::getAllSoldWeaponTypes($gameID));

		$db = Smr\Database::getInstance();
		$dbResult = $db->read('SELECT location_type_id, sector_id FROM location JOIN location_sells_weapons USING (location_type_id) WHERE game_id = ' . $db->escapeNumber($gameID) . ' AND weapon_type_id = ' . $db->escapeNumber($weaponTypeID) . ' ORDER BY RAND() LIMIT 1');
		$dbRecord = $dbResult->record();
		$locationTypeID = $dbRecord->getInt('location_type_id');
		$sectorID = $dbRecord->getInt('sector_id');

		$expires = Smr\Epoch::time() + self::DURATION;

		// Determine which bonuses the weapon should have
		$random = rand(1, 100);
		if ($random <= 40) {
			$bonusAccuracy = false;
			$bonusDamage = true;
		} elseif ($random <= 80) {
			$bonusAccuracy = true;
			$bonusDamage = false;
		} else {
			$bonusAccuracy = true;
			$bonusDamage = true;
		}

		// We replace instead of insert in the very unlikely case that we have
		// selected the same configuration twice in a row.
		$db->replace('location_sells_special', [
			'game_id' => $db->escapeNumber($gameID),
			'sector_id' => $db->escapeNumber($sectorID),
			'location_type_id' => $db->escapeNumber($locationTypeID),
			'weapon_type_id' => $db->escapeNumber($weaponTypeID),
			'expires' => $db->escapeNumber($expires),
			'bonus_accuracy' => $db->escapeBoolean($bonusAccuracy),
			'bonus_damage' => $db->escapeBoolean($bonusDamage),
		]);

		return new self($gameID, $weaponTypeID, $locationTypeID, $sectorID, $expires, $bonusAccuracy, $bonusDamage);
	}

{'fraction_non_alphanumeric': 0.14225611359453064, 'fraction_numerical': 0.00578490665264265, 'mean_word_length': 4.372175141242938, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 73, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3095335', 'n_tokens_mistral': 2704, 'n_tokens_neox': 2427, 'n_words': 642}