This commit is contained in:
2022-06-07 00:30:34 +03:00
commit 5f4b2cbf77
1784 changed files with 327645 additions and 0 deletions
+152
View File
@@ -0,0 +1,152 @@
<?php
namespace Insallah;
use Exception;
use PDO;
use PDOException;
use PDOStatement;
class Db
{
/**
* Íàñòðîéêè ïîäêëþ÷åíèÿ
* Ëó÷øå âûíîñèòü â êîíôèã
* self::DB_HOST -> Config::DB_HOST
*/
const DB_HOST = '127.0.0.1'; // localhost
const DB_USER = 'newcom1_abk';
const DB_PASSWORD = '4nWYsIM[c?}P';
const DB_NAME = 'newcom1_abk';
const CHARSET = 'cp1251';
const DB_PREFIX = '';
/**
* @var PDO
*/
static private $db;
/**
* @var null
*/
protected static $instance = null;
/**
* DB constructor.
* @throws Exception
*/
public function __construct(){
if (self::$instance === null){
try {
self::$db = new PDO(
'mysql:host='.self::DB_HOST.';dbname='.self::DB_NAME,
self::DB_USER,
self::DB_PASSWORD,
$options = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES ".self::CHARSET
]
);
} catch (PDOException $e) {
throw new Exception ($e->getMessage());
}
}
return self::$instance;
}
/**
* @param $stmt
* @return PDOStatement
*/
public static function query($stmt) {
return self::$db->query($stmt);
}
/**
* @param $stmt
* @return PDOStatement
*/
public static function prepare($stmt) {
return self::$db->prepare($stmt);
}
/**
* @param $query
* @return int
*/
static public function exec($query) {
return self::$db->exec($query);
}
/**
* @return string
*/
static public function lastInsertId() {
return self::$db->lastInsertId();
}
/**
* @param $query
* @param array $args
* @return PDOStatement
* @throws Exception
*/
public static function run($query, $args = []) {
try{
if (!$args) {
return self::query($query);
}
$stmt = self::prepare($query);
$stmt->execute($args);
return $stmt;
} catch (PDOException $e) {
throw new Exception($e->getMessage());
}
}
/**
* @param $query
* @param array $args
* @return mixed
*/
public static function getRow($query, $args = []) {
return self::run($query, $args)->fetch();
}
/**
* @param $query
* @param array $args
* @return array
*/
public static function getRows($query, $args = []) {
return self::run($query, $args)->fetchAll();
}
/**
* @param $query
* @param array $args
* @return mixed
*/
public static function getValue($query, $args = []) {
$result = self::getRow($query, $args);
if (!empty($result)) {
$result = array_shift($result);
}
return $result;
}
/**
* @param $query
* @param array $args
* @return array
*/
public static function getColumn($query, $args = []) {
return self::run($query, $args)->fetchAll(PDO::FETCH_COLUMN);
}
public static function sql($query, $args = [])
{
self::run($query, $args);
}
}
@@ -0,0 +1,112 @@
<?php
/** todo
* В каком-то месте проверять по крону не протух ли турнир!
*/
namespace Insallah;
class Tournament
{
/**
* Проверяем может ли игрок учавствовать в турнире и либо присоединяем его, либо обламываем.
*
* @param int $user_id
*
* @return void
*/
public function join($user_id)
{
/** Возвращает level, или 0 если провалены проверки. */
$userLevel = TournamentModel::getUserLevel($user_id);
if ($userLevel === 0) {
return;
}
$mq = TournamentModel::getWaitingMembersQuantity($userLevel);
if (empty($mq)) {
TournamentModel::createTournament($userLevel);
}
TournamentModel::joinTournament($user_id, $userLevel);
/** На третьем участнике пишем уведомление в чат. */
if ($mq === 2) {
TournamentModel::sysMessage("Внимание! Идёт набор бойцов на турнир " . $userLevel . " уровня! Поспешите!");
}
/** На двенадцатом участнике начинаем турнир. */
if ($mq === 11) {
TournamentModel::startTournament($userLevel);
$this->check_members($userLevel);
}
}
/**
* Проверяем есть ли ещё участники турнира. Если есть, отправляем драться. Если остался последний - значит он
* победитель.
* todo Обработать ничью!
*
* @param int $tournament_id
*
* @return void
*/
private function check_members($tournament_id)
{
$active_fighters = TournamentModel::getFreeFighters($tournament_id);
if (count($active_fighters) > 1) {
$this->start_battle($active_fighters);
} else {
TournamentModel::removeFighter($active_fighters[0]); // выбиваем победителя
$this->victory($tournament_id);
}
}
/**
* Получаем пары бойцов и начинаем их поединки.
*
* @param array $fighters_list
*
* @return void
*/
private function start_battle(array $fighters_list)
{
$teams = TournamentModel::getFightersTeams($fighters_list);
foreach ($teams as $team) {
if (count($team) === 2) {
TournamentModel::startBattle($team[0], $team[1]);
}
}
}
/**
* Вызывается при проигрыше боя или при уходе в оффлайн.
*
* @param int $user_id
*
* @return void
*/
public function kick_user($user_id)
{
if (empty($user_id)) {
return;
}
TournamentModel::removeFighter($user_id);
$this->check_members(TournamentModel::getTournamentIdByUserId($user_id)); //перезапуск выбора противника для поединка
}
/**
* Награждаем победителей турнира, чистим базу.
*
* @param int $tournament_id
*
* @return void
*/
private function victory($tournament_id)
{
$winners = TournamentModel::getWinners($tournament_id);
TournamentModel::destroyTournament($tournament_id);
TournamentModel::givePrizeItems($winners[1], 25);
TournamentModel::givePrizeItems($winners[2], 10);
TournamentModel::givePrizeItems($winners[3], 5);
}
}
@@ -0,0 +1,285 @@
<?php
namespace Insallah;
class TournamentModel
{
/**
* проверка уровня, стоимости эквипа, прочие проверки, что персонаж свободен
* таймер ожидания 30 минут
*
* @param int $uid
*
* @return int
*/
public static function getUserLevel($uid)
{
$db = new Db;
$level = $db::getValue('select level from users where id = ? and level between 8 and 12 and battle = 0', [$uid]);
if (!$level) {
return 0;
}
$ekr_total = $db::getValue('select sum(2price) from items_users where inOdet > 0 and uid = ?', [$uid]);
$exp = $db::getValue('select exp from stats where id = ?', [$uid]);
// Вот правда не знаю проканает или нет.
if ($ekr_total > ($level - 7) * 150 || $exp < 250000) {
return 0;
}
return $level;
}
/**
* Считаем сколько игроков ждут в заявке на турнир.
*
* @param int $tid
*
* @return int
*/
public static function getWaitingMembersQuantity($tid)
{
$db = new Db();
return $db::getValue('select count(*) from tournaments_users where tid = ?', [$tid]);
}
/**
* Создание нового турнира.
*
* @param int $tid
*
* @return void
*/
public static function createTournament($tid)
{
$db = new Db();
$db::sql('insert into tournaments (tid) values (?)', [$tid]);
}
/**
* Игрок присоединяется к турниру и телепортируется в турнирную комнату.
*
* @param int $uid
* @param int $tid
*
* @return void
*/
public static function joinTournament($uid, $tid)
{
/** Кастомные комнаты 25008 - 25012. */
$room_id = 25000 + $tid;
$db = new Db();
$db::sql('insert into tournaments_users (tid, uid) values (?, ?)', [$tid, $uid]);
self::teleport($uid, $room_id);
}
/**
* Старт турнира.
*
* @param int $tid
*
* @return void
*/
public static function startTournament($tid)
{
$db = new Db();
$db::sql('update tournaments set start_time = -1 where tid = ?', [$tid]);
}
/**
* Чистим базы от прошедшего турнира.
*
* @param int $tid
*
* @return void
*/
public static function destroyTournament($tid)
{
$db = new Db();
//Убедиться что в базе настроен foreign_keys и последует автоочистка tournaments_users !!!
$db::sql('delete from tournaments where tid = ?', [$tid]);
}
/**
* Получаем список бойцов и бьём их на пары. Возвращаем списки пар + 1 последний без пары если есть.
*
* @param array $fighters_list
*
* @return array
*/
public static function getFightersTeams(array $fighters_list)
{
$db = new Db();
return array_chunk($db::getRows('select id from users where battle = 0 and id in (?)', [implode(', ', $fighters_list)]), 2);
}
/**
* Выбираем живых бойцов не сражающихся в данный момент.
*
* @param int $tid
*
* @return array
*/
public static function getFreeFighters($tid)
{
$db = new Db();
return $db::getRows('select uid from tournaments_users where tid = ? and death_time = 0 order by rand()', [$tid]);
}
/**
* Выбираем победителей. Смещаем массив, чтобы возврат шёл с единицы.
*
* @param int $tid
*
* @return array
*/
public static function getWinners($tid)
{
$db = new Db();
$arr = [];
array_unshift($arr, '');
unset($arr[0]);
$winners = $db::getRows('select uid from tournaments_users where tid = ? order by death_time desc limit 3', [$tid]);
foreach ($winners as $winner) {
$arr[] = $winner['uid'];
}
return $arr;
}
/**
* Пробуем выкусить проигравшего в последней турнирной битве и удалить эту самую битву во избежание.
* @return mixed
*/
public static function getLooser()
{
$query = '
select uid, battle
from
battle_users,
(select id, team_win
from battle
where
team_win > 0 and
typeBattle = 25000
order by time_over desc
limit 1) as last_battle
where
battle_users.battle = last_battle.id and
battle_users.team != last_battle.team_win';
$db = new Db;
$row = $db::getRow($query);
$db::sql('delete from battle where id = ?', [$row['battle']]);
return $row['uid'];
}
/**
* Выбывший из турнира покидает комнату и получает время смерти.
*
* @param int $uid
*
* @return void
*/
public static function removeFighter($uid)
{
$db = new Db();
$db::sql('update tournaments_users set death_time = unix_timestamp() where uid = ?', [$uid]);
self::teleport($uid, 9);
}
/**
* Узнаём id турнира по id игрока.
* todo Проверить, возможно можно обращаться к уровню игрока.
*
* @param int $uid
*
* @return mixed
*/
public static function getTournamentIdByUserId($uid)
{
$db = new Db();
return $db::getValue('select tid from tournaments_users where uid = ?', [$uid]);
}
/**
* Попробуем стартонуть поединок.
* 25000 - Уникальный id поединка под турниры.
* noinc - запрет на вмешательство
* invis - невидимый бой
*
* @param int $uid1
* @param int $uid2
*
* @return void
*/
public static function startBattle($uid1, $uid2)
{
$db = new Db();
$db::exec('insert into battle (city, time_start, timeout, type, invis, noinc, travmChance, typeBattle)
values (\'capitalcity\', unix_timestamp(), 60, 0, 1, 1, 0, 25000)');
$db::sql('update stats set team = 1, hpNow = hpAll, mpNow = mpAll where id = ?', [$uid1]);
$db::sql('update stats set team = 2, hpNow = hpAll, mpNow = mpAll where id = ?', [$uid2]);
$db::sql('update users set battle = ? where id in (?, ?)', [$db::lastInsertId(), $uid1, $uid2]);
}
/**
* Узнаём логин персонажа по его id.
*
* @param int $uid
*
* @return mixed
*/
public static function uidToLogin($uid)
{
$db = new Db();
return $db::getValue('select login from users where id = ?', [$uid]);
}
/**
* Телепорт по комнатам.
*
* @param int $uid
* @param int $room_id
*
* @return void
*/
private static function teleport($uid, $room_id)
{
$db = new Db();
$db::sql('update users set room = ? where id = ?', [$room_id, $uid]);
}
/**
* Нет проверок $message потому что оно всегда задаётся в коде и игрок на него не влияет.
*
* @param string $city
* @param string $message
*
* @return void
*/
public static function sysMessage($message, $city = 'capitalcity')
{
$db = new Db();
$db::sql('insert into chat (city, room, time, type, text, new, da) values (?, 0, unix_timestamp(), 6, ?, 1, 1)', [$city, $message]);
}
/**
* Генерирует множественный запрос сразу на $quantity однотипных предметов в инвентарь пользователя $uid.
*
* @param int $uid
* @param int $quantity
*
* @return void
*/
public static function givePrizeItems($uid, $quantity)
{
$query = 'insert into items_users (item_id, uid, data, iznosMAX, lastUPD, time_create)
values (4754, :uid, :data, 1, unix_timestamp(), unix_timestamp())';
$args = [
'uid' => $uid,
'data' => 'nosale=1|musor=1|sudba=' . self::uidToLogin($uid) . '|lvl=8|tr_s1=0|tr_s2=0|tr_s3=0|tr_s4=0'
];
$db = new Db();
$stmt = $db::prepare($query);
for ($i = 0; $i < $quantity; $i++) {
$stmt->execute($args);
}
}
}