ANTICHAT

ANTICHAT (https://forum.antichat.io/index.php)
-   Общие вопросы программирования (https://forum.antichat.io/forumdisplay.php?f=206)
-   -   Задержка (https://forum.antichat.io/showthread.php?t=1398923)

Smeruxa 20.08.2021 20:16

Пишу СФ плагин и вопрос, отправляю сообщение в чат но проблема, как сделать задержку между ними? Если использовать функции популярные то игру тупо фризит до тех пор пока все сообщения не отправятся

legendabrn 20.08.2021 20:32

std::this_thread::sleep_for(std::chrono::milliseco nds(100)); // 100 миллисекунд

но перед этим создай поток что бы не зафризило игру:

Код:





Код:

std::thread test([]()
{
//code
};

test.detach();



или же:

Цитата:

Сообщение от BlackKnigga

Разработчики, только перешедшие с клео\луа на C++ негодуют из-за необходимости использовать разного рода таймеры и лапшу из GetTickCount'ов вместо полюбившихся функций wait. Но особо ярых фанатов клео это не устраивает, отчего они начинают использовать потоки ради функций вроде Sleep для того чтобы не блокировать цикл игры. Однако это не безопасно. Функции ни GTA ни SAMP'а абсолютно не предназначены для использования в разных потоках и их использование может привести к рандомным крашам.
Выход есть!

Example:





Код:

#include
#include
#include "Yet-another-hook-library/hook.h"
#include "sampapi/CChat.h"
#include "coro_wait/coro_wait.h"
using
namespace
sampapi
::
v037r1
;
void
foo
(
)
{
using
namespace
std
::
chrono_literals
;
CChat
*
&
pChat
=
RefChat
(
)
;
while
(
!
pChat
)
{
this_coro
::
wait
(
100
ms
)
;
}
unsigned
int
counter
=
0
;
while
(
true
)
{
pChat
->
AddMessage
(
-
1
,
(
std
::
string
(
"Hello "
)
+
std
::
to_string
(
counter
)
)
.
c_str
(
)
)
;
counter
++
;
this_coro
::
wait
(
1
s
)
;
}
}
void
CGame_Process_hk
(
)
{
static
coro_wait instance
{
foo
}
;
instance
.
process
(
)
;
}
class
coro_wait_example
{
public
:
coro_wait_example
(
)
{
using
CGame_Process_t
=
void
(
__cdecl
*
)
(
)
;
CGame_Process_t CGame_Process
=
reinterpret_cast

(
0x53BEE0
)
;
static
hook
CGame_Process_hook
(
CGame_Process
,
CGame_Process_hk
)
;
}
}
coro_wait_example
;



Выполнение функции foo приостанавливается на время, переданное функции this_coro::wait, и продолжается с того же места. Все это работает в одном потоке, благодаря чему можно не переживать за потокобезопасность вызываемых внутри функций.
В бесконечных или очень больших циклах требуется вызывать wait(0), все по канонам клео.
Функция coro_wait::process должна вызываться в потоке игры (перехваченном как в примере, либо в функции mainloop для SF API).

Требуется библиотека Boost.Context!

Исходный код:


GitHub - allwanttokissme/coro_wait: Suspending coroutines by time

Suspending coroutines by time. Contribute to allwanttokissme/coro_wait development by creating an account on GitHub.

github.com


хуки
sampapi


Smeruxa 20.08.2021 20:49

Цитата:

Сообщение от legendabrn

std::this_thread::sleep_for(std::chrono::milliseco nds(100)); // 100 миллисекунд
но перед этим создай поток что бы не зафризило игру:

Код:





Код:

std::thread test([]()
{
//code
};

test.detach();



или же:

буду использовать первый вариант, пасиба, работает

Dark_Knight 20.08.2021 20:49

@Smeruxa

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

Ya Zaregalsya 01.09.2021 15:21

Цитата:

Сообщение от Dark_Knight

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

Можно подробнее насчёт таймеров? Я использую функцию CreateThread, с ней вроде нет никаких проблем по части производительности даже когда таких потоков очень много.

Dark_Knight 01.09.2021 20:37

Цитата:

Сообщение от Ya Zaregalsya

Можно подробнее насчёт таймеров? Я использую функцию CreateThread, с ней вроде нет никаких проблем по части производительности даже когда таких потоков очень много.

Потоки зло. Они тебя сожрут, а так без кода ничего и не скажешь.

Ya Zaregalsya 02.09.2021 03:16

Цитата:

Сообщение от Dark_Knight

Потоки зло. Они тебя сожрут, а так без кода ничего и не скажешь.

Для каких задач мы используем потоки: когда надо сделать бесконечный цикл, и когда нужно сделать функцию с задержками, не прерывая выполнение всей программы. Как советуете решать эти задачи?

Dark_Knight 02.09.2021 18:21

Цитата:

Сообщение от Ya Zaregalsya

Для каких задач мы используем потоки: когда надо сделать бесконечный цикл, и когда нужно сделать функцию с задержками, не прерывая выполнение всей программы. Как советуете решать эти задачи?

Код правильно писать. Задержки вообще плохая практика.

Ya Zaregalsya 02.09.2021 18:25

Цитата:

Сообщение от Dark_Knight

Код правильно писать. Задержки вообще плохая практика.

Так себе совет, если честно. Придётся дальше на потоках сидеть.

sc6ut 02.09.2021 18:49

Цитата:

Сообщение от Ya Zaregalsya

Для каких задач мы используем потоки: когда надо сделать бесконечный цикл, и когда нужно сделать функцию с задержками, не прерывая выполнение всей программы. Как советуете решать эти задачи?

@Dark_Knight, наверное, говорит про написание DLL библиотек, где создание потоков и взаимодействие с памятью приложения может вызвать UB, к примеру из-за одновременного изменения того же участка памяти, так как это будет довольно сложно предотвратить. В создание самостоятельной программы, в использование потоков я не вижу ничего плохого, но надо уметь с ними работать чтобы не происходили возможные проблемы с ними.

UPD: Собственно надо и правильно понимать когда использование потоков востребовано, а когда можно обойтись без него.

Ya Zaregalsya 02.09.2021 19:18

Цитата:

Сообщение от SC6UT

@Dark_Knight, наверное, говорит про написание DLL библиотек, где создание потоков и взаимодействие с памятью приложения может вызвать UB, к примеру из-за одновременного изменения того же участка памяти, так как это будет довольно сложно предотвратить. В создание самостоятельной программы, в использование потоков я не вижу ничего плохого, но надо уметь с ними работать чтобы не происходили возможные проблемы с ними.

Dark Knight просто немножко чепуху задвигает, потому что это не программист решает, что ему нужна задержка, а в основном так просто стоит задача. Часто сталкиваюсь с UB, например вот артефакты и странные зависания при эмуляции входящих RPC в потоке:

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

kin4stat 02.09.2021 19:55

Цитата:

Сообщение от kin4stat

Корутины

Либо что-то типа такого

C++:





Код:

static
bool
Process
=
false
;
static
unsigned
long
dwStartTick
{
GetTickCount
(
)
}
;
if
(
Process
&&
GetTickCount
(
)
-
dwStartTick
>
5000
)
{
//Код который должен срабатывать через 5 секунд
Process
=
false
;
}
if
(
NeedToSendMessage
)
{
Process
=
true
;
dwStartTick
=
GetTickCount
(
)
;
NeedToSendMessage
=
false
}



Вместо GetTickCount можно использовать std::chrono::steady_clock()

upd: сейчас подумал, и понял что корутины будут использовать такой же принцип работы

Ya Zaregalsya 02.09.2021 20:19

Цитата:

Сообщение от kin4stat

Либо что-то типа такого

C++:





Код:

static
bool
Process
=
false
;
static
unsigned
long
dwStartTick
{
GetTickCount
(
)
}
;
if
(
Process
&&
GetTickCount
(
)
-
dwStartTick
>
5000
)
{
//Код который должен срабатывать через 5 секунд
Process
=
false
;
}
if
(
NeedToSendMessage
)
{
Process
=
true
;
dwStartTick
=
GetTickCount
(
)
;
NeedToSendMessage
=
false
}



Вместо GetTickCount можно использовать std::chrono::steady_clock()

upd: сейчас подумал, и понял что корутины будут использовать такой же принцип работы

Корутины выглядят непонятно, но многообещающе. Функция, которую можно приостановить — это то, что надо. Надеюсь оно заработает в ГТА и СФ.

Dark_Knight 03.09.2021 02:48

Цитата:

Сообщение от Ya Zaregalsya

потому что это не программист решает, что ему нужна задержка, а в основном так просто стоит задача.

А вот про первое ты как раз вообще не прав. Как программист решает, как решить задачу, а не задача решает, как код программисту решить.

и что же за РПЦ ты там эмулируешь, что ловишь такие артефакты?)

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

Вот тебе еще одна

GitHub - skyformat99/TimerManager: Crossplatform library for simple working with timers

Crossplatform library for simple working with timers - skyformat99/TimerManager

github.com

Ya Zaregalsya 03.09.2021 03:37

Цитата:

Сообщение от Dark_Knight

А вот про первое ты как раз вообще не прав. Как программист решает, как решить задачу, а не задача решает, как код программисту решить.
и что же за РПЦ ты там эмулируешь, что ловишь такие артефакты?)
Тебе вон выше дали хорошую либу для таймеров. Ты в ГТА вообще забудь про слово поток. Это крайне плохая практика в этом сегменте.
Вот тебе еще одна

GitHub - skyformat99/TimerManager: Crossplatform library for simple working with timers

Crossplatform library for simple working with timers - skyformat99/TimerManager

github.com


На видео эмуляция различных RPC для установки позиции и направления камеры, их всего пять примерно, когда-то задавал вопрос по этой теме и ответа так и не нашлось, поэтому сделал через RakNet. Что касается задержек, то программист, к сожалению, время выворачивать не может, если задача требует паузы между действиями (а таких задач 50% на практике), то никуда тут не деться, потоками, таймерами или колбэками всё равно придётся добиваться задержки.

Цитата:

Сообщение от Dark_Knight

А вот про первое ты как раз вообще не прав. Как программист решает, как решить задачу, а не задача решает, как код программисту решить.
и что же за РПЦ ты там эмулируешь, что ловишь такие артефакты?)
Тебе вон выше дали хорошую либу для таймеров. Ты в ГТА вообще забудь про слово поток. Это крайне плохая практика в этом сегменте.
Вот тебе еще одна

GitHub - skyformat99/TimerManager: Crossplatform library for simple working with timers

Crossplatform library for simple working with timers - skyformat99/TimerManager

github.com


По поводу таймера. Правильно ли я понял, что вот эта функция в timer_manager::add_timer сработает как надо только если цикл будет постоянно бегать по ней? Допустим есть основной цикл с !timer_manager::process() и есть функция (допустим ввод команды в игре), которая отрабатывает один раз, в этой функции будет timer_manager::add_timer, оно сработает в таком случае или add_timer нужно вызывать каждую миллисекунду?


Время: 21:07