/** * Creates a new local user in the application data base. * * @param WebSoccer $websoccer Application context. * @param DbConnection $db DB Connection. * @param string $nick User name of new user. Optional if e-mail address is provided. Must be unique in local data base. Case sensitive. * @param string $email E-mail address of new user. Optional if nick is provided. Must be unique in local data base. Case insensitive (will be stored with lower letters). * @throws Exception if both nick and e-mail are blank, or if nick name or e-mail address is already in use. Messages are not internationalized. Method assumes appropriate checks before calling it. * @return int ID of newly created user. */ public static function createLocalUser(WebSoccer $websoccer, DbConnection $db, $nick = null, $email = null) { $username = trim($nick); $emailAddress = strtolower(trim($email)); // check if either nick or e-mail is provided. If not, it most probably is a wrong API call, // hence message is not required to be translated. if (!strlen($username) && !strlen($emailAddress)) { throw new Exception("UsersDataService::createBlankUser(): Either user name or e-mail must be provided in order to create a new internal user."); } // verify that there is not already such a user. If so, the calling function is wrongly implemented, hence // no translation of message. if (strlen($username) && self::getUserIdByNick($websoccer, $db, $username) > 0) { throw new Exception("Nick name is already in use."); } if (strlen($emailAddress) && self::getUserIdByEmail($websoccer, $db, $emailAddress) > 0) { throw new Exception("E-Mail address is already in use."); } // creates user. $i18n = I18n::getInstance($websoccer->getConfig("supported_languages")); $columns = array("nick" => $username, "email" => $emailAddress, "status" => "1", "datum_anmeldung" => $websoccer->getNowAsTimestamp(), "lang" => $i18n->getCurrentLanguage()); if ($websoccer->getConfig("premium_initial_credit")) { $columns["premium_balance"] = $websoccer->getConfig("premium_initial_credit"); } $db->queryInsert($columns, $websoccer->getConfig("db_prefix") . "_user"); // provide ID of created user. if (strlen($username)) { $userId = self::getUserIdByNick($websoccer, $db, $username); } else { $userId = self::getUserIdByEmail($websoccer, $db, $emailAddress); } // trigger plug-ins $event = new UserRegisteredEvent($websoccer, $db, I18n::getInstance($websoccer->getConfig("supported_languages")), $userId, $username, $emailAddress); PluginMediator::dispatchEvent($event); return $userId; }
/** * Notifies listeners about the specified event. * * @param AbstractEvent $event event instance holding data for listeners. * @throws Exception if the configured listener function does not exist or if this function throws an Exception. */ public static function dispatchEvent(AbstractEvent $event) { if (self::$_eventlistenerConfigs == null) { include CONFIGCACHE_EVENTS; if (isset($eventlistener)) { self::$_eventlistenerConfigs = $eventlistener; } else { self::$_eventlistenerConfigs = array(); } } // any event listener configured? if (!count(self::$_eventlistenerConfigs)) { return; } // get available configurations for this event. $eventName = get_class($event); if (!isset(self::$_eventlistenerConfigs[$eventName])) { return; } // call listeners $eventListeners = self::$_eventlistenerConfigs[$eventName]; foreach ($eventListeners as $listenerConfigStr) { $listenerConfig = json_decode($listenerConfigStr, TRUE); if (method_exists($listenerConfig['class'], $listenerConfig['method'])) { call_user_func($listenerConfig['class'] . '::' . $listenerConfig['method'], $event); } else { throw new Exception('Configured event listener must have function: ' . $listenerConfig['class'] . '::' . $listenerConfig['method']); } } }
private function createYouthPlayer($clubId, $scout, $country) { $firstName = $this->getItemFromFile(NAMES_DIRECTORY . "/" . $country . "/firstnames.txt"); $lastName = $this->getItemFromFile(NAMES_DIRECTORY . "/" . $country . "/lastnames.txt"); // strength computation (always compute since plug-ins might override scouting-success-flag) $minStrength = (int) $this->_websoccer->getConfig("youth_scouting_min_strength"); $maxStrength = (int) $this->_websoccer->getConfig("youth_scouting_max_strength"); $scoutFactor = $scout["expertise"] / 100; $strength = $minStrength + round(($maxStrength - $minStrength) * $scoutFactor); // consider random deviation $deviation = (int) $this->_websoccer->getConfig("youth_scouting_standard_deviation"); $strength = $strength + SimulationHelper::getMagicNumber(0 - $deviation, $deviation); $strength = max($minStrength, min($maxStrength, $strength)); // make sure that condigured boundaries are not violated // determine position if ($scout["speciality"] == "Torwart") { $positionProbabilities = array("Torwart" => 40, "Abwehr" => 30, "Mittelfeld" => 25, "Sturm" => 5); } elseif ($scout["speciality"] == "Abwehr") { $positionProbabilities = array("Torwart" => 10, "Abwehr" => 50, "Mittelfeld" => 30, "Sturm" => 10); } elseif ($scout["speciality"] == "Mittelfeld") { $positionProbabilities = array("Torwart" => 10, "Abwehr" => 15, "Mittelfeld" => 60, "Sturm" => 15); } elseif ($scout["speciality"] == "Sturm") { $positionProbabilities = array("Torwart" => 5, "Abwehr" => 15, "Mittelfeld" => 40, "Sturm" => 40); } else { $positionProbabilities = array("Torwart" => 15, "Abwehr" => 30, "Mittelfeld" => 35, "Sturm" => 20); } $position = SimulationHelper::selectItemFromProbabilities($positionProbabilities); $minAge = $this->_websoccer->getConfig("youth_scouting_min_age"); $maxAge = $this->_websoccer->getConfig("youth_min_age_professional"); $age = $minAge + SimulationHelper::getMagicNumber(0, abs($maxAge - $minAge)); // create player $this->_db->queryInsert(array("team_id" => $clubId, "firstname" => $firstName, "lastname" => $lastName, "age" => $age, "position" => $position, "nation" => $country, "strength" => $strength), $this->_websoccer->getConfig("db_prefix") . "_youthplayer"); // trigger event for plug-ins $event = new YouthPlayerScoutedEvent($this->_websoccer, $this->_db, $this->_i18n, $clubId, $scout["id"], $this->_db->getLastInsertedId()); PluginMediator::dispatchEvent($event); // create success message $this->_websoccer->addFrontMessage(new FrontMessage(MESSAGE_TYPE_SUCCESS, $this->_i18n->getMessage("youthteam_scouting_success"), $this->_i18n->getMessage("youthteam_scouting_success_details", $firstName . " " . $lastName))); }
/** * Computes and stores the audience, including crediting the sales revenue. * Considers following factors: * - Fan popularity * - Ticket prices (compared to league average prices, which are set by the admin) * - bonus if the match is attractive. It is attractive if it is a cup match or if teams are neighbors in the standings. * * @param WebSoccer $websoccer request context. * @param DbConnection $db database connection. * @param SimulationMatch $match Simulation match for that the audience shall be computed. */ public static function computeAndSaveAudience(WebSoccer $websoccer, DbConnection $db, SimulationMatch $match) { // get stadium, user and team info $homeInfo = self::getHomeInfo($websoccer, $db, $match->homeTeam->id); if (!$homeInfo) { return; } // is match in particular attractive? $isAttractiveMatch = FALSE; if ($match->type == 'Pokalspiel') { $isAttractiveMatch = TRUE; } else { if ($match->type == 'Ligaspiel') { // consider difference between points $tcolumns = 'sa_punkte'; $fromTable = $websoccer->getConfig('db_prefix') . '_verein'; $whereCondition = 'id = %d'; $result = $db->querySelect($tcolumns, $fromTable, $whereCondition, $match->homeTeam->id); $home = $result->fetch_array(); $result->free(); $result = $db->querySelect($tcolumns, $fromTable, $whereCondition, $match->guestTeam->id); $guest = $result->fetch_array(); $result->free(); if (abs($home['sa_punkte'] - $guest['sa_punkte']) <= 9) { $isAttractiveMatch = TRUE; } } } // consider stadium extras $maintenanceInfluence = $homeInfo['level_videowall'] * $websoccer->getConfig('stadium_videowall_effect'); $maintenanceInfluenceSeats = (5 - $homeInfo['level_seatsquality']) * $websoccer->getConfig('stadium_seatsquality_effect'); $maintenanceInfluenceVip = (5 - $homeInfo['level_vipquality']) * $websoccer->getConfig('stadium_vipquality_effect'); // compute sold tickets $rateStands = self::computeRate($homeInfo['avg_price_stands'], $homeInfo['avg_sales_stands'], $homeInfo['price_stands'], $homeInfo['popularity'], $isAttractiveMatch, $maintenanceInfluence); $rateSeats = self::computeRate($homeInfo['avg_price_seats'], $homeInfo['avg_sales_seats'], $homeInfo['price_seats'], $homeInfo['popularity'], $isAttractiveMatch, $maintenanceInfluence - $maintenanceInfluenceSeats); $rateStandsGrand = self::computeRate($homeInfo['avg_price_stands'] * 1.2, $homeInfo['avg_sales_stands_grand'], $homeInfo['price_stands_grand'], $homeInfo['popularity'], $isAttractiveMatch, $maintenanceInfluence); $rateSeatsGrand = self::computeRate($homeInfo['avg_price_seats'] * 1.2, $homeInfo['avg_sales_seats_grand'], $homeInfo['price_seats_grand'], $homeInfo['popularity'], $isAttractiveMatch, $maintenanceInfluence - $maintenanceInfluenceSeats); $rateVip = self::computeRate($homeInfo['avg_price_vip'], $homeInfo['avg_sales_vip'], $homeInfo['price_vip'], $homeInfo['popularity'], $isAttractiveMatch, $maintenanceInfluence - $maintenanceInfluenceVip); // call plug-ins $event = new TicketsComputedEvent($websoccer, $db, I18n::getInstance($websoccer->getConfig('supported_languages')), $match, $homeInfo['stadium_id'], $rateStands, $rateSeats, $rateStandsGrand, $rateSeatsGrand, $rateVip); PluginMediator::dispatchEvent($event); // is sold out? if ($rateStands == 1 && $rateSeats == 1 && $rateStandsGrand == 1 && $rateSeatsGrand == 1 && $rateVip == 1) { $match->isSoldOut = TRUE; } $tickets_stands = min(1, max(0, $rateStands)) * $homeInfo['places_stands']; $tickets_seats = min(1, max(0, $rateSeats)) * $homeInfo['places_seats']; $tickets_stands_grand = min(1, max(0, $rateStandsGrand)) * $homeInfo['places_stands_grand']; $tickets_seats_grand = min(1, max(0, $rateSeatsGrand)) * $homeInfo['places_seats_grand']; $tickets_vip = min(1, max(0, $rateVip)) * $homeInfo['places_vip']; // update team statistic $columns['last_steh'] = $tickets_stands; $columns['last_sitz'] = $tickets_seats; $columns['last_haupt_steh'] = $tickets_stands_grand; $columns['last_haupt_sitz'] = $tickets_seats_grand; $columns['last_vip'] = $tickets_vip; $fromTable = $websoccer->getConfig('db_prefix') . '_verein'; $whereCondition = 'id = %d'; $db->queryUpdate($columns, $fromTable, $whereCondition, $match->homeTeam->id); // update match field $mcolumns['zuschauer'] = $tickets_stands + $tickets_seats + $tickets_stands_grand + $tickets_seats_grand + $tickets_vip; $fromTable = $websoccer->getConfig('db_prefix') . '_spiel'; $db->queryUpdate($mcolumns, $fromTable, $whereCondition, $match->id); // compute and credit income $revenue = $tickets_stands * $homeInfo['price_stands']; $revenue += $tickets_seats * $homeInfo['price_seats']; $revenue += $tickets_stands_grand * $homeInfo['price_stands_grand']; $revenue += $tickets_seats_grand * $homeInfo['price_seats_grand']; $revenue += $tickets_vip * $homeInfo['price_vip']; BankAccountDataService::creditAmount($websoccer, $db, $match->homeTeam->id, $revenue, 'match_ticketrevenue_subject', 'match_ticketrevenue_sender'); self::weakenPlayersDueToGrassQuality($websoccer, $homeInfo, $match); self::updateMaintenanceStatus($websoccer, $db, $homeInfo); }
// increase age of youth players $youthresult = $db->querySelect('id,age', $conf['db_prefix'] . '_youthplayer', 'team_id = %d', $team['id']); while ($youthplayer = $youthresult->fetch_array()) { $playerage = $youthplayer['age'] + 1; // delete youth player if ($maxYouthAge > 0 && $maxYouthAge <= $playerage) { $db->queryDelete($conf['db_prefix'] . '_youthplayer', 'id = %d', $youthplayer['id']); // update youth player } else { $db->queryUpdate(array('age' => $playerage), $conf['db_prefix'] . '_youthplayer', 'id = %d', $youthplayer['id']); } } $youthresult->free(); // dispatch event $event = new SeasonOfTeamCompletedEvent($website, $db, $i18n, $team['id'], $season['id'], $rank); PluginMediator::dispatchEvent($event); $rank++; } $result->free(); // reset clubs statistics of teams which have not been moved $teamcolumns = array(); $teamcolumns['sa_tore'] = 0; $teamcolumns['sa_gegentore'] = 0; $teamcolumns['sa_spiele'] = 0; $teamcolumns['sa_siege'] = 0; $teamcolumns['sa_niederlagen'] = 0; $teamcolumns['sa_unentschieden'] = 0; $teamcolumns['sa_punkte'] = 0; $db->queryUpdate($teamcolumns, $conf['db_prefix'] . '_verein', 'liga_id = %d', $season['liga_id']); // update season $db->queryUpdate($seasoncolumns, $conf['db_prefix'] . '_saison', 'id = %d', $season['id']);
/** * called when match is considered as completed. * * @param SimulationMatch $match */ private function completeMatch($match) { $match->isCompleted = TRUE; foreach ($this->_observers as $observer) { $observer->onMatchCompleted($match); } // trigger plug-ins $event = new MatchCompletedEvent($this->_websoccer, $this->_db, I18n::getInstance($this->_websoccer->getConfig('supported_languages')), $match); PluginMediator::dispatchEvent($event); }
private function trainPlayers($teamId, $trainer, $unit) { // compute effect on every player $players = PlayersDataService::getPlayersOfTeamById($this->_websoccer, $this->_db, $teamId); // freshness decrease for stamina and technique training $freshnessDecrease = round(1 + $unit["intensity"] / 100 * 5); $fromTable = $this->_websoccer->getConfig("db_prefix") . "_spieler"; $whereCondition = "id = %d"; $trainingEffects = array(); foreach ($players as $player) { // injured player only refreshes and looses stamina $effectFreshness = 0; $effectStamina = 0; $effectTechnique = 0; $effectSatisfaction = 0; if ($player["matches_injured"]) { $effectFreshness = 1; $effectStamina = -1; } else { // regeneration training if ($unit["focus"] == "FR") { $effectFreshness = 5; $effectStamina = -2; $effectSatisfaction = 1; // motivation training } else { if ($unit["focus"] == "MOT") { $effectFreshness = 1; $effectStamina = -1; $effectSatisfaction = 5; // stamina training } else { if ($unit["focus"] == "STA") { $effectSatisfaction = -1; // freshness depends on intensity $effectFreshness = -$freshnessDecrease; // success depends on trainer skills and intensity $staminaIncrease = 1; if ($unit["intensity"] > 50) { $successFactor = $unit["intensity"] * $trainer["p_stamina"] / 100; $pStamina[5] = $successFactor; $pStamina[1] = 100 - $successFactor; $staminaIncrease += SimulationHelper::selectItemFromProbabilities($pStamina); } $effectStamina = $staminaIncrease; // technique } else { $effectFreshness = -$freshnessDecrease; if ($unit["intensity"] > 20) { $effectStamina = 1; } $techIncrease = 0; if ($unit["intensity"] > 75) { $successFactor = $unit["intensity"] * $trainer["p_technique"] / 100; $pTech[2] = $successFactor; $pTech[0] = 100 - $successFactor; $techIncrease += SimulationHelper::selectItemFromProbabilities($pTech); } $effectTechnique = $techIncrease; } } } } // call plugins $event = new PlayerTrainedEvent($this->_websoccer, $this->_db, $this->_i18n, $player["id"], $teamId, $trainer["id"], $effectFreshness, $effectTechnique, $effectStamina, $effectSatisfaction); PluginMediator::dispatchEvent($event); // update player $columns = array("w_frische" => min(100, max(1, $player["strength_freshness"] + $effectFreshness)), "w_technik" => min(100, max(1, $player["strength_technic"] + $effectTechnique)), "w_kondition" => min(100, max(1, $player["strength_stamina"] + $effectStamina)), "w_zufriedenheit" => min(100, max(1, $player["strength_satisfaction"] + $effectSatisfaction))); $this->_db->queryUpdate($columns, $fromTable, $whereCondition, $player["id"]); // add effect $trainingEffects[$player["id"]] = array("name" => $player["pseudonym"] ? $player["pseudonym"] : $player["firstname"] . " " . $player["lastname"], "freshness" => $effectFreshness, "technique" => $effectTechnique, "stamina" => $effectStamina, "satisfaction" => $effectSatisfaction); } $this->_websoccer->addContextParameter("trainingEffects", $trainingEffects); }
private function _createUser($parameters, $fromTable) { $dbcolumns = array(); $dbcolumns["nick"] = $parameters["nick"]; $dbcolumns["email"] = strtolower($parameters["email"]); $dbcolumns["passwort_salt"] = SecurityUtil::generatePasswordSalt(); $dbcolumns["passwort"] = SecurityUtil::hashPassword($parameters["pswd"], $dbcolumns["passwort_salt"]); $dbcolumns["datum_anmeldung"] = $this->_websoccer->getNowAsTimestamp(); $dbcolumns["schluessel"] = str_replace("&", "_", SecurityUtil::generatePassword()); $dbcolumns["status"] = 2; $dbcolumns["lang"] = $this->_i18n->getCurrentLanguage(); if ($this->_websoccer->getConfig("premium_initial_credit")) { $dbcolumns["premium_balance"] = $this->_websoccer->getConfig("premium_initial_credit"); } $this->_db->queryInsert($dbcolumns, $fromTable); // get user id $columns = "id"; $wherePart = "email = '%s'"; $result = $this->_db->querySelect($columns, $fromTable, $wherePart, $dbcolumns["email"]); $newuser = $result->fetch_array(); $result->free(); $querystr = "key=" . $dbcolumns["schluessel"] . "&userid=" . $newuser["id"]; $tplparameters["activationlink"] = $this->_websoccer->getInternalActionUrl("activate", $querystr, "activate-user", TRUE); // send e-mail EmailHelper::sendSystemEmailFromTemplate($this->_websoccer, $this->_i18n, $dbcolumns["email"], $this->_i18n->getMessage("activation_email_subject"), "useractivation", $tplparameters); // trigger plug-ins $event = new UserRegisteredEvent($this->_websoccer, $this->_db, $this->_i18n, $newuser["id"], $dbcolumns["nick"], $dbcolumns["email"]); PluginMediator::dispatchEvent($event); }
/** * Update overall player statistics and match records of player. * * @param SimulationMatch $match * @param SimulationPlayer $player * @param $isOnPitch TRUE if player is on pitch in the end, FALSE if got removed (substitution or red card or injury). */ private function _updatePlayer(SimulationMatch $match, SimulationPlayer $player, $isOnPitch) { // update match statistics $columns = array('name' => $player->name, 'position_main' => $player->mainPosition, 'grade' => $player->getMark(), 'minutes_played' => $player->getMinutesPlayed(), 'card_yellow' => $player->yellowCards, 'card_red' => $player->redCard, 'goals' => $player->getGoals(), 'strength' => $player->strength, 'ballcontacts' => $player->getBallContacts(), 'wontackles' => $player->getWonTackles(), 'shoots' => $player->getShoots(), 'passes_successed' => $player->getPassesSuccessed(), 'passes_failed' => $player->getPassesFailed(), 'assists' => $player->getAssists(), 'state' => $isOnPitch ? '1' : 'Ausgewechselt'); $this->_db->queryUpdate($columns, $this->_websoccer->getConfig('db_prefix') . '_youthmatch_player', 'match_id = %d AND player_id = %d', array($match->id, $player->id)); // update player record, if actually played if ($this->_websoccer->getConfig('sim_played_min_minutes') <= $player->getMinutesPlayed()) { // query existing statistics $result = $this->_db->querySelect('*', $this->_websoccer->getConfig('db_prefix') . '_youthplayer', 'id = %d', $player->id); $playerinfo = $result->fetch_array(); $result->free(); $strengthChange = $this->_computeStrengthChange($player); // trigger plug-ins $event = new YouthPlayerPlayedEvent($this->_websoccer, $this->_db, I18n::getInstance($this->_websoccer->getConfig('supported_languages')), $player, $strengthChange); PluginMediator::dispatchEvent($event); $yellowRedCards = 0; if ($player->yellowCards == 2) { $yellowCards = 1; $yellowRedCards = 1; } else { $yellowCards = $player->yellowCards; } // ensure that new strength does not exceed boundaries (max/min strength) $strength = $playerinfo['strength'] + $strengthChange; $maxStrength = $this->_websoccer->getConfig('youth_scouting_max_strength'); $minStrength = $this->_websoccer->getConfig('youth_scouting_min_strength'); if ($strength > $maxStrength) { $strengthChange = 0; $strength = $maxStrength; } else { if ($strength < $minStrength) { $strengthChange = 0; $strength = $minStrength; } } // save $columns = array('strength' => $strength, 'strength_last_change' => $strengthChange, 'st_goals' => $playerinfo['st_goals'] + $player->getGoals(), 'st_matches' => $playerinfo['st_matches'] + 1, 'st_assists' => $playerinfo['st_assists'] + $player->getAssists(), 'st_cards_yellow' => $playerinfo['st_cards_yellow'] + $yellowCards, 'st_cards_yellow_red' => $playerinfo['st_cards_yellow_red'] + $yellowRedCards, 'st_cards_red' => $playerinfo['st_cards_red'] + $player->redCard); $this->_db->queryUpdate($columns, $this->_websoccer->getConfig('db_prefix') . '_youthplayer', 'id = %d', $player->id); } }