Обучение #39
@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
const GAME = true; // Для совместимости с этой "защитой".
|
||||
const GAME_VERSION = 'alpha-7.4';
|
||||
// Новая автозагрузка.
|
||||
|
11
_incl_data/class/DarksLight2/Helpers/Str.php
Normal 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));
|
||||
}
|
||||
}
|
@ -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,
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
}
|
@ -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
|
||||
|
||||
{
|
||||
return 'first_step';
|
||||
return 'chat_first_quest';
|
||||
}
|
||||
|
||||
public function isInfo(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
@ -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 [];
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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';
|
||||
}
|
||||
|
||||
}
|
@ -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 [];
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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 '';
|
||||
}
|
||||
|
||||
}
|
@ -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 'Уворотов и Силачей';
|
||||
}
|
||||
|
||||
}
|
@ -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 [];
|
||||
}
|
||||
|
||||
}
|
@ -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'];
|
||||
}
|
||||
|
||||
}
|
@ -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'];
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
DarksLight2 marked this conversation as resolved
Outdated
lopar
commented
Прямая зависимость от PDO? Где? Как? Прямая зависимость от PDO? Где? Как?
DarksLight2
commented
ого, я даже не заметил, без понятия как оно туда попало) ого, я даже не заметил, без понятия как оно туда попало)
|
||||
|
||||
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) {
|
||||
lopar
commented
Я бы от греха подальше проверил бы хотя бы на Я бы от греха подальше проверил бы хотя бы на `> 0`, а в идеале на валидное значение. Прилетит некондит, привет "всё сломалось".
DarksLight2
commented
В идеале в айдишнике юзера не должно быть значения В идеале в айдишнике юзера не должно быть значения `<= 0`
Просто подумай, как такое вообще должно работать, если туда куда не надо попадают не те значения?) и все же я думаю что эта проверка должна быть уровнем высше, чтобы не засорять код глупыми `if($u->info['id'] > 0)`
lopar
commented
У нас есть класс User на 12 тысяч строк. Можем сначала полностью переделать его, чтобы id точно, гарантированно, никогда не мог быть невалидным. Рефакторинг старого кода, он такой. У нас есть класс 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()
|
||||
DarksLight2 marked this conversation as resolved
Outdated
lopar
commented
Вроде как полностью дублирует метод PassGen::new(). Вроде как полностью дублирует метод PassGen::new().
DarksLight2
commented
не знал о таком, но посмотрю не знал о таком, но посмотрю
|
||||
{
|
||||
$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
lopar
commented
Если нет особой необходимости, лучше использовать стандартный Db::getRows(), для единообразия. Если нет особой необходимости, лучше использовать стандартный Db::getRows(), для единообразия.
DarksLight2
commented
Выбрал этот путь, потому что только одна запись там должна быть. Выбрал этот путь, потому что только одна запись там должна быть.
lopar
commented
Тогда 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) {
|
||||
DarksLight2 marked this conversation as resolved
Outdated
lopar
commented
Db:sql() Db:sql()
DarksLight2
commented
А смысл, если этот метод все равно вызывает run?) А смысл, если этот метод все равно вызывает run?)
lopar
commented
run изначально приватный медод, который cтал публичным потому что где-то в паре мест понадобился доступ к PDOStatement. run изначально приватный медод, который cтал публичным потому что где-то в паре мест понадобился доступ к PDOStatement.
|
||||
$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;
|
||||
$this->registered_steps[$step->getShortName()] = $step;
|
||||
}
|
||||
}
|
||||
}
|
||||
private function generateToken($length = 16)
|
||||
{
|
||||
|
||||
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;
|
||||
Db::run('UPDATE user_training SET api_token = ? WHERE user_id = ?', [
|
||||
PassGen::new($length),
|
||||
$this->user_id
|
||||
]);
|
||||
}
|
||||
|
||||
DarksLight2 marked this conversation as resolved
Outdated
lopar
commented
Так ты если запрос сюда перенёс, то и переменную хорони, которую ты создаёшь в памяти и без изменений пишешь в базу. :) Так ты если запрос сюда перенёс, то и переменную хорони, которую ты создаёшь в памяти и без изменений пишешь в базу. :)
|
||||
public function createDatabaseRecord()
|
||||
{
|
||||
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($data, true),
|
||||
array_key_first($data)
|
||||
]);
|
||||
|
||||
$this->database = Db::getRow('SELECT * FROM user_training WHERE user_id = ?', [$this->user_id]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \DarksLight2\Training\TrainingException
|
||||
*/
|
||||
public function render()
|
||||
{
|
||||
$path = $_SERVER['DOCUMENT_ROOT'] . '/modules_data/steps/' . $this->short_name . '.php';
|
||||
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';
|
||||
|
||||
if (file_exists($path)) {
|
||||
$short_name = $this->getCurrentStepName();
|
||||
$answer = $this->registered_steps[$this->getCurrentStepName()]->getAnswer();
|
||||
require $path;
|
||||
return;
|
||||
}
|
||||
|
||||
throw TrainingException::noRenderingFile();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function stepData(string $short_name): object
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
public function createDatabaseRecord()
|
||||
{
|
||||
if(!$this->getDatabaseRecords()) {
|
||||
Db::run('INSERT INTO user_training (user_id, data) VALUES (?, ?)', [
|
||||
$this->user_id,
|
||||
json_encode($this->firstRecordData())
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
private function firstRecordData(): array
|
||||
{
|
||||
return [
|
||||
'first_step' => [
|
||||
'complete' => 0,
|
||||
'progress' => [
|
||||
'current' => 0,
|
||||
'need' => 0,
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function __get(string $name)
|
||||
{
|
||||
return $this->steps[$name];
|
||||
}
|
||||
|
||||
public function addPoint(string $short_name)
|
||||
{
|
||||
$this->$short_name->progress++;
|
||||
}
|
||||
|
||||
public function store()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
@ -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
@ -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
@ -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' => 'Вы указали не верный ответ!']));
|
||||
DarksLight2 marked this conversation as resolved
Outdated
lopar
commented
Тут либо "вы указали" либо "ты указал". :) Тут либо "вы указали" либо "ты указал". :)
DarksLight2
commented
Ну проебался чутка) Ну проебался чутка)
|
||||
|
||||
}
|
||||
}
|
||||
}
|
94
css/training/modal.css
Normal 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
164
js/training/modal.js
Normal 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()
|
||||
}
|
||||
})
|
7
main.php
@ -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;
|
||||
DarksLight2 marked this conversation as resolved
Outdated
lopar
commented
Нужны ли игроку технические исключения? Нужны ли **игроку** технические исключения?
DarksLight2
commented
Солгасен, тупанул Солгасен, тупанул
|
||||
|
||||
function var_info($vars, $d = false)
|
||||
{
|
||||
DarksLight2 marked this conversation as resolved
Outdated
lopar
commented
На На https://src.lopar.space/new-combats.com/game/src/commit/dcc6a1337c861b9f2dfd957aeebc6e1c6d8cc85b/main.php#L59 вызывается инстанс User. Зачем вызывать ещё один на 20 строк выше?
DarksLight2
commented
Не обратил внимание) Не обратил внимание)
|
||||
@ -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>
|
||||
|
@ -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,6 +148,13 @@ if (isset($_GET['loc'])) {
|
||||
) . '" AND `city` = "' . $u->info['city'] . '" LIMIT 1'
|
||||
)
|
||||
);
|
||||
|
||||
if (in_array(
|
||||
$go['file'],
|
||||
$training_manager->getRegistered(
|
||||
)[$training_manager->getCurrentStepName()]->allowedToMove()
|
||||
)) {
|
||||
|
||||
$tr_pl = mysql_fetch_array(
|
||||
DarksLight2 marked this conversation as resolved
Outdated
lopar
commented
Куча замен ниже, это тоже про обучение? Костыли, увечья, хаосники, турниры.. Куча замен ниже, это тоже про обучение? Костыли, увечья, хаосники, турниры..
DarksLight2
commented
Я не понимаю почему это добавилось, наверное потому что я обернул в условие. Я хз Я не понимаю почему это добавилось, наверное потому что я обернул в условие. Я хз
|
||||
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'
|
||||
@ -176,7 +185,6 @@ if (isset($_GET['loc'])) {
|
||||
}
|
||||
|
||||
if (isset($tr_pl['id'])) {
|
||||
|
||||
$zadej = 0;
|
||||
|
||||
if ($tr_pl['v1'] == 1) {
|
||||
@ -218,20 +226,25 @@ if (isset($_GET['loc'])) {
|
||||
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);
|
||||
$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 ' ' . $re;
|
||||
} elseif ($u->info['timeGo'] >= time()) {
|
||||
$re = 'Вы не можете перемещаться еще ' . ($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')
|
||||
mysql_query(
|
||||
'SELECT `id` FROM `katok_zv` WHERE `uid` = "' . $u->info['id'] . '" LIMIT 1'
|
||||
)
|
||||
);
|
||||
|
||||
if (isset($ku['id'])) {
|
||||
@ -249,7 +262,9 @@ if (isset($_GET['loc'])) {
|
||||
$re = 'Подали заявку и убегаем?.. Не хорошо!';
|
||||
} else {
|
||||
$re = 'Ваша заявка была удалена... Теперь вы можете перейти в другую локацию!';
|
||||
mysql_query('UPDATE `stats` SET `zv` = 0 WHERE `id` = "' . $u->info['id'] . '" LIMIT 1');
|
||||
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 = 'Вы не можете попасть в эту комнату';
|
||||
@ -299,7 +314,6 @@ if (isset($_GET['loc'])) {
|
||||
) . '" WHERE `id` = "' . $u->info['id'] . '" LIMIT 1'
|
||||
);
|
||||
if ($upd2) {
|
||||
|
||||
if ($u->room['file'] == 'bsenter' && $go['file'] != 'bsenter') {
|
||||
//Удаляем все ставки в БС
|
||||
$sp_bs = mysql_query(
|
||||
@ -319,10 +333,13 @@ if (isset($_GET['loc'])) {
|
||||
|
||||
$smt = $u->testAction(
|
||||
'`uid` = "' . $u->info['id'] . '" AND `time`>=' . (time(
|
||||
) - 600) . ' AND `vars` = "create_snowball_cp" LIMIT 1', 1
|
||||
) - 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(
|
||||
'DELETE FROM `actions` WHERE `id` = "' . $smt['id'] . '" LIMIT 1'
|
||||
);
|
||||
}
|
||||
mysql_query(
|
||||
'UPDATE `eff_users` SET `delete` = "' . time(
|
||||
@ -351,6 +368,9 @@ if (isset($_GET['loc'])) {
|
||||
} else {
|
||||
$re = 'Проход не существует';
|
||||
}
|
||||
} else {
|
||||
$re = 'Вам запрещено передвигаться до окончания обучения!!!';
|
||||
}
|
||||
}
|
||||
|
||||
if ($u->info['room'] == 209) {
|
||||
|
@ -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) {
|
||||
DarksLight2 marked this conversation as resolved
Outdated
lopar
commented
А если человек поднимет не стат, а навык или особенность? Он пройдёт квест так и не подняв стат. А если человек поднимет не стат, а навык или особенность? Он пройдёт квест так и не подняв стат.
DarksLight2
commented
упс, не заметил, я думал там только ability меняется упс, не заметил, я думал там только ability меняется
|
||||
TrainingManager::getInstance()
|
||||
->addPoint(
|
||||
'my_user_third_quest',
|
||||
function (TrainingManager $manager) {
|
||||
$manager->store();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
//if($_GET['energy']>0) {echo ' <font color=red>Увеличение способности "<B>Энергия</B>" произведено удачно</font><br>';}
|
||||
if ($_GET['str'] > 0) {
|
||||
echo ' <font color=red>Увеличение способности "<B>Сила</B>" произведено удачно</font><br>';
|
||||
|
@ -1,13 +1,12 @@
|
||||
<?
|
||||
|
||||
if(!defined('GAME'))
|
||||
{
|
||||
die();
|
||||
}
|
||||
require_once('/home/newcom1/public_html/_incl_data/__config.php');
|
||||
DarksLight2 marked this conversation as resolved
Outdated
lopar
commented
Убирая где-то Убирая где-то `__config.php` и `__db_connect.php` надо вместо них вызывать `Config::init()` и `Database::init()`. Первое подтягивает настройки, второе подтягивает функции `mysql_`.
DarksLight2
commented
Я же убирал галочку ( Я же убирал галочку (
|
||||
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> ';
|
||||
|
@ -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';
|
38
modules_data/steps/step.php
Normal file
@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
DarksLight2 marked this conversation as resolved
lopar
commented
Точно классы вызовутся без загрузчика? Точно классы вызовутся без загрузчика?
DarksLight2
commented
этот файл инклудится, чтобы не дублировать код вынес в отдельный файл этот файл инклудится, чтобы не дублировать код вынес в отдельный файл
|
||||
/**
|
||||
DarksLight2 marked this conversation as resolved
Outdated
lopar
commented
Не надо такое прописывать в отдельных файлах, чтобы потом общие настройки игнорировались и перезаписывались. Не надо такое прописывать в отдельных файлах, чтобы потом общие настройки игнорировались и перезаписывались.
DarksLight2
commented
Я для себя ставил и забыл убрать( Я для себя ставил и забыл убрать(
|
||||
* @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);
|
||||
DarksLight2 marked this conversation as resolved
Outdated
lopar
commented
Если это константа, тогда зачем нужна переременная? Сразу в скрипт её. Если это константа, тогда зачем нужна переременная? Сразу в скрипт её.
DarksLight2
commented
Я там думал менять текст при вопросах, квестах и просто информационных блоках, но забыл) Я там думал менять текст при вопросах, квестах и просто информационных блоках, но забыл)
|
||||
?>
|
||||
|
||||
<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>
|
13
online.php
@ -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();
|
||||
lopar
commented
И эта штука один раз отработала и дальше будет вхолостую колбаситься на каждое сообщение в чате? И эта штука один раз отработала и дальше будет вхолостую колбаситься на каждое сообщение в чате?
DarksLight2
commented
Я не знал как по другому, может не додумал Я не знал как по другому, может не додумал
|
||||
|
||||
$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",
|
||||
|
33
test.php
@ -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();
|
||||
}
|
Это методы, возвращающие.. константу?
Это добавляет гибкости. Захочешь ты для определённого задания сделать логику отличную от других, сможешь спокойно это сделать, плюс я уже убедился что это хорошое решение, когда решил переписать логику трейнинга.