Перейти к публикации
Поиск в
  • Дополнительно...
Искать результаты, содержащие...
Искать результаты в...
  • Нужна помощь?

    Создайте тему в соответствующем разделе
    Не нужно писать всё в чат!
  • Загляните на торговую площадку

    Там вы можете купить
    всё что касается игровых серверов
  • Не хотите бан?

    Пожалуйста, ознакомьтесь с нашими правилами
    Не нарушайте порядок!
  • Продаёте или покупаете?

    Пользуйтесь услугами гаранта
    Мы сделаем вашу сделку безопасной
BorizzK

DAYZ enScript (вопросы, ответы)

Рекомендованные сообщения

BorizzK А!..Понял. Сама по себе CallLater() , помещает первый свой аргумент в очередь вызовов, с интервалом заданным вторым аргументом. Третий аргумент - флаг повторения вызова. Так?

"Поставь Васю в очередь, окликни Васю через Х/1000  секунд, (повторяй/не повторяй)". Так?

Что за очереди и почему именно эта очередь?

Изменено пользователем VIRrusR (история изменений)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
MagicByte MagicByte MagicByte

VIRrusR 

Небольшое отступление про Call и CallLater

 

CallLater фактически позволяет

Выполнить нужную функцию

1 Позже (с задержкой)

2 Повторять вызов одной и той же функции

 

Call - не разбирался - не было нужды такой

 

Очереди - я предполагаю что это очереди имеющие разные приоритеты - чем выше номер тем ниже приоритет

их всего 3, а на сервере 2

 

CALL_CATEGORY_SYSTEM = 0;

CALL_CATEGORY_GUI = 1; // (это только на клиенте)

CALL_CATEGORY_GAMEPLAY = 2;

 

есть нюанс небольшой с которым я столкнулся

 

Надо оттэпэшить игрока указатель на которого уже есть в переменной player

и тебе ее надо выполнить скажем на 1 сек позже чем вызов

 

vector a = "10 10 10";

GetGame().GetCallQueue(2).CallLater(player.SetPosition, 1000, false, a); // false - значит выполнять 1 раз (если укажем trueть будет повторять каждые 1сек)

и вот тут будет ошибка - что-т там неверный тип данных или типа того и краш при компиляции

Вобщем через Call и CallLater ты не можешь передать параметр типа vector - будет ошибка - почему? спроси у Богемии

Вобщем передавать надо каждый элемент вектора (вектор это по сути статический массив из 3х эелементов)

 

Обходим это дело так

 

Пишем функцию в своем класса (ну где мы ее вызывать будем или в другом к которому сможем обратиться класс.нашафункция)

 

MyFunc(float a, float b, float c, PlayerBase player) // первые три параметра это будут координаты, ну а 4й будет указателем на перса игрока)

{

  player.SetPosition(Vector(a,b,c));

}

 

и уже где надо вызовем

 

vector pos = "6000 200 6000";

GetGame().GetCallQueue(CALL_CATEGORY_SYSTEM).CallLater(MyFunc, 1000, false, pos[0], pos[1], pos[2], player);

 

и вуаля

 

все работает

 

Изменено пользователем BorizzK (история изменений)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

VIRrusR 

Ага - все по сути так

 

Про синтаксис вызова - на всяк случай

 

Если вызывать MyFunc(float a, float b, float c, PlayerBase player) напрямую

MyFunc(pos[0], pos[1], pos[2], player)

 

если через CallLater

CallLater(MyFunc, время в мс, true - повторять / false - не повторять, pos[0], pos[1], pos[2], player)

 

Что касается бякости

 

Чем позже в процессе игры был сделан вызов CallLater тем ниже в той же очереди будет его приоритет

 

потому все что было закатано в очередь при старте сервера выполняется исправно

 

а что позже - скажем грохнули игрока и хотим труп через CallLater убрать через 300сек (300 000мс)

то оно в очередь встанет - но выполнится может и через 10 минут

 

Хотя с последним обновлением вроде лучше работать стало

 

Изменено пользователем BorizzK (история изменений)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

BorizzK ,погодь ты ТПшить!.. :relaxed:

То всё частные случаи!

А мне надоть вразуметь, что за очереди такие, куда мы Васю нашего пхаем, чтоб его каждые Х секунд потом дёргать! :joy:

1-й тип, как я понимаю, нам нафик, ибо вызывает другого Васю, который вообще не из нашей песочницы.

2-й и 3-й типы.

Я так из названий догадываюсь, что 2-й, это всё, что касается "игровых" функций, будь то пользовательских или нативных - не суть! Главно, что это про скрипты? А 3-й - это системное, всякие там проблемы "двигла", прерывания,сетевые протоколы и прочая заумь, в которую нам лучше даже не соваться?

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

VIRrusR ненене - системное, всякие там проблемы "двигла", прерывания,сетевые протоколы и прочая заумь, в которую нам лучше даже не соваться

это вообще из другой оперы

 

3 очереди - описаны в Game.c

 

  Returns CallQueue for certain category
  @param call_category call category, valid values are:
	\n CALL_CATEGORY_SYSTEM - calls & timers in this queue are processed every time without any restrictions
	\n CALL_CATEGORY_GUI - calls & timers in this queue are processed when GUI is enabled (even during pase game)
	\n CALL_CATEGORY_GAMEPLAY - calls & timers in this queue are processed only during mission, when game is not paused
	\n usage:
	* @code
	* GetGame().GetCallQueue(CALL_CATEGORY_GUI).Call(this, "Refresh"); // calls "Refresh" function on "this" with no arguments
	* GetGame().GetCallQueue(CALL_CATEGORY_GUI).Call(this, "Show", new Param1<bool>(true)); // calls "Show" function on "this" with one bool argument
	* GetGame().GetCallQueue(CALL_CATEGORY_GUI).Call(this, "SetPos", new Param2<float, float>(0.2, 0.5)); // calls "SetPos" function on "this" with two float arguments
	* @endcode
	*/

ну и в tool.c их значения

 

const int CALL_CATEGORY_SYSTEM = 0; // Runs always
const int CALL_CATEGORY_GUI = 1; // Runs always (on client)
const int CALL_CATEGORY_GAMEPLAY = 2; // Runs unless ingame menu is opened

про их значения я там выше ошибся (писал по памяти)

потому на стороне сервера я юзаю _SYSTEM

 

перечитай мои предыдущие 2 поста - я там поправил кой-чего

Изменено пользователем BorizzK (история изменений)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Только что, BorizzK сказал:

CALL_CATEGORY_SYSTEM - calls & timers in this queue are processed every time without any restrictions

"Вызовы и таймеры в этой очереди обрабатываются всё время (постоянно) без любых условий" - верно перевёл? Я в языке странном слабо...

То есть, если бы в нашем скрипте мы использовали этот тип очереди, то проверка бы производилась постоянно, с момента включения сервера, до завершения его работы, так?

Только что, BorizzK сказал:

CALL_CATEGORY_GAMEPLAY - calls & timers in this queue are processed only during mission, when game is not paused

"Вызовы и таймеры в этой очереди обрабатываются только во время миссии, когда игра не приостановлена" 

Я что-то не догнал, о чём речь и в чём разница? Суть очередь 2-го типа с флагом true тоже, что 3-го... Или нет?

...Или тут БИСова собака порылась в том, что 2-й тип это "на игрока", а 3-й - "на сервер"? В том смысле, что если наш Вася из игры сдрыснет, то при использовании очереди CALL_CATEGORY_GAMEPLAY (2) для него все проверки будут приостановлены, до момента, когда он снова в игре обнаружится.

А если по CALL_CATEGORY_SYSTEM (3), то Вася наш проснётся, а голова его в тумбочке, потому, что сервер продолжит долбить его проверкой, хотя Васи то и нет? 

Или о чём речь? 3-й тип непременим к объектам, а лишь к процессам?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

VIRrusR Наверное так оно и есть

Для всех функций которые на игроков я применяю GAMEPLAY

А вдминке для себя SYSTEM

Ну там вывести мне список игроков в чат - все с задержкой - а то быстро пробежит и не увидишь ничего и команду стоп не отдашь

Но хотя бы после крайнего обновления работать бм ровно стало

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

BorizzK ,"наверное" это как бэ-э...:sad:

Возможно как раз на эту тему и как раз про наш скрипт "заражённых зон", случай из жизни:

 

У меня на сервере в данный момент используется исходный вариант от elanc с нашей модификацией проверки на состояние защиты. Кроме того, я к симптомам ещё рвоту дописал, ну я об этом уже говорил... Так вот, затеялись мы как-то своей компашкой на машине по делам своим тёмным промотнуться. А путь наш разбойничий через Зеленогорск лежал. А там, как раз зона заражённая прописана, ну, ты в курсе. Ну и не стали мы городишко то объезжать - так и рванули напрямки. Само-собой, всё чин по чину, урон мы получили, пока через город неслись... Покашляли малость, да и помчали себе дальше. Да...

Приехали, стало быть. Надоть из машинёнки вылезать, да зобмачков местных, что на шум движка сбежалися, резать стало быть... Ну мы ножики в зубы и из машины то повыпрыгивали, ага. ...Вот тут то  нас и накрыло! Да так, что саму малость нас не порвали там в клочья - спасибо встречал нас человек надёжный, который ходунцов местных, кровушкой истекая сам, поупокоил всех, пока нас наизнанку выворачивало. Такая вот тебе быль про CallLater() и очереди стало быть...

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

VIRrusR Вот тут то  нас и накрыло - это как?

 

Аааа - рвота

Ну так рвота не сразу начинается

А несколько позже

Ручками ее на игрока навешивать надо аккуратно

Ее потом тем же таймером по состоянию здоровья над убирать

Изменено пользователем BorizzK (история изменений)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

BorizzK , не... Так оно хорошо получается - вродь как пронеслись быстро, потому и покашляли только, а уж как приехали - отходнячок догнал :wink:

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

BorizzK , в CallLater параметр CheckZones - поясни. Я не вижу такой переменной. Это функция? Или метод? Я так понимаю, что это проверка нашего класса ZonesClass{} ,вызываемая через указатель Zones? Но не пойму, что она должна вернуть?..

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

VIRrusR Поехали дальше

обсудим чо таймер вызывает как оно потом работает и что в свою очередь вызывает

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

BorizzK ,как раз вопрос задал, одновременно с твоим постом )))

Дальше там незнакомые мне матюки сплошь... 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

VIRrusR Ну выше же обсудили

я еще правок в нес про синтаксис калллатер

 

в CallLater параметр CheckZones - поясни. Я не вижу такой переменной. Это функция? Или метод? Я так понимаю, что это проверка нашего класса ZonesClass{} ,вызываемая через указатель Zones? Но не пойму, что она должна вернуть?..

 

CheckZones - функция (она там внизу)

мы отправляем ее вызов в очередь вызовов и движок ее в цикле (true стоит) каждые zone_Check_Timer секунд взывает на исполнение (разумеется в контексте класса где она расположена)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Только что, BorizzK сказал:

CheckZones - функция (она там внизу)

Не вижу! Блин, да что за язык такой?! Чтоб найти что-то, надо десять раз весь листинг из начала в конец и обратно перелопатить!:veryangry:

Пальцем ткни! Где "там внизу"?

Изменено пользователем VIRrusR (история изменений)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

BorizzK , всё нашёл - спасибо NotePad!

Пытаюсь понять, чего она делает...

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

BorizzK , GetPlayers (players) нативная функция "взять игроков". Что делает? Зачем мы в неё указатель на массив запихиваем?

Далее вся функция для меня набор  букв... Рассказывай.

Изменено пользователем VIRrusR (история изменений)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
	void CheckZones()
	{
		ref array<Man> players = new array<Man>; //обьявили локальный массив указателей который будет указатели на игроков
		GetGame().GetPlayers( players ); //нативная функция GetPlayers из класса cGame (GetGame() - глобальная функция возвращающая указатель на этот класс) в ранее обьявленный нами массив players запихнула указатели на всех игроков играющих на сервере - и возвращает она указатели класса MAN - потому и массив класса MAN
		for ( int i = 0; i < players.Count(); i++ ) // Цикл 1 //перечисление игроков - последовательно будет выполняться для каждого элемента массива  players пока i не станет равно максимальному номеру элемента массива players - players.Count() возвращает кол-во элементов в массиве
		{
			PlayerBase player = PlayerBase.Cast(players[i]); //тк массив у нас относится к классу MAN, а PlayerBase дочерний для него - даункастим очередной элемент массива players[i] содержащий указатель на очередного игрока в переменную класса PlayerBase, что бы можно было применять к этому игроку(обьекту игрока/персонажу игрока) методы из класса Playerbase
			if (player.GetIdentity()) //если перс имеет идентичность - те связан с клиентом - в то вдруг за пару мс до этого игрок отключился и перс идентичность потерял - дальнейшая работа для этого перса тогда теряет смысл и мы его пропустим не выполнив следующий цикл
			{ //.. то
				for ( int j = 0; j < ga_zones.Count(); j++ ) // Цикл 2 // берем наш массив в которые загнаны все указатели на созданные экземпляры класса Zone - в которых параметры зон - и последовательно перебираем
				{
					if (InZone(player, ga_zones[j])) break; //А тут для каждого указателя на экземпляр Zone и полученного ранее перса игрока мы вызываем функцию InZone которая вернет нам true если игрок в зоне и false если нет // если вернет true (игрок в зоне) - то цикл по зонам для этого игрока прерываем - тк игрок может быть только в одной зоне (если конечно его по кусочкам не разметало по всем бггг) // кроме того функция InZone если игрок в зоне обработает для него урон и напишет сообщение
                //переходим к следующей зоне (элеименту массива)
				} // конец Цикла 2
			}
          //переходим к следующему игроку / указателю на него
		} // конец Цикла 1
	}

VIRrusR 

 

Читаем - офигеваем ))))

 

Изменено пользователем BorizzK (история изменений)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

BorizzK , у меня смена заканчивается. 

Глянул просто на объём твоих комментов!..

Только что, BorizzK сказал:

Читаем - офигеваем

 Приеду домой буду пониматель вывихивать...

Вижу, что много новой для меня информации. Это меня надолго загрузит, видимо...

Как наковыряюсь - отпишу чего и как понял. ...Ох чую завтра ругни немало от тебя выслушаю...

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

VIRrusR Ну там все просто

обьявили массив

загнали в него всех игроков на сервере

далее 2 вложенных цикла

внешний - переборка игроков

     внутренний переборка зон и вызов функции проверки для игрока - есть ли он в текущей зоне - прерываем этот цикл и переходим к след игроку

        если вернуло что игрок не в зоне - переходим к следующей зоне

 

функция проверки в зоне игрок или нет - параллельно в случае если он в зоне выполняет полезную работу - наносит ущерб

ну и возвращает нам true если игрок в зоне или false если нет

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

BorizzK , спасибо за это пояснение, но это... общая логика. А мне нужно каждый шаг в пределах этой логики понять...

 

 

Изменено пользователем VIRrusR (история изменений)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

VIRrusR в яндексе

 

1 - цикл For

2 - вложенные циклы For

 

Изменено пользователем BorizzK (история изменений)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

BorizzK , это то как раз не вопрос!.. Циклы я хорошо понимаю.

Тут много новых для меня понятий, новые функции... Надо разбираться! А ты ж знаешь как я разбираюсь?:joy: Я сам себя так заморочу!..

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

VIRrusR ну в нашем случае ваще все просто

1 Получили очередной элемент (указатель на игрока) массива players

Выполняем для него внутренний цикл
2 получили элемент зоны
2.1вызвали функцию InZone передав в него игрока и зону
2 получили следующий элемент зоны
2.1 вызвали функцию InZone передав в него игрока и зону

.......

InZone вернула true - прерывем цикл (break;) перешли к пункту 1

эелементы зон кончились

цикл завершился
перешли к пункту 1

эелементы players кончились

цикл завершился

функция завершилась
 

Изменено пользователем BorizzK (история изменений)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

BorizzK , давай построчно?

void CheckZones()

-- опрделили свою (пользовательскю) фунцию проверки класса ZonesClass{},обратившись к нему через указатель класса (Zones)

ref array<Man> players = new array<Man>;

Создали массив, в который поместим указатели (players) на всех игроков на сервере. Массив у нас локальный - я так понимаю, что локальный он потому, что используется только внутри нашей функции CheckZones() класса ZonesClass{}, так?

for ( int i = 0; i < players.Count(); i++ )

Ну это циклическое инкрементирование. Задаём переменную i ,которая является счётчиком элементов массива и одновременно количества повторений проверки. Определяем начало отсчёта от нуля. Если значение счётчика менее, чем количество игроков , заданное в массиве (это значение нам возвращает .Count(), обращающаяся к массиву по указателю player), то инкрементируем счётчик - переходим на следующий элемент массива (то есть, если игроков не 0, то начинать с 1-го).

PlayerBase player = PlayerBase.Cast(players[i]);

Даункастим элемент массива (указатель класса Man) в класс PlayerBase, для дальнейшего использования. 

Вопрос: что записано в аргументе функции .Cast() ? Ранее мы не использовали эту функцию с аргументами. Предполагаю, что функция вернёт нам не указатель, а порядковый номер указателя на игрока в массиве? То есть, порядковый номер элемента массива?

if (player.GetIdentity())

Новая функция. Я так понимаю, что нативная?

Из твоего комментария понял так, что это проверка игрока (через указатель массива player) на подключение к серверу?

for ( int j = 0; j < ga_zones.Count(); j++ )

Если проверка на подключение вернула true (я же правильно понимаю, что она просто флаг выставляет?), то запускаем цикл проверки текущего элемента массива player (текущего игрока) на нахождение в зоне. Определяем счётчик цикла в 0, если счётчик менее количества определённых в массиве ga_zones элементов (экземпляров класса Zone{}),то инкрементируем счётчик (то есть начинать с первого элемента массива ga_zones).

if (InZone(player, ga_zones[j])) break;

Собственно, сама проверка на нахождение текущего проверяемого игрока в одной из зон. Если игрок в зоне (ещё не разбирался с InZone() ), то получаем номер зоны (порядковый номер элемента массива ga_zones, содержащего ссылки на экземпляры класса Zone{}).

break - я так понимаю прекратить выполнение проверки (для текущего элемента)? Иначе она будет выполняться по бесконечному циклу?

 

Ну и , соответственно, выходы из циклов:

--если игрок не в зоне, то конец проверки, переход на проверку следующего игрока.

--если игрок в зоне, то к нему будут применены действия по фунции InZone(), конец проверки и переход на проверку следующего игрока.

Всё верно понимаю?

Изменено пользователем VIRrusR (история изменений)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Создайте аккаунт или войдите в него для комментирования

Вы должны быть пользователем, чтобы оставить комментарий

Создать аккаунт

Зарегистрируйтесь для получения аккаунта. Это просто!

Зарегистрировать аккаунт

Войти

Уже зарегистрированы? Войдите здесь.

Войти сейчас

  • Похожие публикации

    • Автор: Troy1
      Всем привет. Суть в чём, пишу мод на событие и когда происходит событие, параллельно должна меняться скорость ветра, не могу понять как заставить скрипт управлять силой ветра. Понижать силу ветра получилось сделать, а вот повышать не как. Только после перезагрузки сервера сила ветра задаётся в нужном значение.
      Как сделать, что бы по вызову функции менялась сила ветра в большую или в меньшую сторону?
      protected void SetWind(float wind, float time) { if (!g_Game) return; Weather m_Weather = g_Game.GetWeather(); if (!m_Weather) return; m_Weather.SetWindMaximumSpeed(wind); m_Weather.SetWind(Vector(1/Math.Sqrt(3), 1/Math.Sqrt(3), 1/Math.Sqrt(3)) * wind); m_Weather.SetWindSpeed(wind); m_Weather.SetWindFunctionParams(1.0, 1.0, -1); } Это скрипт на понижение силы ветра.
      Работает понижение силы ветра в том случае, если до этого сила ветра была выше.
      Пример:
      Изначально на сервере сила ветра = 20 m/s А нужно понизить до 10 m/s
      Только в этом случае сработает скрипт который я приложил выше.
      Помогите пожалуйста решить этот вопрос.
      За ранние благодарю.
    • Автор: Troy1
      Всем привет. Помогите пожалуйста со скриптом.
      Суть. Я пытаюсь сделать синхранизацию сервера с клиентом передавая c конфига время разделки животного.
      В родных скриптах есть class UATimeSpent с константами и там есть константа SKIN.
      Мне нужно её перезаписать на своё значение и мне выдаёт ошибку: Trying to modify write protected variable 'SKIN' в переводе на Русский Попытка изменить защищенную от записи переменную «SKIN».
      Функция скрипта: Когда игрок запускает клиент, идёт запрос на серверную часть и получает в ответ время разделки.
      Задача: Нужно перезаписать константу SKIN на новое значение и всё.
      Сам скрипт.
      class timeToComplete extends UATimeSpent { protected ref UATimeSpent m_UATimeSpent; void timeToComplete() { GetDayZGame().Event_OnRPC.Insert(OnRPC); CheckUATimeSpent(); } void ~timeToComplete() { GetDayZGame().Event_OnRPC.Remove(OnRPC); } void CheckUATimeSpent() { GetGame().RPCSingleParam(NULL, SOC_TIME_RPCs.SOC_GT, NULL, true); } void OnRPC(PlayerIdentity sender, Object target, int rpc_type, ParamsReadContext ctx) { if (rpc_type == SOC_TIME_RPCs.SOC_RT) { Param1<float> soc_srt; if (ctx.Read(soc_srt)) { if (soc_srt.param1!= 0) { m_UATimeSpent.SKIN = soc_srt.param1; Print("Пришёл ответ от сервера в m_UATimeSpent.SKIN - " + m_UATimeSpent.SKIN) } } } } };  
    • Автор: RedWoodGamer
      Ищу мододела который напишет мод на поиск предметов в ванильной фурнитуре с возможностью конфигурации лутабельных объектов и лута внутри них, а так-же КД на лутаемый объект (Простыми словами чтобы нельзя было лутать один и тот же объект двум игрокам одновременно, если один залутал, включается определённый таймер и второй игрок может залутать его через прошедшее время, либо же завязать это время на рестарт сервера.)
      Бюджет есть, оценивайте свою работу и предлагайте цену, кто не хочет в комментариях вот Discord : RedWood#6323
    • Автор: CubeIn
      Приветствую друзья, возникла неприятная ошибка.
      Подписал все ключи через DS Utils, вставил ключ в северную часть, но все равно при заходе на сервер пишет данную ошибку.
      Client contains PBO which is not part of server data
       
    • Автор: CubeIn
      Есть ли у кого ни будь шаблон или инструкция как создать свой шеврон?
      Нашел видео от Фидова, но ссылка на шаблон не действительна

      Пожалуйста, Войдите или Зарегистрируйтесь, чтобы увидеть это: Вложение.
  • Наш выбор

×
×
  • Создать...

Важная информация

Используя этот сайт, вы автоматически обязуетесь соблюдать наши Правила и Политика конфиденциальности.
Чтобы сделать этот веб-сайт лучше, мы разместили cookies на вашем устройстве. Вы можете изменить свои настройки cookies, в противном случае мы будем считать, что вы согласны с этим.

Поддержка