Обучение #39

Merged
lopar merged 15 commits from maksym into dev 2023-01-23 11:45:10 +00:00
30 changed files with 1210 additions and 317 deletions

View File

@ -1,4 +1,5 @@
<?php
const GAME = true; // Для совместимости с этой "защитой".
const GAME_VERSION = 'alpha-7.4';
// Новая автозагрузка.
@ -44,4 +45,4 @@ spl_autoload_register(function (string $classname) {
}
require_once $file;
});
});

View File

@ -0,0 +1,11 @@
<?php
namespace DarksLight2\Helpers;
class Str
{
public static function snakeCase($string): string
{
return strtolower(preg_replace(['/([a-z\d])([A-Z])/', '/([^_])([A-Z][a-z])/'], '$1_$2', $string));
}
}

View File

@ -2,12 +2,47 @@
namespace DarksLight2\Training;
use DarksLight2\Helpers\Str;
use User;
abstract class StepFactory
{
abstract public function getTitle(): string;
abstract public function getMessage(): string;
abstract public function getShortName(): string;
abstract public function getRewards(): array;
public function onLocations(): array
{
return ['all'];
}
public function getShortName(): string
{
return Str::snakeCase(get_class($this));
}
public function getAnswer()
{
return null;
}
public function allowedToMove(): array
{
return [];
}
public function isInfo(): bool
{
return true;
}
public function databaseRecord()
{
return [
'completed' => false,
'progress' => [
'current' => 0,
'need' => 1,
]
];
}
}

View File

@ -4,17 +4,17 @@ namespace DarksLight2\Training\Steps;
use DarksLight2\Training\StepFactory;
class FirstStep extends StepFactory
class ChatFirstQuest extends StepFactory
{
public function getTitle(): string
{
return 'Первое знакомство';
return 'Начало.';
}
public function getMessage(): string
{
return 'test';
return 'Отправьте сообщение в общий чат.';
}
public function getRewards(): array
@ -24,7 +24,11 @@ class FirstStep extends StepFactory
public function getShortName(): string
Review

Это методы, возвращающие.. константу?

Это методы, возвращающие.. константу?
Review

Это добавляет гибкости. Захочешь ты для определённого задания сделать логику отличную от других, сможешь спокойно это сделать, плюс я уже убедился что это хорошое решение, когда решил переписать логику трейнинга.

Это добавляет гибкости. Захочешь ты для определённого задания сделать логику отличную от других, сможешь спокойно это сделать, плюс я уже убедился что это хорошое решение, когда решил переписать логику трейнинга.
{
return 'first_step';
return 'chat_first_quest';
}
public function isInfo(): bool
{
return false;
}
}

View File

@ -0,0 +1,30 @@
<?php
namespace DarksLight2\Training\Steps;
use DarksLight2\Training\StepFactory;
class ChatFirstStep extends StepFactory
{
public function getTitle(): string
{
return 'Начало.';
}
public function getMessage(): string
{
return 'Помните, оскорблять, унижать, обсуждать политику, подстёгивать других игроков, как в общем чате так и в приватном приведет к временному ограничению возможности отправки сообщений в любой из чатов.';
}
public function getShortName(): string
{
return 'chat_first_step';
}
public function getRewards(): array
{
return [];
}
}

View File

@ -0,0 +1,35 @@
<?php
namespace DarksLight2\Training\Steps;
use DarksLight2\Training\StepFactory;
class ChatSecondQuest extends StepFactory
{
public function getTitle(): string
{
return 'Начало.';
}
public function getMessage(): string
{
return 'Отправьте адресное сообщение в общий чат, нажав 1 раз по никнейму игрока либо в чате, либо со списка онлайна, который находится справа.';
}
public function getShortName(): string
{
return 'chat_second_quest';
}
public function getRewards(): array
{
return [];
}
public function isInfo(): bool
{
return false;
}
}

View File

@ -0,0 +1,34 @@
<?php
namespace DarksLight2\Training\Steps;
use DarksLight2\Training\StepFactory;
class ChatThirdQuest extends StepFactory
{
public function getTitle(): string
{
return 'Начало.';
}
public function getMessage(): string
{
return 'Отправьте адресное личное сообщение в чат, нажав 2 раза по никнему игрока либо в чате, либо со списка онлайна, который находится справа.';
}
public function getShortName(): string
{
return 'chat_third_quest';
}
public function getRewards(): array
{
return [];
}
public function isInfo(): bool
{
return false;
}
}

View File

@ -0,0 +1,35 @@
<?php
namespace DarksLight2\Training\Steps;
use DarksLight2\Training\StepFactory;
class MyUserFirstQuest extends StepFactory
{
public function getTitle(): string
{
return 'Персонаж.';
}
public function getMessage(): string
{
return 'Сколько всего основных игровых Валют? Введите их число...';
}
public function getShortName(): string
{
return 'my_user_first_quest';
}
public function getRewards(): array
{
return [];
}
public function getAnswer(): string
{
return '2';
}
}

View File

@ -0,0 +1,30 @@
<?php
namespace DarksLight2\Training\Steps;
use DarksLight2\Training\StepFactory;
class MyUserFirstStep extends StepFactory
{
public function getTitle(): string
{
return 'Персонаж.';
}
public function getMessage(): string
{
return 'В нашей игре, ваш персонаж расположен слева от экрана с игровыми локациями, там же, можно увидеть пустые слоты под предметы и параметры персонажа, ваш опыт, деньги, ежедневные задания...';
}
public function getShortName(): string
{
return 'my_user_first_step';
}
public function getRewards(): array
{
return [];
}
}

View File

@ -0,0 +1,35 @@
<?php
namespace DarksLight2\Training\Steps;
use DarksLight2\Training\StepFactory;
class MyUserFourthQuest extends StepFactory
{
public function getTitle(): string
{
return 'Персонаж.';
}
public function getMessage(): string
{
return 'Войдите во вкладку " Умения ", в правой части экрана, сверху, а далее, перейдите во вкладку " Приёмы ", после чего, выберите нужные Вам приемы, но будьте внимательны, некоторые из приемов могут быть на разные классы, обязательно прочтите их описание или потестируйте в поединках.';
}
public function getShortName(): string
{
return 'my_user_fourth_quest';
}
public function getRewards(): array
{
return [];
}
public function isInfo(): bool
{
return false;
}
}

View File

@ -0,0 +1,48 @@
<?php
namespace DarksLight2\Training\Steps;
use DarksLight2\Training\StepFactory;
class MyUserFourthStep extends StepFactory
{
public function getTitle(): string
{
return 'Персонаж.';
}
public function getMessage(): string
{
return '"Параметры Персонажа"<br>
Все игроки имеют свободные очки распределения параметров, что они дают игрокам конкретные модификаторы в зависимости от того, в какой из параметров распределяются очки распределения.<br>
--- если можно, добавить скрин как выглядит эта кнопка ---
Сила - Увеличивает мощность рубящего урона ( для Силачей )<br>
Ловкость - Увеличивает мощность колющего урона ( для Критоуворотов и Уворотов )<br>
Интуиция - Увеличивает мощность режущего урона ( для Критовиков )<br>
Выносливость - Увеличивает защиту от урона и магии, а так же добавит немного жизней. ( для Танков )<br>
Интелект - Увеличивает мощность магии. ( Для Любого Мага )<br>
Мудрость - Увеличивает колличество маны. ( Для Любого Мага )<br>
<br>
Дополнительно, игроки имеют очки распределения Мастерства Оружия, это позволит воинам увеличить урон, а магам, открыть новые приемы.<br>
Очки распределения Оружий распределяются точно так же, как и очки распределения параметров ( статов ).<br>
<br>
В случае, если вы распределили неверно любые доступные очки распределения, или хотите их изменить, вы можете это сделать, поднявшись на 2 этаж здания " Бойцовский Клуб ".';
}
public function getShortName(): string
{
return 'my_user_fourth_step';
}
public function getRewards(): array
{
return [];
}
public function getAnswer(): string
{
return '';
}
}

View File

@ -0,0 +1,35 @@
<?php
namespace DarksLight2\Training\Steps;
use DarksLight2\Training\StepFactory;
class MyUserSecondQuest extends StepFactory
{
public function getTitle(): string
{
return 'Персонаж.';
}
public function getMessage(): string
{
return 'Кого убивает игровой класс "Танк"?';
}
public function getShortName(): string
{
return 'my_user_second_quest';
}
public function getRewards(): array
{
return [];
}
public function getAnswer(): string
{
return 'Уворотов и Силачей';
}
}

View File

@ -0,0 +1,39 @@
<?php
namespace DarksLight2\Training\Steps;
use DarksLight2\Training\StepFactory;
class MyUserSecondStep extends StepFactory
{
public function getTitle(): string
{
return 'Персонаж.';
}
public function getMessage(): string
{
return 'Опыт - Получение опыта происходит после сыгранных поединков, в зависимости от выбитого урона с противников, нажав по своему опыту, откроется таблица опыта, в которой можно посмотреть, когда вы получите дополнительное очко распределение параметров персонажа/оружий, награду за взятие " апа " или " Уровня "<br>
Текущий уровень - Отображает ваш текущий уровень персонажа.<br>
Победы - Отображает сумму всех ваших побед, в любых поединках.<br>
Поражения - Отображает сумму всех ваших поражений, в любых поединках.<br>
Ничьих - Отображает сумму всех поединков, которые завершились в ничью.<br>
Кредиты - Обычная игровая валюта - кредиты ( креды ), которые можно потратить в обычном магазине.<br>
Еврокредиты - Покупная игровая валюта - еврокредиты ( екры ) , которые можно потратить в магазине " Берёзка ". <br>
Воинственность - Дополнительная игровая валюта, потратить её можно в Подпольной Лавке.<br>
Ежедневное задание - Отображает текущее ежедневное задание либо предоставляет возможность его взятия.<br>
Бонус - Позволяет получить немного кредитов или еврокредитов.';
}
public function getShortName(): string
{
return 'my_user_second_step';
}
public function getRewards(): array
{
return [];
}
}

View File

@ -0,0 +1,40 @@
<?php
namespace DarksLight2\Training\Steps;
use DarksLight2\Training\StepFactory;
class MyUserThirdQuest extends StepFactory
{
public function getTitle(): string
{
return 'Персонаж.';
}
public function getMessage(): string
{
return 'Распределите свободные параметры распределения ( статы ) и параметры оружий ( умения ) в зависимости от выбранного вами при регистрации "Класса" игрока нажав по кнопке " + Способности ", а далее, после распределения параметров " Сохранить ".';
}
public function getShortName(): string
{
return 'my_user_third_quest';
}
public function getRewards(): array
{
return [];
}
public function isInfo(): bool
{
return false;
}
public function allowedToMove(): array
{
return ['cp1'];
}
}

View File

@ -0,0 +1,45 @@
<?php
namespace DarksLight2\Training\Steps;
use DarksLight2\Training\StepFactory;
class MyUserThirdStep extends StepFactory
{
public function getTitle(): string
{
return 'Персонаж.';
}
public function getMessage(): string
{
return 'В нашей игре, существует 5 Воинских и 4 Магических класса, такие как:<br>
Критовик - Убивает Танков и Магов, основное оружие - Мечи<br>
Уворот - Убивает Критовиков и Силачей, основное оружие - Кинжалы<br>
Танк - Убивает Уворотов и Силачей, основное оружие - Дубина и щит.<br>
Силач - Убивает Критовиков и Магов, основное оружие - Топоры<br>
Критоуворот - Убивает Силачей и с небольшим шансом Критовиков и Уворотов, основное оружие - Кинжалы.<br>
<br>
Маг Огня - Атакующий маг, убивает Уворотов и Танков.<br>
Маг Воздуха - Атакующий маг, убивает Уворотов и Танков.<br>
Маг Земли - Защищающийся маг, слабый урон, хорошая защита.<br>
Маг Воды - Защищающийся маг, слабый урон, хорошая защита.';
}
public function getShortName(): string
{
return 'my_user_third_step';
}
public function getRewards(): array
{
return [];
}
public function allowedToMove(): array
{
return ['cp1'];
}
}

View File

@ -3,24 +3,125 @@
namespace DarksLight2\Training;
use Core\Db;
use DarksLight2\Training\Steps\ChatFirstStep;
use DarksLight2\Training\Steps\MyUserFirstQuest;
use DarksLight2\Training\Steps\MyUserFirstStep;
use DarksLight2\Training\Steps\MyUserFourthQuest;
use DarksLight2\Training\Steps\MyUserFourthStep;
use DarksLight2\Training\Steps\MyUserSecondQuest;
use DarksLight2\Training\Steps\MyUserSecondStep;
use DarksLight2\Training\Steps\MyUserThirdQuest;
use DarksLight2\Training\Steps\MyUserThirdStep;
use DarksLight2\Traits\Singleton;
use PDO;
use stdClass;
use PassGen;
use User;
class TrainingManager
{
use Singleton;
private $database_records = false;
private array $steps_data;
private int $user_id;
private array $steps;
public string $current_step = '';
private array $registered_steps;
private array $completed_steps;
private array $active_steps;
public function __construct(int $user_id)
private $database;
public function __construct(int $user_id, $refresh_token = true)
{
try {
$this->register([
new ChatFirstStep(),
new MyUserFirstStep(),
new MyUserFirstQuest(),
new MyUserSecondStep(),
new MyUserSecondQuest(),
new MyUserThirdStep(),
new MyUserThirdQuest(),
new MyUserFourthStep(),
new MyUserFourthQuest(),
]);
} catch (TrainingException $e) {
}
$this->user_id = $user_id;
if($refresh_token) {
Review

Я бы от греха подальше проверил бы хотя бы на > 0, а в идеале на валидное значение. Прилетит некондит, привет "всё сломалось".

Я бы от греха подальше проверил бы хотя бы на `> 0`, а в идеале на валидное значение. Прилетит некондит, привет "всё сломалось".
Review

В идеале в айдишнике юзера не должно быть значения <= 0
Просто подумай, как такое вообще должно работать, если туда куда не надо попадают не те значения?) и все же я думаю что эта проверка должна быть уровнем высше, чтобы не засорять код глупыми if($u->info['id'] > 0)

В идеале в айдишнике юзера не должно быть значения `<= 0` Просто подумай, как такое вообще должно работать, если туда куда не надо попадают не те значения?) и все же я думаю что эта проверка должна быть уровнем высше, чтобы не засорять код глупыми `if($u->info['id'] > 0)`
Review

У нас есть класс User на 12 тысяч строк. Можем сначала полностью переделать его, чтобы id точно, гарантированно, никогда не мог быть невалидным. Рефакторинг старого кода, он такой.
Я говорю по своему опыту, что запросто встречал случаи, когда $u->info вообще NULL. И в данном случае код вернёт FATAL ERROR и полностью остановится. Я же предлагаю исключительно на время, пока всё хреново, сделать вариант, когда метод вернёт false и ругнётся не останавливая все процессы.

У нас есть класс User на 12 тысяч строк. Можем сначала полностью переделать его, чтобы id точно, гарантированно, никогда не мог быть невалидным. Рефакторинг старого кода, он такой. Я говорю по своему опыту, что запросто встречал случаи, когда `$u->info` вообще `NULL`. И в данном случае код вернёт FATAL ERROR и полностью остановится. Я же предлагаю исключительно на время, пока всё хреново, сделать вариант, когда метод вернёт false и ругнётся не останавливая все процессы.
$this->generateToken();
}
$this->database = Db::getRow('SELECT * FROM user_training WHERE user_id = ?', [$user_id]);
$this->createDatabaseRecord();
$this->database['data'] = json_decode($this->database['data'], true);
$this->selectActiveSteps();
}
public function getCurrentStepName(): string
{
if(empty($this->current_step)) {
$this->current_step = array_key_first($this->active_steps) ?? '';
}
return $this->current_step;
}
public function getRegistered(): array
{
return $this->registered_steps;
}
public function getDatabaseData()
{
return $this->database;
}
public function addPoint($short_name, $closure = null)
{
if($short_name === $this->getCurrentStepName()) {
$this->database['data'][$short_name]['progress']['current']++;
if(isset($closure)) {
$closure($this);
}
}
}
public function nextStep()
{
if($this->database['data'][$this->getCurrentStepName()]['progress']['need'] <= $this->database['data'][$this->getCurrentStepName()]['progress']['current']) {
$this->database['data'][$this->getCurrentStepName()]['progress']['current'] = 0;
$this->database['data'][$this->getCurrentStepName()]['completed'] = true;
unset($this->active_steps[$this->getCurrentStepName()]);
$this->current_step = array_key_first($this->active_steps) ?? '';
$this->database['current'] = $this->getCurrentStepName();
}
}
public function previousStep()
{
$this->current_step = end($this->completed_steps) ?? '';
$this->database['current'] = $this->current_step;
$this->database['data'][$this->getCurrentStepName()]['completed'] = false;
}
public function selectActiveSteps()
{
foreach ($this->database['data'] as $step_name => $data) {
if($data['completed'] === false) {
$this->active_steps[$step_name] = $data;
continue;
}
$this->completed_steps[] = $step_name;
}
}
DarksLight2 marked this conversation as resolved
Review

Если нет особой необходимости, лучше использовать стандартный Db::getRows(), для единообразия.

Если нет особой необходимости, лучше использовать стандартный Db::getRows(), для единообразия.
Review

Выбрал этот путь, потому что только одна запись там должна быть.

Выбрал этот путь, потому что только одна запись там должна быть.
Review

Тогда Db::getRow

Тогда Db::getRow
public function store()
{
Db::sql('UPDATE user_training SET data = ?, current = ? WHERE user_id = ?', [json_encode($this->database['data']), $this->database['current'], $this->user_id]);
}
/**
@ -37,104 +138,55 @@ class TrainingManager
foreach ($steps as $step) {
if($step instanceof StepFactory) {
$this->steps[$step->getShortName()] = new class (
$step->getMessage(),
$step->getTitle(),
$step->getRewards(),
$this->stepData($step->getShortName())->complete,
$step->getShortName(),
$this->stepData($step->getShortName())->progress
) {
public string $message;
public string $title;
public string $short_name;
public array $rewards;
public bool $isComplete;
public stdClass $progress;
public function __construct(
string $message,
string $title,
array $rewards,
bool $isComplete,
string $short_name,
stdClass $progress
) {
$this->rewards = $rewards;
$this->title = $title;
$this->isComplete = $isComplete;
$this->message = $message;
$this->short_name = $short_name;
$this->progress = $progress;
}
public function render()
{
$path = $_SERVER['DOCUMENT_ROOT'] . '/modules_data/steps/' . $this->short_name . '.php';
if(file_exists($path)) {
require $path;
return;
}
throw TrainingException::noRenderingFile();
}
};
$this->registered_steps[$step->getShortName()] = $step;
}
}
}
private function stepData(string $short_name): object
private function generateToken($length = 16)
{
return json_decode($this->getDatabaseRecords()->data)->$short_name;
}
private function getDatabaseRecords()
{
if(!$this->database_records) {
$this->database_records = Db::run('SELECT * FROM user_training WHERE user_id = ?', [$this->user_id])
->fetch(PDO::FETCH_OBJ);
}
return $this->database_records;
Db::run('UPDATE user_training SET api_token = ? WHERE user_id = ?', [
PassGen::new($length),
$this->user_id
]);
}
public function createDatabaseRecord()
{
if(!$this->getDatabaseRecords()) {
Db::run('INSERT INTO user_training (user_id, data) VALUES (?, ?)', [
if(!$this->database) {
$data = [];
foreach ($this->registered_steps as $step) {
$data[$step->getShortName()] = $step->databaseRecord();
}
Db::sql('INSERT INTO user_training (user_id, data, current) VALUES (?, ?, ?)', [
$this->user_id,
json_encode($this->firstRecordData())
json_encode($data, true),
array_key_first($data)
]);
$this->database = Db::getRow('SELECT * FROM user_training WHERE user_id = ?', [$this->user_id]);
}
}
private function firstRecordData(): array
/**
* @throws \DarksLight2\Training\TrainingException
*/
public function render()
{
return [
'first_step' => [
'complete' => 0,
'progress' => [
'current' => 0,
'need' => 0,
]
]
];
}
if(in_array(User::start()->room['file'], $this->registered_steps[$this->getCurrentStepName()]->onLocations()) || in_array('all', $this->registered_steps[$this->getCurrentStepName()]->onLocations())) {
$path = $_SERVER['DOCUMENT_ROOT'] . '/modules_data/steps/step.php';
public function __get(string $name)
{
return $this->steps[$name];
}
public function addPoint(string $short_name)
{
$this->$short_name->progress++;
}
public function store()
{
if (file_exists($path)) {
$short_name = $this->getCurrentStepName();
$answer = $this->registered_steps[$this->getCurrentStepName()]->getAnswer();
require $path;
return;
}
throw TrainingException::noRenderingFile();
}
}
}

View File

@ -1,6 +1,7 @@
<?php
use Core\Db;
use DarksLight2\Training\TrainingManager;
use Insallah\Math;
/*
@ -2054,6 +2055,10 @@ class Priems
'UPDATE `stats` SET `priems` = "' . $p . '" WHERE `id` = "' . $this->u->info['id'] . '" LIMIT 1'
);
if ($upd) {
TrainingManager::getInstance()
->addPoint('my_user_fourth_quest', function (TrainingManager $manager) {
$manager->store();
});
$this->u->info['priems'] = $p;
}
} else {

5
api/.htaccess Normal file
View File

@ -0,0 +1,5 @@
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^training/complete/?$ index.php?get=complete [L]
RewriteRule ^training/go_back/?$ index.php?get=go_back [L]
</IfModule>

70
api/index.php Normal file
View File

@ -0,0 +1,70 @@
<?php
use DarksLight2\Training\Steps\ChatFirstStep;
use DarksLight2\Training\Steps\MyUserFirstQuest;
use DarksLight2\Training\TrainingException;
use DarksLight2\Training\TrainingManager;
header('Content-type: application/json');
if (!defined('GAME_VERSION')) {
require_once '../_incl_data/autoload.php';
}
$user = User::start();
if($input = file_get_contents("php://input")) {
$data = json_decode($input);
}
if(!empty($user->info)) {
$training = TrainingManager::getInstance($user->info['id'], false);
try {
$training->createDatabaseRecord();
$training->register([
new MyUserFirstQuest(),
new ChatFirstStep()
]);
} catch (TrainingException $e) {
}
if (!isset($data->token) || !password_verify(
$training->getDatabaseData()['api_token'] . $data->time . $user->info['id'],
$data->token
)) {
http_response_code(401);
die;
}
if (isset($_GET['get'])) {
switch ($_GET['get']) {
default:
http_response_code(400);
die;
case 'complete':
if ($training->getDatabaseData()['data'][$training->getCurrentStepName()]['completed']) {
http_response_code(400);
die;
}
if($training->getRegistered()[$data->short_name]->isInfo()) {
$training->addPoint($training->getCurrentStepName());
}
$training->nextStep();
$training->store();
die(json_encode(['status' => 'ok']));
case 'go_back':
$training->previousStep();
$training->store();
die(json_encode(['status' => 'ok', 'message' => 'Вы указали не верный ответ!']));
}
}
}

94
css/training/modal.css Normal file
View File

@ -0,0 +1,94 @@
.modal__backdrop {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
/*background: rgba(0, 0, 0, 0.5);*/
opacity: 0;
z-index: -1;
pointer-events: none;
transition: opacity0 .2s ease-in;
}
.modal__content {
position: relative;
width: auto;
margin: 10px;
transition: opacity 0.3s ease-in;
display: flex;
flex-direction: column;
background-color: #fff;
background-clip: padding-box;
border: 1px solid rgba(0, 0, 0, 0.2);
border-radius: 0.3rem;
box-shadow: 0 0 7px 0 rgba(0, 0, 0, 0.3);
}
@media (min-width: 576px) {
.modal__content {
max-width: 500px;
margin: 50px auto;
}
}
.modal__show .modal__backdrop,
.modal__show .modal__content {
opacity: 1;
z-index: 1050;
pointer-events: auto;
overflow-y: auto;
}
.modal__header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 15px;
border-bottom: 1px solid #eceeef;
}
.modal__title {
margin-top: 0;
margin-bottom: 0;
line-height: 1.5;
font-size: 1.25rem;
font-weight: 500;
}
.modal__btn-close {
float: right;
font-family: sans-serif;
font-size: 24px;
font-weight: 700;
line-height: 1;
color: #000;
text-shadow: 0 1px 0 #fff;
opacity: 0.5;
text-decoration: none;
}
.modal__btn-close:focus,
.modal__btn-close:hover {
color: #000;
text-decoration: none;
cursor: pointer;
opacity: 0.75;
}
.modal__body {
position: relative;
flex: 1 1 auto;
padding: 15px;
overflow: auto;
}
.modal__footer {
display: flex;
align-items: center;
justify-content: flex-end;
padding: 1rem;
border-top: 1px solid #e9ecef;
border-bottom-right-radius: 0.3rem;
border-bottom-left-radius: 0.3rem;
}

0
js/training/index.js Normal file
View File

164
js/training/modal.js Normal file
View File

@ -0,0 +1,164 @@
const request = new XMLHttpRequest();
const training_handler = () => {
const url = (condition) => {
return condition ? '/api/training/complete' : '/api/training/go_back';
};
request.open('POST', url(training_data().answer === null || training_data().answer === get_user_answer()))
request.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
request.onreadystatechange = function () {//Call a function when the state changes.
if (request.readyState === 4) {
if(request.status === 200) {
parent.frames['main'].location.reload();
}
if(request.responseText !== '') {
let response = JSON.parse(request.responseText);
if (response.message !== undefined) {
alert(response.message);
}
}
}
}
request.send(JSON.stringify({
time: training_data().time,
token: training_data().token,
short_name: training_data().short_name,
answer: get_user_answer(),
}))
}
function get_user_answer() {
if(training_data().answer === '') {
return '';
}
return document.getElementsByName('user_answer')[0].value;
}
(function () {
if (typeof window.CustomEvent === "function") return false;
function CustomEvent(event, params) {
params = params || { bubbles: false, cancelable: false, detail: null };
var evt = document.createEvent('CustomEvent');
evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail);
return evt;
}
window.CustomEvent = CustomEvent;
})();
$modal = function (options) {
var
_elemModal,
_eventShowModal,
_eventHideModal,
_hiding = false,
_destroyed = false,
_animationSpeed = 200;
function _createModal(options) {
var
elemModal = document.createElement('div'),
modalTemplate = '<div class="modal__backdrop" data-dismiss="modal"><div class="modal__content"><div class="modal__header"><div class="modal__title" data-modal="title">{{title}}</div><span class="modal__btn-close" data-dismiss="modal" title="Закрыть">×</span></div><div id="modal_content" class="modal__body" data-modal="content">{{content}}</div>{{footer}}</div></div>',
modalFooterTemplate = '<div class="modal__footer">{{buttons}}</div>',
modalInputAnswer = '',
modalButtonTemplate = '<button type="button" class="{{button_class}}" data-handler={{button_handler}}>{{button_text}}</button>',
modalHTML,
modal_content,
modalFooterHTML = '';
if(training_data().answer !== '') {
modalInputAnswer = '<br><br><input name="user_answer" placeholder="Укажите ответ"/>';
}
elemModal.classList.add('modal');
modalHTML = modalTemplate.replace('{{title}}', options.title || 'Новое окно');
if (options.footerButtons) {
for (var i = 0, length = options.footerButtons.length; i < length; i++) {
var modalFooterButton = modalButtonTemplate.replace('{{button_class}}', options.footerButtons[i].class);
modalFooterButton = modalFooterButton.replace('{{button_handler}}', options.footerButtons[i].handler);
modalFooterButton = modalFooterButton.replace('{{button_text}}', options.footerButtons[i].text) + modalInputAnswer;
modalFooterHTML += modalFooterButton;
}
modalFooterHTML = modalFooterTemplate.replace('{{buttons}}', modalFooterHTML);
}
modalHTML = modalHTML.replace('{{footer}}', modalFooterHTML);
elemModal.innerHTML = modalHTML;
document.body.appendChild(elemModal);
modal_content = document.getElementById('modal_content')
modal_content.innerHTML = options.content
return elemModal;
}
function _showModal() {
if (!_destroyed && !_hiding) {
_elemModal.classList.add('modal__show');
document.dispatchEvent(_eventShowModal);
}
}
function _hideModal() {
_hiding = true;
_elemModal.classList.remove('modal__show');
_elemModal.classList.add('modal__hiding');
setTimeout(function () {
_elemModal.classList.remove('modal__hiding');
_hiding = false;
}, _animationSpeed);
document.dispatchEvent(_eventHideModal);
}
function _handlerCloseModal(e) {
if (e.target.dataset.dismiss === 'modal') {
_hideModal();
}
}
_elemModal = _createModal(options || {});
_elemModal.addEventListener('click', _handlerCloseModal);
_eventShowModal = new CustomEvent('show.modal', { detail: _elemModal });
_eventHideModal = new CustomEvent('hide.modal', { detail: _elemModal });
return {
show: _showModal,
hide: _hideModal,
destroy: function () {
_elemModal.parentElement.removeChild(_elemModal),
_elemModal.removeEventListener('click', _handlerCloseModal),
_destroyed = true;
},
setContent: function (html) {
_elemModal.querySelector('[data-modal="content"]').innerHTML = html;
},
setTitle: function (text) {
_elemModal.querySelector('[data-modal="title"]').innerHTML = text;
}
}
};
let modal = $modal({
title: training_data().title,
content: training_data().content,
footerButtons: [
{
class: 'btn btn__ok',
text: 'Продолжить',
handler: 'next_step'
}
]
});
document.addEventListener('click', function (e) {
if (e.target.dataset.handler === 'next_step') {
training_handler()
}
})

View File

@ -25,14 +25,18 @@
</style>
<link href="/img.new-combats.com/css/main.css" rel="stylesheet" type="text/css">
<link rel="stylesheet" href="/css/training/modal.css">
<div class="se-pre-con" id="se-pre-con"></div>
<?php
if (!defined('GAME_VERSION')) {
require_once '_incl_data/autoload.php';
}
use Core\{Config, Database, Db};
use DarksLight2\Training\TrainingManager;
function var_info($vars, $d = false)
{
@ -53,6 +57,8 @@ $u = User::start();
$filter = new Filter();
$q = new Quests;
$training_manager = TrainingManager::getInstance($u->info['id']);
/** Восстанавливаем всем ботам, которые не в бою здоровье до максимума. */
Db::exec(
'update stats set hpNow = hpAll, mpNow = mpAll
@ -555,6 +561,7 @@ $spl = $spl['exp'];
echo '<script>top.myexpLineTop27(' . $u->info['exp'] . ',' . $spl . ');' . $tjs . 'top.ctest("' . $u->info['city'] . '");top.sd4key="' . $u->info['nextAct'] . '"; var battle = ' . (0 + $u->info['battle']) . '; top.hic();</script></body>
</html>';
$training_manager->render();
?>
<!--<script src="https://cdnjs.cloudflare.com/ajax/libs/modernizr/2.8.2/modernizr.js"></script>-->
<script>

View File

@ -139,6 +139,8 @@ function thisInfRm($id, $tp = null, $json = false)
}
if (isset($_GET['loc'])) {
$training_manager = \DarksLight2\Training\TrainingManager::getInstance();
$go = mysql_fetch_array(
mysql_query(
'SELECT * FROM `room` WHERE `code` = "' . mysql_real_escape_string(
@ -146,210 +148,228 @@ if (isset($_GET['loc'])) {
) . '" AND `city` = "' . $u->info['city'] . '" LIMIT 1'
)
);
$tr_pl = mysql_fetch_array(
mysql_query(
'SELECT `id`,`v1` FROM `eff_users` WHERE `id_eff` = 4 AND `uid` = "' . $u->info['id'] . '" AND `delete` = "0" ORDER BY `v1` DESC LIMIT 1'
)
);
//Проверяем костыли
$kos1 = mysql_fetch_array(
mysql_query(
'SELECT `id`,`item_id` FROM `items_users` WHERE `inOdet` = 3 AND `uid` = "' . $u->info['id'] . '" AND `delete` = 0 LIMIT 1'
)
);
$kos2 = mysql_fetch_array(
mysql_query(
'SELECT `id`,`item_id` FROM `items_users` WHERE `inOdet` = 14 AND `uid` = "' . $u->info['id'] . '" AND `delete` = 0 LIMIT 1'
)
);
if (in_array(
$go['file'],
$training_manager->getRegistered(
)[$training_manager->getCurrentStepName()]->allowedToMove()
)) {
if ($kos1['item_id'] == 630 || $kos1['item_id'] == 631) {
$kos1['good'] = 1;
} else {
$kos1['good'] = 0;
}
if ($kos2['item_id'] == 630 || $kos2['item_id'] == 631) {
$kos2['good'] = 1;
} else {
$kos2['good'] = 0;
}
$tr_pl = mysql_fetch_array(
mysql_query(
'SELECT `id`,`v1` FROM `eff_users` WHERE `id_eff` = 4 AND `uid` = "' . $u->info['id'] . '" AND `delete` = "0" ORDER BY `v1` DESC LIMIT 1'
)
);
if (isset($tr_pl['id'])) {
//Проверяем костыли
$kos1 = mysql_fetch_array(
mysql_query(
'SELECT `id`,`item_id` FROM `items_users` WHERE `inOdet` = 3 AND `uid` = "' . $u->info['id'] . '" AND `delete` = 0 LIMIT 1'
)
);
$kos2 = mysql_fetch_array(
mysql_query(
'SELECT `id`,`item_id` FROM `items_users` WHERE `inOdet` = 14 AND `uid` = "' . $u->info['id'] . '" AND `delete` = 0 LIMIT 1'
)
);
$zadej = 0;
if ($tr_pl['v1'] == 1) {
//все ок
} elseif ($tr_pl['v1'] == 2) {
if ($kos1['good'] == 0 && $kos2['good'] == 0) {
$re = 'Вы травмированы. Не возможно с такими увечиями передвигаться без костылей.';
$zadej = -1;
} else {
$zadej = 20;
}
} elseif ($tr_pl['v1'] == 3 || $tr_pl['v1'] == 4) {
if ($kos1['good'] == 0 || $kos2['good'] == 0) {
$re = 'Вы травмированы. Не возможно с такими увечиями передвигаться без костылей.';
$zadej = -1;
} else {
$zadej = 30;
}
if ($kos1['item_id'] == 630 || $kos1['item_id'] == 631) {
$kos1['good'] = 1;
} else {
$kos1['good'] = 0;
}
}
if ($u->room['extdlg'] > 0) {
header('location: main.php?talk=' . $u->room['extdlg'] . '');
} elseif (isset($zadej) && $zadej == -1) {
if (!isset($re) || $re == '') {
$re = 'У вас травма, нельзя перемещаться...';
if ($kos2['item_id'] == 630 || $kos2['item_id'] == 631) {
$kos2['good'] = 1;
} else {
$kos2['good'] = 0;
}
//Травма...
} elseif ($u->info['align'] == 2 && $go['nochaos'] == 1) {
$re = 'Проход для хаосников закрыт!';
} elseif ($u->info['inTurnir'] > 0) {
$re = 'Вы не можете перемещаться, Вы приняли заявку на турнир ...';
} elseif (($kos1['good'] == 0 && $kos2['good'] == 0) && ((!isset($zadej) || $zadej == 0) && $u->aves['now'] >= $u->aves['max'] && $u->room['name'] != 'Общежитие' && $u->room['name'] != 'Общ. Этаж 1' && $u->room['name'] != 'Общ. Этаж 2' && $u->room['name'] != 'Общ. Этаж 3')) {
$re = 'Вы не можете перемещаться, рюкзак переполнен ...';
} elseif (isset($go['id'])) {
$rmgo = [];
$rg = explode(',', $u->room['roomGo']);
$mlvl = explode('-', $go['level']);
$i = 0;
while ($i < count($rg)) {
if ($rg[$i] >= 0) {
$rmgo[$rg[$i]] = 1;
}
$i++;
}
$sleep = $u->testAction('`vars` = "sleep" AND `uid` = "' . $u->info['id'] . '" LIMIT 1', 1);
if (isset($sleep['id']) && $sleep['vars'] == 'sleep' && $go['name'] != 'Общ. Этаж 1' && $go['name'] != 'Общ. Этаж 2' && $go['name'] != 'Общ. Этаж 3') {
$re = '<font color=red><b>Вы можете перемещаться только когда бодрствуете.</b></font>';
echo '&nbsp;' . $re;
} elseif ($u->info['timeGo'] >= time()) {
$re = 'Вы не можете перемещаться еще ' . ($u->info['timeGo'] - time()) . ' сек.';
} elseif ($rmgo[$go['id']] == 1) {
$alg = explode('-', $go['align']);
$ku = mysql_fetch_array(
mysql_query('SELECT `id` FROM `katok_zv` WHERE `uid` = "' . $u->info['id'] . '" LIMIT 1')
);
if (isset($tr_pl['id'])) {
$zadej = 0;
if (isset($ku['id'])) {
$re = 'Вы подали заявку на турнир и не можете перемещаться...';
} elseif (($alg[0] > $u->info['align'] || $alg[1] < $u->info['align']) && $go['align'] != 0 && $u->info['admin'] == 0) {
$re = 'Ты не ту склонность выбрал.. Дружок :)';
} elseif ($u->info['zv'] > 0) {
$test_zv = mysql_fetch_array(
mysql_query(
'SELECT * FROM `zayvki` WHERE `id` = "' . $u->info['zv'] . '" AND `cancel` = 0 AND `start` = 0 AND `time` > "' . (time(
) - 60 * 60 * 2) . '" LIMIT 1'
)
);
if (isset($test_zv['id'])) {
$re = 'Подали заявку и убегаем?.. Не хорошо!';
if ($tr_pl['v1'] == 1) {
//все ок
} elseif ($tr_pl['v1'] == 2) {
if ($kos1['good'] == 0 && $kos2['good'] == 0) {
$re = 'Вы травмированы. Не возможно с такими увечиями передвигаться без костылей.';
$zadej = -1;
} else {
$re = 'Ваша заявка была удалена... Теперь вы можете перейти в другую локацию!';
mysql_query('UPDATE `stats` SET `zv` = 0 WHERE `id` = "' . $u->info['id'] . '" LIMIT 1');
$zadej = 20;
}
} elseif ((($go['clan'] > 0 && $u->info['clan'] != $go['clan']) || ($go['clan'] == -1 && $u->info['clan'] == 0)) && $u->info['admin'] == 0) {
$re = 'Вы не можете попасть в эту комнату';
} elseif ($go['sex'] > 0 && $go['sex'] - 1 != $u->info['sex'] && $u->info['invis'] != 1 && $u->info['invis'] < time(
) && $u->info['admin'] == 0) {
$re = 'Вы не можете попасть в эту комнату';
} elseif ($mlvl[0] > $u->info['level'] && $u->info['admin'] == 0) {
$re = 'Вы не можете попасть в эту комнату, уровень маловат ;)';
} elseif ($mlvl[1] < $u->info['level'] && $u->info['admin'] == 0) {
$re = 'Вы не можете попасть в эту комнату, уровень высоковат ;)';
} elseif ($go['close'] == 0 || $u->info['admin'] > 0) {
$travms = mysql_fetch_array(
} elseif ($tr_pl['v1'] == 3 || $tr_pl['v1'] == 4) {
if ($kos1['good'] == 0 || $kos2['good'] == 0) {
$re = 'Вы травмированы. Не возможно с такими увечиями передвигаться без костылей.';
$zadej = -1;
} else {
$zadej = 30;
}
}
}
if ($u->room['extdlg'] > 0) {
header('location: main.php?talk=' . $u->room['extdlg'] . '');
} elseif (isset($zadej) && $zadej == -1) {
if (!isset($re) || $re == '') {
$re = 'У вас травма, нельзя перемещаться...';
}
//Травма...
} elseif ($u->info['align'] == 2 && $go['nochaos'] == 1) {
$re = 'Проход для хаосников закрыт!';
} elseif ($u->info['inTurnir'] > 0) {
$re = 'Вы не можете перемещаться, Вы приняли заявку на турнир ...';
} elseif (($kos1['good'] == 0 && $kos2['good'] == 0) && ((!isset($zadej) || $zadej == 0) && $u->aves['now'] >= $u->aves['max'] && $u->room['name'] != 'Общежитие' && $u->room['name'] != 'Общ. Этаж 1' && $u->room['name'] != 'Общ. Этаж 2' && $u->room['name'] != 'Общ. Этаж 3')) {
$re = 'Вы не можете перемещаться, рюкзак переполнен ...';
} elseif (isset($go['id'])) {
$rmgo = [];
$rg = explode(',', $u->room['roomGo']);
$mlvl = explode('-', $go['level']);
$i = 0;
while ($i < count($rg)) {
if ($rg[$i] >= 0) {
$rmgo[$rg[$i]] = 1;
}
$i++;
}
$sleep = $u->testAction(
'`vars` = "sleep" AND `uid` = "' . $u->info['id'] . '" LIMIT 1',
1
);
if (isset($sleep['id']) && $sleep['vars'] == 'sleep' && $go['name'] != 'Общ. Этаж 1' && $go['name'] != 'Общ. Этаж 2' && $go['name'] != 'Общ. Этаж 3') {
$re = '<font color=red><b>Вы можете перемещаться только когда бодрствуете.</b></font>';
echo '&nbsp;' . $re;
} elseif ($u->info['timeGo'] >= time()) {
$re = 'Вы не можете перемещаться еще ' . ($u->info['timeGo'] - time(
)) . ' сек.';
} elseif ($rmgo[$go['id']] == 1) {
$alg = explode('-', $go['align']);
$ku = mysql_fetch_array(
mysql_query(
'SELECT * FROM `eff_users` WHERE `uid` = "' . $u->info['id'] . '" and (`v1`="2" or `v1`="3") and `delete`=0 ORDER by v1 DESC'
'SELECT `id` FROM `katok_zv` WHERE `uid` = "' . $u->info['id'] . '" LIMIT 1'
)
);
//замедление перемешения при травмах
$plus_timeGo = 0 + $zadej; // добавочное время при травме
if ($plus_timeGo < 0) {
$plus_timeGo = 0;
}
if (((!isset($zadej) || $zadej == 0) && $u->aves['now'] >= $u->aves['max'] && $u->room['name'] != 'Общежитие' && $u->room['name'] != 'Общ. Этаж 1' && $u->room['name'] != 'Общ. Этаж 2' && $u->room['name'] != 'Общ. Этаж 3')) {
$plus_timeGo += 2 * 60;
if ($kos1['good'] == 0) {
$plus_timeGo += 1.5 * 60;
} elseif ($kos1['good'] == 0) {
$plus_timeGo += 1.5 * 60;
}
}
//end freez time go
if ($u->stats['silver'] >= 1) {//время перемещения -20%
$go['timeGO'] = floor($go['timeGO'] / 100 * 80);
$plus_timeGo = floor($plus_timeGo / 100 * 80);
}
$u->info['timeGo'] = time() + $go['timeGO'] + $plus_timeGo;
$u->info['timeGoL'] = time();
$upd = mysql_query(
'UPDATE `stats` SET `timeGo` = "' . $u->info['timeGo'] . '",`timeGoL` = "' . $u->info['timeGoL'] . '" WHERE `id` = "' . $u->info['id'] . '" LIMIT 1'
);
if ($upd) {
$upd2 = mysql_query(
'UPDATE `users` SET `room` = "' . $go['id'] . '",`online` = "' . time(
) . '" WHERE `id` = "' . $u->info['id'] . '" LIMIT 1'
if (isset($ku['id'])) {
$re = 'Вы подали заявку на турнир и не можете перемещаться...';
} elseif (($alg[0] > $u->info['align'] || $alg[1] < $u->info['align']) && $go['align'] != 0 && $u->info['admin'] == 0) {
$re = 'Ты не ту склонность выбрал.. Дружок :)';
} elseif ($u->info['zv'] > 0) {
$test_zv = mysql_fetch_array(
mysql_query(
'SELECT * FROM `zayvki` WHERE `id` = "' . $u->info['zv'] . '" AND `cancel` = 0 AND `start` = 0 AND `time` > "' . (time(
) - 60 * 60 * 2) . '" LIMIT 1'
)
);
if (isset($test_zv['id'])) {
$re = 'Подали заявку и убегаем?.. Не хорошо!';
} else {
$re = 'Ваша заявка была удалена... Теперь вы можете перейти в другую локацию!';
mysql_query(
'UPDATE `stats` SET `zv` = 0 WHERE `id` = "' . $u->info['id'] . '" LIMIT 1'
);
}
} elseif ((($go['clan'] > 0 && $u->info['clan'] != $go['clan']) || ($go['clan'] == -1 && $u->info['clan'] == 0)) && $u->info['admin'] == 0) {
$re = 'Вы не можете попасть в эту комнату';
} elseif ($go['sex'] > 0 && $go['sex'] - 1 != $u->info['sex'] && $u->info['invis'] != 1 && $u->info['invis'] < time(
) && $u->info['admin'] == 0) {
$re = 'Вы не можете попасть в эту комнату';
} elseif ($mlvl[0] > $u->info['level'] && $u->info['admin'] == 0) {
$re = 'Вы не можете попасть в эту комнату, уровень маловат ;)';
} elseif ($mlvl[1] < $u->info['level'] && $u->info['admin'] == 0) {
$re = 'Вы не можете попасть в эту комнату, уровень высоковат ;)';
} elseif ($go['close'] == 0 || $u->info['admin'] > 0) {
$travms = mysql_fetch_array(
mysql_query(
'SELECT * FROM `eff_users` WHERE `uid` = "' . $u->info['id'] . '" and (`v1`="2" or `v1`="3") and `delete`=0 ORDER by v1 DESC'
)
);
if ($upd2) {
if ($u->room['file'] == 'bsenter' && $go['file'] != 'bsenter') {
//Удаляем все ставки в БС
$sp_bs = mysql_query(
'SELECT `id`,`bsid`,`money` FROM `bs_zv` WHERE `uid` = "' . $u->info['id'] . '" AND `inBot` = "0" AND `finish` = "0"'
);
while ($pl_bs = mysql_fetch_array($sp_bs)) {
//замедление перемешения при травмах
$plus_timeGo = 0 + $zadej; // добавочное время при травме
if ($plus_timeGo < 0) {
$plus_timeGo = 0;
}
if (((!isset($zadej) || $zadej == 0) && $u->aves['now'] >= $u->aves['max'] && $u->room['name'] != 'Общежитие' && $u->room['name'] != 'Общ. Этаж 1' && $u->room['name'] != 'Общ. Этаж 2' && $u->room['name'] != 'Общ. Этаж 3')) {
$plus_timeGo += 2 * 60;
if ($kos1['good'] == 0) {
$plus_timeGo += 1.5 * 60;
} elseif ($kos1['good'] == 0) {
$plus_timeGo += 1.5 * 60;
}
}
//end freez time go
if ($u->stats['silver'] >= 1) {//время перемещения -20%
$go['timeGO'] = floor($go['timeGO'] / 100 * 80);
$plus_timeGo = floor($plus_timeGo / 100 * 80);
}
$u->info['timeGo'] = time() + $go['timeGO'] + $plus_timeGo;
$u->info['timeGoL'] = time();
$upd = mysql_query(
'UPDATE `stats` SET `timeGo` = "' . $u->info['timeGo'] . '",`timeGoL` = "' . $u->info['timeGoL'] . '" WHERE `id` = "' . $u->info['id'] . '" LIMIT 1'
);
if ($upd) {
$upd2 = mysql_query(
'UPDATE `users` SET `room` = "' . $go['id'] . '",`online` = "' . time(
) . '" WHERE `id` = "' . $u->info['id'] . '" LIMIT 1'
);
if ($upd2) {
if ($u->room['file'] == 'bsenter' && $go['file'] != 'bsenter') {
//Удаляем все ставки в БС
$sp_bs = mysql_query(
'SELECT `id`,`bsid`,`money` FROM `bs_zv` WHERE `uid` = "' . $u->info['id'] . '" AND `inBot` = "0" AND `finish` = "0"'
);
while ($pl_bs = mysql_fetch_array($sp_bs)) {
mysql_query(
'UPDATE `bs_turnirs` SET `users` = `users` - 1 WHERE `id` = "' . $pl_bs['bsid'] . '" LIMIT 1'
);
}
unset($sp_bs, $pl_bs);
mysql_query(
'UPDATE `bs_turnirs` SET `users` = `users` - 1 WHERE `id` = "' . $pl_bs['bsid'] . '" LIMIT 1'
'UPDATE `bs_zv` SET `finish` = "' . time(
) . '" WHERE `uid` = "' . $u->info['id'] . '" AND `inBot` = "0" AND `finish` = "0"'
);
}
unset($sp_bs, $pl_bs);
mysql_query(
'UPDATE `bs_zv` SET `finish` = "' . time(
) . '" WHERE `uid` = "' . $u->info['id'] . '" AND `inBot` = "0" AND `finish` = "0"'
$smt = $u->testAction(
'`uid` = "' . $u->info['id'] . '" AND `time`>=' . (time(
) - 600) . ' AND `vars` = "create_snowball_cp" LIMIT 1',
1
);
if (isset($smt['id'])) {
mysql_query(
'DELETE FROM `actions` WHERE `id` = "' . $smt['id'] . '" LIMIT 1'
);
}
mysql_query(
'UPDATE `eff_users` SET `delete` = "' . time(
) . '" WHERE `id_eff` = "24" AND `uid` = "' . $u->info['id'] . '" AND `delete` = "0" LIMIT 24'
);
}
$smt = $u->testAction(
'`uid` = "' . $u->info['id'] . '" AND `time`>=' . (time(
) - 600) . ' AND `vars` = "create_snowball_cp" LIMIT 1', 1
);
if (isset($smt['id'])) {
mysql_query('DELETE FROM `actions` WHERE `id` = "' . $smt['id'] . '" LIMIT 1');
}
mysql_query(
'UPDATE `eff_users` SET `delete` = "' . time(
) . '" WHERE `id_eff` = "24" AND `uid` = "' . $u->info['id'] . '" AND `delete` = "0" LIMIT 24'
);
$u->info['room'] = $go['id'];
$u->room = $go;
if (!isset($_GET['mAjax'])) {
echo '<script>top.chat.reflesh();</script>';
$u->info['room'] = $go['id'];
$u->room = $go;
if (!isset($_GET['mAjax'])) {
echo '<script>top.chat.reflesh();</script>';
}
} else {
$re = 'Вы не смогли перейти в локацию, возможно она была разрушена';
}
} else {
$re = 'Вы не смогли перейти в локацию, возможно она была разрушена';
$re = 'Вы не смогли перейти в локацию';
}
} elseif ($go['destroy'] == 1) {
$re = 'Здание было разрушено, в данный момент оно реставрируется';
} else {
$re = 'Вы не смогли перейти в локацию';
$re = 'Временно закрыто';
}
} elseif ($go['destroy'] == 1) {
$re = 'Здание было разрушено, в данный момент оно реставрируется';
} else {
$re = 'Временно закрыто';
$re = 'Проход не существует';
}
} else {
$re = 'Проход не существует';
}
} else {
$re = 'Проход не существует';
$re = 'Вам запрещено передвигаться до окончания обучения!!!';
}
}

View File

@ -1,4 +1,7 @@
<?php
use DarksLight2\Training\TrainingManager;
if (!defined('GAME')) {
die();
}
@ -441,6 +444,16 @@ $tma = '';
WHERE
`id` = '" . (int)$u->info['id'] . "';"
)) {
if((int)$u->info['ability'] === 0 && (int)$u->info['skills'] === 0) {
TrainingManager::getInstance()
->addPoint(
'my_user_third_quest',
function (TrainingManager $manager) {
$manager->store();
}
);
}
//if($_GET['energy']>0) {echo '&nbsp; &nbsp;<font color=red>Увеличение способности "<B>Энергия</B>" произведено удачно</font><br>';}
if ($_GET['str'] > 0) {
echo '&nbsp; &nbsp;<font color=red>Увеличение способности "<B>Сила</B>" произведено удачно</font><br>';

View File

@ -1,13 +1,12 @@
<?
if(!defined('GAME'))
{
die();
}
require_once('/home/newcom1/public_html/_incl_data/__config.php');
require_once('/home/newcom1/public_html/_incl_data/class/__db_connect.php');
if($u->room['file']=='cp1')
{
if($u->room['file']=='cp1') {
if(date("H")>=8 && date("H")<=23) {
$now = 'day';
$tattack = '<a style="color:#D8D8D8" style="cursor:pointer" onclick="top.useMagic(\'Нападение на персонажа\',\'night_atack\',\'pal_button8.gif\',1,\'main.php?nightatack=1\');">Напасть на игрока</a> &nbsp; ';

View File

@ -1,11 +0,0 @@
<?php
use DarksLight2\Training\TrainingManager;
$short_name = 'first_step';
$manager = TrainingManager::getInstance();
var_dump($manager->$short_name->progress);
echo 'it\'s work';

View File

@ -0,0 +1,38 @@
<?php
DarksLight2 marked this conversation as resolved
Review

Точно классы вызовутся без загрузчика?

Точно классы вызовутся без загрузчика?
Review

этот файл инклудится, чтобы не дублировать код вынес в отдельный файл

этот файл инклудится, чтобы не дублировать код вынес в отдельный файл
/**
* @var string $short_name
* @var $answer
* @var \DarksLight2\Training\StepFactory $step
*/
$user = User::start();
use DarksLight2\Training\TrainingManager;
$manager = TrainingManager::getInstance();
$step = $manager->getRegistered()[$short_name];
$time = time();
$token = password_hash($manager->getDatabaseData()['api_token'] . $time . $user->info['id'], PASSWORD_DEFAULT);
?>
<script>
const training_data = () => {
return {
content: `<?=$step->getMessage()?>`,
title: `<?=$step->getTitle()?>`,
time: <?=$time?>,
token: '<?=$token?>',
short_name: '<?=$short_name?>',
answer: '<?=$answer?>'
}
}
</script>
<script src="/js/training/modal.js"></script>
<script>
modal.show()
</script>

View File

@ -7,6 +7,7 @@ if (!defined('GAME_VERSION')) {
use Core\Config;
use Core\Database;
use Core\Db;
use DarksLight2\Training\TrainingManager;
Config::init();
@ -265,6 +266,18 @@ if (isset($_POST['msg']) && str_replace(' ', '', $_POST['msg']) != '') {
mysql_query("UPDATE `chat` SET `delete` = 1 WHERE `login` = '" . $u->info['login'] . "' LIMIT 1000");
$_POST['msg'] = 'Я спамер ' . $u->info['login'] . ' и меня нужно заблокировать https://new-combats.com/info/' . $u->info['id'] . '';
$training_manager = TrainingManager::getInstance();
Review

И эта штука один раз отработала и дальше будет вхолостую колбаситься на каждое сообщение в чате?

И эта штука один раз отработала и дальше будет вхолостую колбаситься на каждое сообщение в чате?
Review

Я не знал как по другому, может не додумал

Я не знал как по другому, может не додумал
$training_manager->addPoint('chat_first_quest');
if(preg_match("/to\[(.*?)\]/", $_POST['msg'])) {
$training_manager->addPoint('chat_second_quest');
}
if(preg_match("/private\[(.*?)\]/", $_POST['msg'])) {
$training_manager->addPoint('chat_third_quest');
}
mysql_query(
'INSERT INTO `chat` (`nosee`,`invis`,`da`,`delete`,`molch`,`new`,`login`,`to`,`city`,`room`,`time`,`type`,`spam`,`text`,`toChat`,`color`,`typeTime`,`sound`,`global`) VALUES (
"0",

View File

@ -1,33 +0,0 @@
<?php
use DarksLight2\Training\Steps\FirstStep;
use DarksLight2\Training\TrainingException;
use DarksLight2\Training\TrainingManager;
if (session_status() === PHP_SESSION_NONE) {
session_start();
}
if (isset($_GET['unset'])) {
session_unset();
}
if (!defined('GAME_VERSION')) {
require_once '_incl_data/autoload.php';
}
$user = User::start();
$manager = TrainingManager::getInstance($user->info['id']);
$manager->createDatabaseRecord();
try {
$manager->register([
new FirstStep(),
]);
} catch (TrainingException $e) {
}
if(!$manager->first_step->complete) {
$manager->first_step->render();
}