PDA

Просмотр полной версии : [Античит] Защита обхода регистрации



TBoPoIIIoK
13.07.2016, 12:43
Всем привет. Многие наверное знают что можно обойти систему регистрации и авторизации. Суть обхода заключается в том, что игрок не вызывает OnPlayerRequestClass и напрямую ставит себе состояние PLAYER_STATE_ONFOOT без PLAYER_STATE_SPAWNED. И так, как же это исправить ? Да очень просто.
1. Ко всем переменным добавляем -

new bool: ac_1[MAX_PLAYERS char];
2. В OnPlayerConnect добавляем обнуление переменной -

ac_1{playerid} = false;
3. В OnPlayerRequestClass добавляем (чтобы исключить ложные срабатывания) -

ac_1{playerid} = true;
4. Ну и напоследок в OnPlayerStateChange добавляем (в самое начало) проверку состояния и переменной -

if(!ac_1{playerid} && newstate == PLAYER_STATE_ONFOOT && oldstate == PLAYER_STATE_NONE) return SendClientMessage(playerid, 0xE6E6FAFF, "AC #1 [ОБХОД РЕГИСТРАЦИИ / АВТОРИЗАЦИИ]");
Вот собственно и все, наша защита готова. А вот собственно доказательство что все работает -

http://rgho.st/8M8fQKsSl/image.png
Не забываем, что "SendClientMessage(playerid, 0xE6E6FAFF, "AC #1 [ОБХОД РЕГИ / АВТОРИЗАЦИИ]");" нужно заменить на свое наказание.
Всем спасибо за просмотр. Критика и идеи приветствуются.

Nexius_Tailer
13.07.2016, 13:20
Молодец, простая и эффективная защита. Жаль плюсы здесь ставить почему-то нельзя xD

HarrWe
13.07.2016, 13:23
Годно, поставил в свой мод)

Geebrox
13.07.2016, 14:03
1. В pawn не существует логический тип данных (bool), это просто макрос, подробнее тут (http://pro-pawn.ru/showthread.php?13514-%D0%9C%D0%B8%D1%84%D1%8B-%D0%BE-Pawn-%D1%81%D0%BA%D1%80%D0%B8%D0%BF%D1%82%D0%B8%D0%BD%D0%B3%D0%B5-8)
2. После авторизации / регистрации, переменная останется просто в памяти, нет нужды, раз так лучше уж использовать pvar и удалить его



public OnPlayerConnect(playerid)
{
SetPvarInt(playerid, "connecting", 1);
return 1;
}

public OnPlayerRequestClass(playerid, classid)
{
if(GetPvarInt(playerid, "connecting"))
DeletePVar(playerid, "connecting");
return 1;
}

public OnPlayerSpawn(playerid)
{
if(GetPvarInt(playerid, "connecting"))
SendClientMessage(playerid, 0xCD0000FF, "Подозрение в читерстве!");
return 1;
}

TBoPoIIIoK
13.07.2016, 14:10
1. В pawn не существует логический тип данных (bool), это просто макрос, подробнее тут (http://pro-pawn.ru/showthread.php?13514-%D0%9C%D0%B8%D1%84%D1%8B-%D0%BE-Pawn-%D1%81%D0%BA%D1%80%D0%B8%D0%BF%D1%82%D0%B8%D0%BD%D0%B3%D0%B5-8)
2. После авторизации / регистрации, переменная останется просто в памяти, нет нужды, раз так лучше уж использовать pvar и удалить его



public OnPlayerConnect(playerid)
{
SetPvarInt(playerid, "connecting", 1);
return 1;
}

public OnPlayerRequestClass(playerid, classid)
{
if(GetPvarInt(playerid, "connecting"))
DeletePVar(playerid, "connecting");
return 1;
}

public OnPlayerSpawn(playerid)
{
if(GetPvarInt(playerid, "connecting"))
SendClientMessage(playerid, 0xCD0000FF, "Подозрение в читерстве!");
return 1;
}


1. Мне удобнее работать с ним, нежели с 1 и 0.
2. Можно, но мне переменные как-то привычнее. Переписать на них - минутное дело, но этого делать не буду. Кому надо - сделают.

Desulaid
13.07.2016, 14:15
Молодец, простая и эффективная защита. Жаль плюсы здесь ставить почему-то нельзя xD

Тема не одобрена



Мне одному не нравится такое?))

!ac_1[playerid]

Можно использовать оператор char и обращаться к байту

массив{индекс}

:give_heart:

Nexius_Tailer
13.07.2016, 14:16
1. В pawn не существует логический тип данных (bool), это просто макрос, подробнее тут (http://pro-pawn.ru/showthread.php?13514-%D0%9C%D0%B8%D1%84%D1%8B-%D0%BE-Pawn-%D1%81%D0%BA%D1%80%D0%B8%D0%BF%D1%82%D0%B8%D0%BD%D0%B3%D0%B5-8)
2. После авторизации / регистрации, переменная останется просто в памяти, нет нужды, раз так лучше уж использовать pvar и удалить его



public OnPlayerConnect(playerid)
{
SetPvarInt(playerid, "connecting", 1);
return 1;
}

public OnPlayerRequestClass(playerid, classid)
{
if(GetPvarInt(playerid, "connecting"))
DeletePVar(playerid, "connecting");
return 1;
}

public OnPlayerSpawn(playerid)
{
if(GetPvarInt(playerid, "connecting"))
SendClientMessage(playerid, 0xCD0000FF, "Подозрение в читерстве!");
return 1;
}

Проверялся ли этот код? Если нет, то совсем не факт, что будет вызываться OnPlayerSpawn

TBoPoIIIoK
13.07.2016, 14:24
Проверялся ли этот код? Если нет, то совсем не факт, что будет вызываться OnPlayerSpawn

Не вызывается. Вызывается только OnPlayerConnect и все.

http://rgho.st/6KdCBbNXC/image.png

Geebrox
13.07.2016, 14:33
Проверялся ли этот код? Если нет, то совсем не факт, что будет вызываться OnPlayerSpawn

Я не разбираюсь в читах, если не вызывается OnPlayerSpawn то просто измени на проверку state. Главное не в этом, главное в оформление кода

- - - Добавлено - - -



Можно использовать оператор char и обращаться к биту


может к байту? :bye:

Nexius_Tailer
13.07.2016, 14:35
Тема не одобрена
Хорошая причина не считать посты и репутацию в таких темах


Мне одному не нравится такое?))

!ac_1[playerid]

Можно использовать оператор char и обращаться к биту

массив{индекс}

:give_heart:
Можно, но много профита ты на этом не сделаешь

Geebrox
13.07.2016, 14:36
1. Мне удобнее работать с ним, нежели с 1 и 0.

Сам себя обманывать любишь?


2. Можно, но мне переменные как-то привычнее. Переписать на них - минутное дело, но этого делать не буду. Кому надо - сделают.

Извини, но это не Г-И, ты находишься в портале pro-pawn.ru (http://pro-pawn.ru/)

Nexius_Tailer
13.07.2016, 14:39
Сам себя обманывать любишь?



Извини, но это не Г-И, ты находишься в портале pro-pawn.ru (http://pro-pawn.ru/)
Это дело удобства. А с тем, что пвары ещё и медленнее, так в идеале вообще лучше юзать именно переменные.

Geebrox
13.07.2016, 14:47
Это дело удобства.

Удобство? Покажи мне его... Переменная используется для 1 действии и все, алеее



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

Опять таки чуть выше прочитай, Переменная используется для 1 действии. и остается в памяти (MAX_PLAYERS ячеек) 4*MAX_PLAYERS байтов, что тебе лучше экономить такое кол-во памяти или выиграть 0.00001 мс?

Nexius_Tailer
13.07.2016, 15:29
Удобство? Покажи мне его... Переменная используется для 1 действии и все, алеее
Что за "алеее"?
Удобство понятие персональное, поэтому насчёт него что-то доказывать глупо


Опять таки чуть выше прочитай, Переменная используется для 1 действии. и остается в памяти (MAX_PLAYERS ячеек) 4*MAX_PLAYERS байтов, что тебе лучше экономить такое кол-во памяти или выиграть 0.00001 мс?
Конечно, процессорное время гораздо дороже оперативной памяти

BadPawn
13.07.2016, 15:32
static bool:ac_dialog_reglog[MAX_PLAYERS char];
//если уж нужен bool :DD

OnPlayerConnect:

ac_dialog_reglog{playerid} = false;

OnPlayerRequestClass :

ac_dialog_reglog{playerid} = true;

OnPlayerStateChange:

if(
ac_dialog_reglog{playerid} == false
&& newstate == PLAYER_STATE_ONFOOT
&& oldstate == PLAYER_STATE_NONE
)
return SendClientMessage(playerid, 0xE6E6FAFF,
!"AC #1 [ОБХОД РЕГИСТРАЦИИ / АВТОРИЗАЦИИ]");


Каждый сам себе программист. )))

Geebrox
13.07.2016, 15:34
Что за "алеее"?
Удобство понятие персональное, поэтому насчёт него что-то доказывать глупо


Раз уж это персональное, то не отвечай за всех

Это дело удобства.


Конечно, процессорное время гораздо дороже оперативной памяти

Я с тобой согласен, но не в таких условиях, у тебя проблемы со сравнениями?

Nexius_Tailer
13.07.2016, 15:39
Раз уж это персональное, то не отвечай за всех
Лол, так и ты не отвечай за всех. Глупо было вообще заводить тогда эту тему, если это и так понятно, что для каждого существует своё удобство.


Я с тобой согласен, но не в таких условиях, у тебя проблемы со сравнениями?
В каких условиях? Когда оперативной памяти предоставляются гигабайты, а ты гонишься за байтами?
Проблем со сравнениями как раз никак нет, а вот с твоих слов такое ощущение, что они есть у тебя.

Geebrox
13.07.2016, 16:06
В каких условиях? Когда оперативной памяти предоставляются гигабайты, а ты гонишься за байтами?
Проблем со сравнениями как раз никак нет, а вот с твоих слов такое ощущение, что они есть у тебя.

https://pp.vk.me/c604426/v604426066/1bcad/ltll5eseHxE.jpg


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

Я не отвечал за всех и не говорил, что мой код удобнее, я просто попросил у тебя показать мне удобства в этом коде

- - - Добавлено - - -

Все таки мое мнение о PVar опровергнут (http://pro-pawn.ru/showthread.php?14044-%D0%9C%D0%B8%D1%84%D1%8B-%D0%BE-Pawn-%D1%81%D0%BA%D1%80%D0%B8%D0%BF%D1%82%D0%B8%D0%BD%D0%B3%D0%B5-8&p=75084#post75084) :mosking:

ziggi
13.07.2016, 16:32
bool используют для того, чтобы обозначить то, что значение этой переменной может быть равно true или false. Даже в C/C++ bool имеет размер в те же 4 байта, что и int. Естественно, чтобы полностью раскрыть смысл, переменную обязательно нужно назвать так, чтобы сразу было понятно за что она отвечает.



new
bool:gIsRequestClassCalled[MAX_PLAYERS char];

public OnPlayerConnect(playerid)
{
gIsRequestClassCalled{playerid} = false;
return 1;
}

public OnPlayerRequestClass(playerid, classid)
{
gIsRequestClassCalled{playerid} = true;
return 1;
}

public OnPlayerStateChange(playerid, newstate, oldstate)
{
if (!gIsRequestClassCalled{playerid}
&& newstate == PLAYER_STATE_ONFOOT
&& oldstate == PLAYER_STATE_NONE) {
SendClientMessage(playerid, -1, "cheat");
}
return 1;
}


Назвав переменную gIsRequestClassCalled я сразу понимаю за что она отвечает, названия ac_1, connecting, ac_dialog_reglog не говорят абсолютно ничего. По этой теме советую изучить тему самодокументируемого кода.


>_>

<_<

-_-

http://pro-pawn.ru/showthread.php?14044

Open SA-MP - это не слитые исходники, а результат реверс-инжиниринга, это видно по отдельным частям кода и по сильным различиям с ранее слитыми версиями.

Nexius_Tailer
13.07.2016, 18:30
https://pp.vk.me/c604426/v604426066/1bcad/ltll5eseHxE.jpg
Картинка то красивая, но это скорее не тот случай. Сэкономленные три байта твои игроки не оценят, а вот если всё будет медленно выполняться - то да, это будет заметно не только в тестах.

DeimoS
13.07.2016, 18:49
Кто бы что ни говорил, тут я согласен с Geebrox.
Говорить о медленной обработке pVar как-то глупо, ибо код вызывается не так уж и часто (основные действия будт происходить только при коннекте). При этом, можно спокойно сэкономить память




Все таки мое мнение о PVar опровергнут (http://pro-pawn.ru/showthread.php?14044-%D0%9C%D0%B8%D1%84%D1%8B-%D0%BE-Pawn-%D1%81%D0%BA%D1%80%D0%B8%D0%BF%D1%82%D0%B8%D0%BD%D0%B3%D0%B5-8&p=75084#post75084) :mosking:

Как раз твои слова лишь подтверждаются. Как я всегда говорил, временную информацию лучше хранить в PVar, ибо хоть и PVar В ЛЮБОМ СЛУЧАЕ занимают память, НО в эту память ты можешь записывать разные данные под разными "метками".
То бишь, создав глобальную переменную под данную систему, ты уже вряд ли сможешь использовать её где-то ещё, как минимум, не испортив читаемость кода и не добавив шансов совершить ошибок.
С PVar же ты можешь в один и тот же участок памяти записывать разные данные (если удалять одни перед записью других) и не терять при этом читаемость кода.


То бишь, экономия памяти будет не в том, что ты удалишь pVar и эта память освободится вообще. А в том, что ты будешь работать с уже зарезервированным куском памяти, который будет зарезервирован в любом случае: объявишь ты глобальную переменную вместо pVar или нет

В общем, ты говоришь правильные вещи, хоть и немного неправильно их представляя

- - - Добавлено - - -



В каких условиях? Когда оперативной памяти предоставляются гигабайты, а ты гонишься за байтами?

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

Nexius_Tailer
13.07.2016, 19:00
Это один из тех случаев, когда глупо говорить о гигабайтах оперативки. Используя pVar, ты ничего не потеряешь и даже выиграешь, в отличии от массива.
Если бы мне было бы удобно - я бы их использовал. А будь они хоть трижды оптимальнее в потреблении памяти, но гораздо медленнее в работе - использовал бы обычные переменные, т.к. причина выше.
Хотя конечно, в данной ситуации сильно той скорости не теряется, но ведь и память сильно не экономится :grin:
Кароче то на то выходит, ибо кода тут три строчки, так что изначальный вариант вполне годен и ничего, как по мне, менять особо и нечего.


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

Daniel_Cortez
13.07.2016, 19:09
Даже в C/C++ bool имеет размер в те же 4 байта, что и int.
В Visual Studio в файле на C++ ввёл "const int x = sizeof(bool);", при наведении курсора на "x" всплывает подсказка "const int x = 1". К чему бы это?



Open SA-MP - это не слитые исходники, а результат реверс-инжиниринга, это видно по отдельным частям кода и по сильным различиям с ранее слитыми версиями.
В курсе, по отдельным комментариям и частям кода сразу становится ясно, что это, как минимум, отчасти результат обратной разработки.
На счёт "ранее слитых версий", они ещё есть в открытом доступе? Помню, я пробовал искать год назад, нашёл только Open SA-MP -_-

DeimoS
13.07.2016, 19:23
А будь они хоть трижды оптимальнее в потреблении памяти, но гораздо медленнее в работе - использовал бы обычные переменные, т.к. причина выше.

В том-то и дело, что они не "гораздо медленнее в работе".
Вот тебе простой тест

cmd:t(playerid, params[])
{
new tick = GetTickCount();
printf("\n\n\nИнициализация:");
for(new i; i < 1_000_000; i++)
{
new test = 11;
#pragma unused test
}

printf("new - %d", GetTickCount()-tick);
tick = GetTickCount();
tick = GetTickCount();
for(new i; i < 1_000_000; i++)
{
SetPVarInt(playerid, "TestSet", 11);
}
printf("pVar - %d", GetTickCount()-tick);


printf("\nВозврат:");
new test = 11,
buff;
SetPVarInt(playerid, "TestGet", 11);
for(new i; i < 1_000_000; i++)
{
buff = test;
}
printf("new - %d", GetTickCount()-tick);
tick = GetTickCount();
for(new i; i < 1_000_000; i++)
{
buff = GetPVarInt(playerid, "TestGet");
}
#pragma unused buff
printf("pVar - %d", GetTickCount()-tick);
return 1;
}



Инициализация:
[18:13:21] new - 47
[18:13:21] pVar - 203
[18:13:21]
Возврат:
[18:13:21] new - 265
[18:13:21] pVar - 161



Инициализация:
[18:13:38] new - 46
[18:13:38] pVar - 200
[18:13:38]
Возврат:
[18:13:38] new - 258
[18:13:38] pVar - 159



Инициализация:
[18:13:38] new - 48
[18:13:39] pVar - 205
[18:13:39]
Возврат:
[18:13:39] new - 265
[18:13:39] pVar - 166

Хотя он не претендует на сверхточный и сверхправильный, но суть в том, что разница в скорости ощущается лишь при очень частых вызовах. Прямо очень-очень (миллион раз в секунду, смекаешь?). И бояться, что pVar как-то затормозит данный код - это, как минимум, глупо.


Хотя конечно, в данной ситуации сильно той скорости не теряется, но ведь и память сильно не экономится :grin:

Ну если 1000 ячеек - это для тебя пустяки, то да. Но я не привык подобным количеством памяти разбрасываться без причины.



О них глупо говорить только тогда, когда уже при этом имеешь какой-нибудь ColAndreas, сильно её потребляющий (и даже тогда её ещё вполне хватает на твои нужды)

Во-первых, всё зависит от хостинга, на котором стоит сервер.
Во-вторых, странная нынче мода в SA-MP: пытаться оптимизировать скорость нахождения команды (СКОРОСТЬ НАХОЖДЕНИЯ КОМАНДЫ, КАРЛ), но забивать на подобные вещи. Я соглашусь, ничего страшного от того, что ты выделишь лишнюю 1000 ячеек, не случится. Но какой в этом смысл? Что ты от этого выиграешь, кроме того, что тебе меньше придётся печатать? Жертвовать памятью в угоду собственной лени - такой себе подход к работе.

Nexius_Tailer
13.07.2016, 19:34
В том-то и дело, что они не "гораздо медленнее в работе".
Вот тебе простой тест

cmd:t(playerid, params[])
{
new tick = GetTickCount();
printf("\n\n\nИнициализация:");
for(new i; i < 1_000_000; i++)
{
new test = 11;
#pragma unused test
}

printf("new - %d", GetTickCount()-tick);
tick = GetTickCount();
tick = GetTickCount();
for(new i; i < 1_000_000; i++)
{
SetPVarInt(playerid, "TestSet", 11);
}
printf("pVar - %d", GetTickCount()-tick);


printf("\nВозврат:");
new test = 11,
buff;
SetPVarInt(playerid, "TestGet", 11);
for(new i; i < 1_000_000; i++)
{
buff = test;
}
printf("new - %d", GetTickCount()-tick);
tick = GetTickCount();
for(new i; i < 1_000_000; i++)
{
buff = GetPVarInt(playerid, "TestGet");
}
#pragma unused buff
printf("pVar - %d", GetTickCount()-tick);
return 1;
}



Инициализация:
[18:13:21] new - 47
[18:13:21] pVar - 203
[18:13:21]
Возврат:
[18:13:21] new - 265
[18:13:21] pVar - 161



Инициализация:
[18:13:38] new - 46
[18:13:38] pVar - 200
[18:13:38]
Возврат:
[18:13:38] new - 258
[18:13:38] pVar - 159



Инициализация:
[18:13:38] new - 48
[18:13:39] pVar - 205
[18:13:39]
Возврат:
[18:13:39] new - 265
[18:13:39] pVar - 166
Так а ты GetTickCount во втором тесте в нужное место поставь (а не как сейчас, что у тебя в одном месте два стоят) и сразу другие результаты увидишь.


Ну если 1000 ячеек - это для тебя пустяки, то да. Но я не привык подобным количеством памяти разбрасываться без причины.
Ты не привык.. Мм, жаль


Во-вторых, странная нынче мода в SA-MP: пытаться оптимизировать скорость нахождения команды (СКОРОСТЬ НАХОЖДЕНИЯ КОМАНДЫ, КАРЛ), но забивать на подобные вещи.
Не знаком с такими людьми. Встречу - обязательно им об этом сообщу

П.с. Для тебя пустяки сравнивать пвары в скорости, когда они проигрывают на доли секунды. Для меня пустяки (как ты считаешь) выделить лишних 1к ячеек (не обязательно из стека, просто к примеру). Ну так ведь я ж уже написал: за сэкономленную память тебе в ладоши не попляшут, а быстро работающий код вроде как ещё не считается гомосексуализмом.
И ещё. Для меня как раз то и не пустяк сэкономить память, когда это реально на что-то повлияет. Нужно меру видеть во всём, ибо оптимизация того, на что при его работе не жалуешься, не первостепенная задача. Ресурсы нужно в правильное русло свои применять

TBoPoIIIoK
13.07.2016, 20:43
переписал на char.

DeimoS
13.07.2016, 21:10
Так а ты GetTickCount во втором тесте в нужное место поставь (а не как сейчас, что у тебя в одном месте два стоят) и сразу другие результаты увидишь.

И что изменится? Если ты не заметил, дублированный вызов стоит в той части, где ты "обнуляешь" значение переменной "tick" после предыдущего теста для нового. На результаты это никак не влияет.
А есть он там, как ты можешь понять, из-за того, что тест составлялся путём CTRL+C/CTRL+V


Ты не привык.. Мм, жаль

Как и большая часть тех, кто не раскидывается ресурсами направо и налево.
Или то, что ты решил придраться к словам, намекая на моё личное мнение, отменяет тот факт, что данная "экономия" полезна?



Не знаком с такими людьми. Встречу - обязательно им об этом сообщу

Взгляни в темы с релизами DC_CMD и Pawn.CMD, где многие активно фапают на заявление о скорости.


Ну так ведь я ж уже написал: за сэкономленную память тебе в ладоши не попляшут, а быстро работающий код вроде как ещё не считается гомосексуализмом.
Ты пытаешься оперировать приростом, который изменяется наносекундами. Да ещё и в системе, которая вызывается всего 1 раз за всё время нахождения игрока на сервере (не считая условия в OnPlayerStateChange). Игроки и за такой неощутимый прирост в ладоши хлопать не будут. Да и причём тут игроки, когда суть в том, чтоб код, который ты написал, дружил с логикой и здравым смыслом?
С таким же успехом можно и над подсчётом размера массивов не заморачиваться, а выделять по 2000 ячеек везде и всё. Какая разница? Памяти-то много. И плевать, что если к написанию кода подходить подобным образом, рано или поздно все твои "да лааадно, памяти ведь много" перерастут в огромный ком неиспользуемой памяти, который потом придётся разгребать.


И ещё. Для меня как раз то и не пустяк сэкономить память, когда это реально на что-то повлияет.
Покажи мне пример экономии памяти, которая реально на что-то влияет, не считая переполнения стэка, который можно увеличить


Нужно меру видеть во всём, ибо оптимизация того, на что при его работе не жалуешься, не первостепенная задача. Ресурсы нужно в правильное русло свои применять

Ты так говоришь, как будто у тебя на клавиатуре стоит лимит нажатий, после которых та отказывается работать. О каких ресурсах идёт речь? Тут система, которую ты раз написал и о которой забыл. От того, что ты изначально учтёшь в ней ещё и правильный расход памяти, ни тебе, ни компилятору, ни серверу, ни кому-либо ещё не убудет.
Ладно бы я предлагал тебе прикрутить к такой простой системе какие-нибудь emit'ы или какой-нибудь другой подобный, в контексте данной системы, бред, но нет, я просто предлагаю использовать память, которая в любом случае выделяется, вместо того, чтоб выделять новую. Ощущаешь разницу?

ziggi
13.07.2016, 21:20
В Visual Studio в файле на C++ ввёл "const int x = sizeof(bool);", при наведении курсора на "x" всплывает подсказка "const int x = 1". К чему бы это?

Видимо что-то изменилось, по крайней мере так было раньше:
- "In Visual C++4.2, the Standard C++ header files contained a typedef that equated bool with int. In Visual C++ 5.0 and later, bool is implemented as a built-in type with a size of 1 byte. That means that for Visual C++ 4.2, a call of sizeof(bool) yields 4, while in Visual C++ 5.0 and later, the same call yields 1" - источник (https://msdn.microsoft.com/en-us/library/tf4dy80a(v=vs.100).aspx)
- "В памяти компьютера значения констант и переменных типа bool занимают 4 байта." - источник (https://book.mql4.com/ru/basics/types)
- "Учтите, что тип BOOL в C имеет размер 4 байта (= sizeof(int)), а тип Boolean состоит только из одного." - источник (http://www.transl-gunsmoker.ru/2009/04/bool-boolean-integer.html)


В курсе, по отдельным комментариям и частям кода сразу становится ясно, что это, как минимум, отчасти результат обратной разработки.
На счёт "ранее слитых версий", они ещё есть в открытом доступе? Помню, я пробовал искать год назад, нашёл только Open SA-MP -_-

По рукам ходят.

Nexius_Tailer
13.07.2016, 21:43
И что изменится?
Инициализация:
[20:18:17] new - 87
[20:18:17] pVar - 256
[20:18:17]
Возврат:
[20:18:17] new - 326
[20:18:18] pVar - 253

cmd:t(playerid, params[])
{
new tick = GetTickCount();
printf("\n\n\nИнициализация:");
for(new i; i < 1_000_000; i++)
{
new test = 11;
#pragma unused test
}

printf("new - %d", GetTickCount()-tick);
tick = GetTickCount();
tick = GetTickCount();
for(new i; i < 1_000_000; i++)
{
SetPVarInt(playerid, "TestSet", 11);
}
printf("pVar - %d", GetTickCount()-tick);


printf("\nВозврат:");
new test = 11,
buff;
SetPVarInt(playerid, "TestGet", 11);
for(new i; i < 1_000_000; i++)
{
buff = test;
}
printf("new - %d", GetTickCount()-tick);
tick = GetTickCount();
for(new i; i < 1_000_000; i++)
{
buff = GetPVarInt(playerid, "TestGet");
}
#pragma unused buff
printf("pVar - %d", GetTickCount()-tick);
return 1;
}
Инициализация:
[20:19:14] new - 76
[20:19:15] pVar - 255
[20:19:15]
Возврат:
[20:19:15] new - 81
[20:19:15] pVar - 254

cmd:t(playerid, params[])
{
new tick = GetTickCount();
printf("\n\n\nИнициализация:");
for(new i; i < 1_000_000; i++)
{
new test = 11;
#pragma unused test
}

printf("new - %d", GetTickCount()-tick);
tick = GetTickCount();
//->
for(new i; i < 1_000_000; i++)
{
SetPVarInt(playerid, "TestSet", 11);
}
printf("pVar - %d", GetTickCount()-tick);


printf("\nВозврат:");
tick = GetTickCount(); //<-
new test = 11,
buff;
SetPVarInt(playerid, "TestGet", 11);
for(new i; i < 1_000_000; i++)
{
buff = test;
}
printf("new - %d", GetTickCount()-tick);
tick = GetTickCount();
for(new i; i < 1_000_000; i++)
{
buff = GetPVarInt(playerid, "TestGet");
}
#pragma unused buff
printf("pVar - %d", GetTickCount()-tick);
return 1;
}
И самое ведь смешное то, что вместо исправления ошибки, ты доказываешь мол "нет, это не баг а фича". Или ты реально не видишь в изменённом варианте и тестах разницы? Тогда тебе лучше не проводить их вообще.


Как и большая часть тех, кто не раскидывается ресурсами направо и налево.
Или то, что ты решил придраться к словам, намекая на моё личное мнение, отменяет тот факт, что данная "экономия" полезна?
В самом низу поста в дополнении к нему я как-бы тончайше намекунл, что действительно полезная экономия только тогда, когда она уместна.


Взгляни в темы с релизами DC_CMD и Pawn.CMD, где многие активно фапают на заявление о скорости.
Так а к чему это вообще? Иди к тем людям и спорь с ними на эту тему.


Ты пытаешься оперировать приростом, который изменяется наносекундами. Да ещё и в системе, которая вызывается всего 1 раз за всё время нахождения игрока на сервере (не считая условия в OnPlayerStateChange). Игроки и за такой неощутимый прирост в ладоши хлопать не будут. Да и причём тут игроки, когда суть в том, чтоб код, который ты написал, дружил с логикой и здравым смыслом?
В любой реализации, что с пварами, что без - код будет дружить с логикой и здравым смыслом.


С таким же успехом можно и над подсчётом размера массивов не заморачиваться, а выделять по 2000 ячеек везде и всё. Какая разница? Памяти-то много. И плевать, что если к написанию кода подходить подобным образом, рано или поздно все твои "да лааадно, памяти ведь много" перерастут в огромный ком неиспользуемой памяти, который потом придётся разгребать.

Покажи мне пример экономии памяти, которая реально на что-то влияет, не считая переполнения стэка, который можно увеличить
Так ты сам себе противоречишь что ли? Если непонятен какой-то текст - его можно перечитать. Это будет гораздо легче, чем мне ещё раз писать, что пренебрегать этим не нужно, как и не нужно корячиться над такими мелочами, которые сильно расход твоей памяти не увеличат.


Ты так говоришь, как будто у тебя на клавиатуре стоит лимит нажатий, после которых та отказывается работать. О каких ресурсах идёт речь? Тут система, которую ты раз написал и о которой забыл. От того, что ты изначально учтёшь в ней ещё и правильный расход памяти, ни тебе, ни компилятору, ни серверу, ни кому-либо ещё не убудет.
Ладно бы я предлагал тебе прикрутить к такой простой системе какие-нибудь emit'ы или какой-нибудь другой подобный, в контексте данной системы, бред, но нет, я просто предлагаю использовать память, которая в любом случае выделяется, вместо того, чтоб выделять новую. Ощущаешь разницу?
Немного не то имел в виду я. А именно под ресурсами я подразумевал свой же труд.
Конечно, если времени у тебя много и сроков разработки какого-либо проекта просто нет, то делать лучше можно даже в таких мелочах (emit'ы здесь не берём, это треш полный и нужны они далеко не всегда). Ну а если твоя задача написать код за некоторый, пусть и не короткий срок - то в попу дуть, лишь бы пару байтов сэкономить не лучшая затея.

Geebrox
13.07.2016, 21:48
Deimos, наверно ему не угодить) я то пытался объяснять сколько раз) у каждого своя правда
Он думает, что миллионная доля секунды важнее 4000 байтов (~4 килобайта) памяти

P.S. По поводу pVar, я оказываться не понял миф #9 с первого прочтения

Nexius_Tailer
13.07.2016, 21:59
Он думает, что миллионная доля секунды важнее 4000 байтов (~4 килобайта) памяти
Не миллионная, иначе бы роли такая выгода не играла абсолютно (как с теми командами). А твои 4 килобайта, это и есть как раз та капля в море, которую тебе предоставляет хостинг. Дело ведь ещё и в том, что от памяти ничего быстрее не станет вообще, при том что её относительно много по меркам сампа. А вот один большой цикл, или ещё что похуже, может нагрузить сервер так, что это будет видно игрокам даже с довольно мощным серверным оборудованием. У меня просто такое чувство, что здесь сборище теоретиков, ибо в реальной ситуации от большого потребления оперативной памяти страдает гораздо меньше людей, чем от нагрузок на процессор. И вроде очевидная вещь, однако всё равно не ясна.

Ну а насчёт "у каждого своя правда", ок. Странно просто при этом, что со своей правдой кто-то так и лезет навязывать её другим.

Geebrox
13.07.2016, 22:04
Не миллионная, иначе бы роли такая выгода не играла абсолютно (как с теми командами).

Ну так уточни, раз я не прав, докажи сколько миллисекунд уходит на инициализацию pvar (1 раз) и для удаление (тоже 1 раз, если что)


кто-то так и лезет навязывать её другим.

Кто-то не лезет, ко-то доказывает

DeimoS
13.07.2016, 22:13
И самое ведь смешное то, что вместо исправления ошибки, ты доказываешь мол "нет, это не баг а фича".

Стоило указать на конкретную ошибку, а не затирать про два GetTickCount в одном месте и то, что они должны где-то в другом месте стоять. Теперь понял о чём ты.
В любом случае, сути это не меняет. Как я сказал изначально, суть теста не в том, чтоб сравнить разницу во времени между инициализацией и возвратом значений, а в том, чтоб увидеть, что разница существенно видна лишь при очень частых вызовах. Тестирование и инициализации, и возврата я прикрутил так, к слову.


В самом низу поста в дополнении к нему я как-бы тончайше намекунл, что действительно полезная экономия только тогда, когда она уместна.

А тут она неуместна? Ты многое теряешь при попытке сэкономить память?


Так а к чему это вообще? Иди к тем людям и спорь с ними на эту тему.

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


В любой реализации, что с пварами, что без - код будет дружить с логикой и здравым смыслом.

То бишь, тот факт, что вариант с pVar никак существенно не влияет на скорость, но, при этом позволяет сэкономить память, не является для тебя сигналом о том, что этот вариант логичнее? Или ты не знаешь значения слова "логичность"?


Так ты сам себе противоречишь что ли? Если непонятен какой-то текст - его можно перечитать.
Это как раз тебе и стоит сделать, раз до тебя не дошло. Хотя я не гордый, могу и объяснить.
Про увеличение стэка при переполнении я напомнил лишь для того, что это как раз тот вариант, к которому человек должен прийти, если он будет пользоваться твоей логикой. Сам же сказал, памяти много. Так в каком тогда случае нужно оптимизировать её расход, если в этом не нужно? Где тот самый критерий, по которому можно понять: стоит ли пытаться что-то оптимизировать или нет?


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

Над чем корячится? Ты не силён в pVar? Или тебе тяжело написать чуть больше символов?


Немного не то имел в виду я. А именно под ресурсами я подразумевал свой же труд.
Конечно, если времени у тебя много и сроков разработки какого-либо проекта просто нет, то делать лучше можно даже в таких мелочах (emit'ы здесь не берём, это треш полный и нужны они далеко не всегда). Ну а если твоя задача написать код за некоторый, пусть и не короткий срок - то в попу дуть, лишь бы пару байтов сэкономить не лучшая затея.

Всё тот же вопрос: что сложного использовать pVar по их предназначению, а не массивы? Ты не знаешь в каких случаях их использовать? Или не имеешь хотя бы примерного представления о том, как будет работать твоя будущая система? В чём заключается потеря времени?

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

- - - Добавлено - - -


А твои 4 килобайта, это и есть как раз та капля в море, которую тебе предоставляет хостинг.

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


А вот один большой цикл, или ещё что похуже, может нагрузить сервер так, что это будет видно игрокам даже с довольно мощным серверным оборудованием.
Причём тут циклы и наша тема разговора? pVar ну никак не смогут навредить твоему серверу даже при самых больших онлайнах. Взгляни на результаты своего исправленного теста и раздели их на миллион. А потом отними результат pVar от результат new и получишь реальное время, которое ты выиграл для своего сервера.



У меня просто такое чувство, что здесь сборище теоретиков, ибо в реальной ситуации от большого потребления оперативной памяти страдает гораздо меньше людей, чем от нагрузок на процессор. И вроде очевидная вещь, однако всё равно не ясна.

Скорее тут один парень, который не видит разницы между какими-то сложными махинациями ради оптимизации (те же emit) и замена одной реализации переменных на другую.

Nexius_Tailer
13.07.2016, 22:16
Ну так уточни, раз я не прав, докажи сколько миллисекунд уходит на инициализацию pvar (1 раз) и для удаление (тоже 1 раз, если что)
1 раз он никогда не будет вызываться, к примеру, в OnPlayerUpdate. Ну а вот если использовать их по уму (к примеру в данной системе), то тут мизерное экономие памяти покрывает мизерные затраты во времени выполнения, не иначе как используй что хочешь, дело сводится к удобству. Кстати об удобстве, вернёмся к предыдущим постам (и о том, что мол у каждого своя правда)

Удобство? Покажи мне его... Переменная используется для 1 действии и все, алеее


Кто-то не лезет, ко-то доказывает
Смысла фразы это сильно не меняет

Geebrox
13.07.2016, 22:20
1 раз он никогда не будет вызываться, к примеру, в OnPlayerUpdate.

Причем тут OnPlayerUpdate вообще не понятно, мы вообще то говорим об OnPlayerConnect. Или в самп внесли новое изменение, что OnPlayerUpdate будет вызывать OnPlayerConnect каждый раз?

И еще будут результаты 1 разового инициализации pVar'a? Я таки тебе уточнил сколько памяти экономится (округленно конечно)

DeimoS
13.07.2016, 22:23
1 раз он никогда не будет вызываться, к примеру, в OnPlayerUpdate.

Даже вызов в OnPlayerUpdate не приведёт к лагам. Или 1 миллион раз за секунду (как в случае теста) равно, примерно, 25-30 вызовов за секунду, с коей вызывается OnPlayerUpdate?


тут мизерное экономие памяти

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

Nexius_Tailer
13.07.2016, 22:56
В любом случае, сути это не меняет. Как я сказал изначально, суть теста не в том, чтоб сравнить разницу во времени между инициализацией и возвратом значений, а в том, чтоб увидеть, что разница существенно видна лишь при очень частых вызовах. Тестирование и инициализации, и возврата я прикрутил так, к слову.
Ну так смысл пваров в том, что они для каждого игрока, и "не очень частых вызовов", будь они тут и там, при большом онлайне не будет.


То бишь, тот факт, что вариант с pVar никак существенно не влияет на скорость, но, при этом позволяет сэкономить память, не является для тебя сигналом о том, что этот вариант логичнее? Или ты не знаешь значения слова "логичность"?
Как впрочем существенно не экономит память, но влияет на скорость? - это уж как преподнести. И не тебе уж мне про логичность затирать.


Это обычное сравнение двух ситуаций. Хотя ты уже ни раз доказал, что в сравнения ты играть не умеешь.
Как и ты уже не раз доказал, что твои сравнения чаще неуместны, так и играть в них не интересно.


Про увеличение стэка при переполнении я напомнил лишь для того, что это как раз тот вариант, к которому человек должен прийти, если он будет пользоваться твоей логикой. Сам же сказал, памяти много. Так в каком тогда случае нужно оптимизировать её расход, если в этом не нужно? Где тот самый критерий, по которому можно понять: стоит ли пытаться что-то оптимизировать или нет?
Моя логика - использовать всё в меру, если ты до сих пор не понял. Вряд ли ничем не злоупотребляя можно прийти к переполнению стека.
Про "тот самый критерий" по моему стало бы понятно, если бы прочитал посты выше: как ты приводил очень "корректное" сравнение неэкономия пары байт с выделением огромного массива в 2 тысячи ячеек под каждую строку. Во втором случае, очевидно, пытаться что-то оптимизировать стоит.


Всё тот же вопрос: что сложного использовать pVar по их предназначению, а не массивы? Ты не знаешь в каких случаях их использовать? Или не имеешь хотя бы примерного представления о том, как будет работать твоя будущая система? В чём заключается потеря времени?
Как это не знаю, если сам говорю, в каких случаях? И я тебе даже не про то, что это займёт огромного количества времени (потому что про время я говорил скорее об оптимизации памяти в целом). Я тебе о том, о чём, наверное уже несколько постов одно и тоже говорю - о приоритетах скорости над памятью и об умеренном использовании что того, что другого.


Что тебе мешает воспринимать pVar как разновидность переменных - одному богу известно. Но логики я в твоих словах не вижу
Ничего, я так и делаю. Странно с чего ты это взял. Если ты запутался в своих же аргументах, то напомню: здесь началось всё с того, что начали предлагать реализацию пваров, ссылаясь как плюс на экономие ими памяти, ну а минусов... а минусов как будто бы и нет. Начав их описывать, мне почему-то ты одно и тоже начал рассказывать несколько страниц подряд (при том что я не говорил, что от них нужно избавляться вообще, заметь. Тут мне кажется, у кого-то просто нет чувства меры, вот и всё).


Я тебе уже говорил: 4 килобайта ты выделил впустую тут, 4 килобайта там и в конечном итоге получилось, что память подошла к концу... Хочешь говнокодить - пожалуйста. Но ты хотя бы признавай факт говнокода и признавай то, что есть иные, более правильные, реализации.
Если допускать такое, чтобы она подходила к концу, то да, это говнокод. Иначе же нет.


Причём тут циклы и наша тема разговора? pVar ну никак не смогут навредить твоему серверу даже при самых больших онлайнах. Взгляни на результаты своего исправленного теста и раздели их на миллион. А потом отними результат pVar от результат new и получишь реальное время, которое ты выиграл для своего сервера.
Так и ты тогда возьми свои 4 килобайта и умножь их на столько, чтобы получить хотя-бы гигабайт. Сколько килобайт в итоге ты выиграл для своего сервера?


Скорее тут один парень, который не видит разницы между какими-то сложными махинациями ради оптимизации (те же emit) и замена одной реализации переменных на другую.
Про не видение разницы уже написал. Одни "сравнения" чего стоят.

DeimoS
13.07.2016, 23:26
Ну так смысл пваров в том, что они для каждого игрока, и "не очень частых вызовов", будь они тут и там, при большом онлайне не будет.
Где это про не очень частые вызовы написано?
И при большом онлайне ничего ровным счётом не изменится


Как впрочем существенно не экономит память, но влияет на скорость? - это уж как преподнести. И не тебе уж мне про логичность затирать.
А кому? Тебе? Человеку, который хочет информацию, которая будет использоваться только при входе, хранить постоянно? Ну окей, рассказывай


Как и ты уже не раз доказал, что твои сравнения чаще неуместны, так и играть в них не интересно.
Если ты не смог понять их смысл, дело не в них, а в тебе, не? Кто же виноват, что для тебя, судя по твоей вечной реакции, сравнением будет являться только сравнение "pVar с new" и "pVar с new". А провести параллель с чем-либо другим - это уж не к нам, мы такого не умеем, нас такому не учили


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

Так а как понять, где та самая мера? И чем тебе pVar не угодили?


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

Лол, разница между моим и твоим примером - 1000 ячеек. О каких паре байт идёт речь? Или ты забыл значение макроса MAX_PLAYERS?
Или ты "экономишь" силы только в случае этой системы, а больше нигде не выкидываешь по 1000 ячеек впустую?


Как это не знаю, если сам говорю, в каких случаях? И я тебе даже не про то, что это займёт огромного количества времени (потому что про время я говорил скорее об оптимизации памяти в целом). Я тебе о том, о чём, наверное уже несколько постов одно и тоже говорю - о приоритетах скорости над памятью и об умеренном использовании что того, что другого.
А теперь найди мой второй пост в этой теме и узри там результаты теста. А потом раздели результат инициализации на миллион и узри, насколько сильно ты выиграешь в скорости. А потом попробуй всё же подумать: стоит ли 0,000179 миллисекунды того, чтоб 4 килобайта памяти висели без дела? Такой себе КПД выходит, не кажется?



Ничего, я так и делаю. Странно с чего ты это взял. Если ты запутался в своих же аргументах, то напомню: здесь началось всё с того, что начали предлагать реализацию пваров, ссылаясь как плюс на экономие ими памяти, ну а минусов... а минусов как будто бы и нет. Начав их описывать, мне почему-то ты одно и тоже начал рассказывать несколько страниц подряд (при том что я не говорил, что от них нужно избавляться вообще, заметь. Тут мне кажется, у кого-то просто нет чувства меры, вот и всё).
О чём ты говоришь? В чём я запутался? Не ты ли говоришь о каком-то выигрыше во времени и жертве ради этого памяти?
Твои слова звучат настолько тупо, что даже комментировать это не хочется...


Если допускать такое, чтобы она подходила к концу, то да, это говнокод. Иначе же нет.
А она у тебя бесконечная, да? Или ты не паришься по поводу чего-либо, пока не припрёт?



Так и ты тогда возьми свои 4 килобайта и умножь их на столько, чтобы получить хотя-бы гигабайт. Сколько килобайт в итоге ты выиграл для своего сервера?
Как минимум, я не потерял 4 килобайта, которые уйдут на другие нужды. А сколько ты выиграл времени?


Про не видение разницы уже написал. Одни "сравнения" чего стоят.

Вставать в позицию "твои аргументы - фигня, и контраргументов не будет" - это, конечно, круто.

Nexius_Tailer
13.07.2016, 23:48
Где это про не очень частые вызовы написано?

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


И при большом онлайне ничего ровным счётом не изменится
Как сказать. Умножь свой результат на 1000



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


Если ты не смог понять их смысл, дело не в них, а в тебе, не? Кто же виноват, что для тебя, судя по твоей вечной реакции, сравнением будет являться только сравнение "pVar с new" и "pVar с new". А провести параллель с чем-либо другим - это уж не к нам, мы такого не умеем, нас такому не учили
Вас может и не учили. Если бы не понял смысл - не писал бы, что они некорректны и неуместны. А ведь всё именно так.


Так а как понять, где та самая мера? И чем тебе pVar не угодили?
С какого раза нужно тебе написать, чтоб дошло, что ничем?
А понять возможно так, что при явном выделении огромного количества памяти, к примеру, под строки (опять к примеру, что-ли), можно банально примерно предположить, сколько займёт в ней текст.


Лол, разница между моим и твоим примером - 1000 ячеек. О каких паре байт идёт речь? Или ты забыл значение макроса MAX_PLAYERS?
Или ты "экономишь" силы только в случае этой системы, а больше нигде не выкидываешь по 1000 ячеек впустую?
Так и строки ты чаще всего будешь выделять на каждом шагу, и возможно даже в локальной памяти, при том что те переменные будут всегда будут в глобальной.


А теперь найди мой второй пост в этой теме и узри там результаты теста. А потом раздели результат инициализации на миллион и узри, насколько сильно ты выиграешь в скорости. А потом попробуй всё же подумать: стоит ли 0,000179 миллисекунды того, чтоб 4 килобайта памяти висели без дела? Такой себе КПД выходит, не кажется?
На 1000 умножал? Или забыл значение макроса MAX_PLAYERS?


О чём ты говоришь? В чём я запутался? Не ты ли говоришь о каком-то выигрыше во времени и жертве ради этого памяти?
Нет, скорее о какой-то жертве памятью ради выигрыша во времени.


А она у тебя бесконечная, да? Или ты не паришься по поводу чего-либо, пока не припрёт?
Нет, изначально просто трезво к этому подхожу.


Как минимум, я не потерял 4 килобайта, которые уйдут на другие нужды. А сколько ты выиграл времени?
Десятую долю секунды, которая уйдёт на другие нужды.


Вставать в позицию "твои аргументы - фигня, и контраргументов не будет" - это, конечно, круто.
Как не будет, выше же.

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

DeimoS
14.07.2016, 00:32
При большом онлайне и очень частые вызовы будут.
И что? Они будут одновременные?
Даже если представить, что 1000 игроков одновременно зайдёт на сервер (у них будет совершенно одинаковый пинг и сервер примет их пакеты чётко по очереди, что в принципе невозможно), на обработку их всех у сервера уйдёт 0,179 миллисекунды. Всё прямо зависнет...






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



Вас может и не учили. Если бы не понял смысл - не писал бы, что они некорректны и неуместны. А ведь всё именно так.
А что бы ты писал, если бы не понял смысла, лол? Ты потому и не понял смысла, что не смог провести параллель между моими примерами и ситуацией.


А понять возможно так, что при явном выделении огромного количества памяти, к примеру, под строки (опять к примеру, что-ли), можно банально примерно предположить, сколько займёт в ней текст.
То бишь, оптимизировать нужно только большие объёмы памяти. Но 1000 ячеек - не большой объём памяти... Ты, видиимо, используешь строки в 10к символов и более, да?


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



На 1000 умножал? Или забыл значение макроса MAX_PLAYERS?
Лол, и что? 0,179 миллисекунды при самом худшем исходе, который просто не сможет произойти в силу особенностей интернета. Вопрос всё тот же: много ли ты выиграл, поставив на кон 1000 ячеек?


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



Нет, изначально просто трезво к этому подхожу.

Настолько трезво, что кладёшь болт на логику (на эту часть моего сообщения не отвечай. Лучше удели время моему вопросу в конце)


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




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

Прошу, начни писать по-русски. Перечитав эту часть твоего сообщения 5 раз, я всё ещё смутно понял её смысл. Видимо, именно поэтому мы до сих пор и общаемся...


А вот и вопрос, о котором я говорил:
Ты действительно считаешь, что гораздо логичнее информацию, которая будет использоваться исключительно при входе на сервер, хранить всё время, а не только в момент, когда игрок входит на сервер? Можешь даже не отвечать на всё то, что я написал выше. Ответ на этот вопрос расставит все точки над "i": либо ты начнёшь противоречить своим замечаниям в сторону Geebrox, либо ты настолько "оптимизатор-3000", что разговор дальше не имеет смысла быть.

Daniel_Cortez
14.07.2016, 01:07
Накидал тут свой тест производительности обычных переменных на Pawn и PVar'ов.


CMD:profile(playerid, params[])
{
const PROFILE_ITERATIONS_MAJOR = 10_000,
PROFILE_ITERATIONS_MINOR = 100;
const NUM_PVARS = 100;
static const pvar_name_prefix[] = "pvar_%03d";
static pvar_name[sizeof(pvar_name_prefix) + (- 4 + 3)];
static arr[2], x;
for (i = 0; i < NUM_PVARS; ++i)
{
format(pvar_name, sizeof(pvar_name), pvar_name_prefix, i);
SetPVarInt(playerid, pvar_name, 0);
}
static x, y;
static t, t1, t2, t3, t4;
t1 = 0, t2 = 0, t3 = 0, t4 = 0;
for (i = PROFILE_ITERATIONS_MAJOR; i-- != 0; )
{
t = GetTickCount();
for (j = PROFILE_ITERATIONS_MINOR; j-- != 0; )
y = x;
t1 += GetTickCount() - t;
t = GetTickCount();
for (j = PROFILE_ITERATIONS_MINOR; j-- != 0; )
y = GetPVarInt(playerid, pvar_name);
t2 += GetTickCount() - t;
t = GetTickCount();
for (j = PROFILE_ITERATIONS_MINOR; j-- != 0; )
x = 42;
t3 += GetTickCount() - t;
t = GetTickCount();
for (j = PROFILE_ITERATIONS_MINOR; j-- != 0; )
SetPVarInt(playerid, pvar_name, 42);
t4 += GetTickCount() - t;
}
new results_buf[128 + 1];
new jit_enabled;
#emit zero.pri
#emit lctrl 7
#emit stor.s.pri jit_enabled
format(results_buf, sizeof(results_buf), "JIT: %s", jit_enabled ? ("on") : ("off"));
print(results_buf);
SendClientMessage(playerid, -1, results_buf);
format(results_buf, sizeof(results_buf), "Total PVars: %d", NUM_PVARS);
print(results_buf);
SendClientMessage(playerid, -1, results_buf);
format(results_buf, sizeof(results_buf), "Pawn variable get: %d", t1);
print(results_buf);
SendClientMessage(playerid, -1, results_buf);
format(results_buf, sizeof(results_buf), "PVar get: %d", t2);
print(results_buf);
SendClientMessage(playerid, -1, results_buf);
format(results_buf, sizeof(results_buf), "Pawn variable set: %d", t3);
print(results_buf);
SendClientMessage(playerid, -1, results_buf);
format(results_buf, sizeof(results_buf), "PVar set: %d", t4);
print(results_buf);
SendClientMessage(playerid, -1, results_buf);
#emit load.pri y
}



JIT: off
Total PVars: 1
Pawn variable get: 85
PVar get: 4152
Pawn variable set: 91
PVar set: 4100

JIT: on
Total PVars: 1
Pawn variable get: 38
PVar get: 4114
Pawn variable set: 47
PVar set: 4077

JIT: off
Total PVars: 20
Pawn variable get: 95
PVar get: 4427
Pawn variable set: 73
PVar set: 4353

JIT: off
Total PVars: 100
Pawn variable get: 89
PVar get: 5360
Pawn variable set: 86
PVar set: 5487

В сравнении с тестом DeimoS'а разница куда большая. Возможно это из-за того, что в первом образце кода нет создания переменной в цикле. (Как можно было вообще додуматься так насиловать стек? Конечно, тогда обычная переменная будет "откликаться" медленнее.)
Ещё один вариант: в предыдущем тесте для каждого отрывка используется цикл на миллион итераций. Скорее всего процессор просто помещает нужные блоки памяти из секций данных и кода в процессорный кэш, что и влияет на производительности. В реальных ситуациях такое вряд ли возможно.
В моём же тесте используются вложенные циклы: 1-го уровня на 10 000 итераций и второго на 100. В результате получается тот же миллион итераций, но без побочных эффектов с кэшированием. Но про кэширование это лишь моя догадка.

При включении JIT повышается быстродействие обычных переменных (что в принципе логично, JIT повышает производительность кода на Pawn, а не нативных функций).
При увеличении кол-ва активных PVar'ов наоборот увеличивается время их отклика. На самом деле, для самого первого PVar'а время остаётся таким же, а для последующих оно увеличивается пропорционально с увеличением внутреннего ID.
Иными словами, чем позднее создан PVar, тем больше время его отклика. Это происходит из-за того, что сервер совершает линейный поиск по всем слотам для PVar'ов в поисках слота с нужным именем.
И да, если кто-то назовёт меня теоретиком, аргументируя, что в реальных проектах не используется так много PVar'ов - посмотрите сначала на исходники какого-нибудь крупного проекта (например, WCRP - там по какой-то странной причине PVar'ы используются практически для всего).

Btw, упаковав массив, можно использовать вчетверо меньше памяти, при этом практически не жертвуя скоростью в сравнении с PVar. Что собственно и сделал автор темы.





Видимо что-то изменилось, по крайней мере так было раньше:
- "In Visual C++4.2, the Standard C++ header files contained a typedef that equated bool with int. In Visual C++ 5.0 and later, bool is implemented as a built-in type with a size of 1 byte. That means that for Visual C++ 4.2, a call of sizeof(bool) yields 4, while in Visual C++ 5.0 and later, the same call yields 1" - источник (https://msdn.microsoft.com/en-us/library/tf4dy80a(v=vs.100).aspx)
- "В памяти компьютера значения констант и переменных типа bool занимают 4 байта." - источник (https://book.mql4.com/ru/basics/types)

Да, размер bool зависит от реализации (т.е. от компилятора или стандартной библиотеки)... как и всё остальное в C++ -__-



- "Учтите, что тип BOOL в C имеет размер 4 байта (= sizeof(int)), а тип Boolean состоит только из одного." - источник (http://www.transl-gunsmoker.ru/2009/04/bool-boolean-integer.html)

Так это ж кастомный тип, который специфичен только для функций WIN32 API.


По рукам ходят.
В любом случае, исходники из Open SA-MP явно основаны на слитых исходниках от куя. Об этом можно судить, например, по наличии файлов с расширением ".cpp.orig" в дополнение к файлам с тем же именем, но расширением ".cpp" (например, "func_amx.cpp" и "func_amx.cpp.orig").
Также в исходниках Pawn AMX присутствуют все модификации, которые были сделаны в рамках SA-MP: например, куй отключил опкоды "jump.pri" и "call.pri" (сделано из соображений "безопасности", если верить комментариям в коде).
И да, в тех же исходниках Pawn AMX можно найти дату изменения (видимо, в SA-MP Team тоже пользовались утилитой svnrev, которой пользовался и разработчик Pawn):
А вот что можно найти в amx.c: https://github.com/Sasuke78200/open-samp/blob/master/Open%20SAMP/amx/amx.c#L2096


op_call_pri:
// Kye SA-MP Team 9/9/2009 Unsecure opcode
//PUSH((unsigned char *)cip-code);
//cip=(cell *)(code+(int)pri);
//NEXT(cip);
assert(0);
ABORT(amx,AMX_ERR_INVINSTR);

"9/9/2009" - это позднее выхода 0.2x (20.11.2008) и раньше даты релиза 0.3a (19.10.2009), т.е. исходники либо от одной из предрелизных версий 0.3, либо от релиза 0.3a или более поздних версий.
Как раз в одной из ревизий 0.3a добавили PVar'ы, так что в исходниках Open SA-MP они вряд ли являются результатом обратной разработки.

Nexius_Tailer
14.07.2016, 02:01
Какие другие случаи? pVar есть смысл использовать только тогда, когда какую-то информацию нужно хранить короткий промежуток времени. И даже если тебя так пугает случаи вызова pVar в цикле, в результате которой ты теряешь наносекунды, ты всегда можешь этот самый pVar записать в локальную переменную и использовать её.
Могу, и, собственно, так и делаю как правило.


А что бы ты писал, если бы не понял смысла, лол? Ты потому и не понял смысла, что не смог провести параллель между моими примерами и ситуацией.
Так бы и написал. Да и было бы тут что понимать. Если тебе каждый раз объяснять, почему твоя параллель неуместна, клавиатура бы уже и загнулась. С теми же командными процессорами: команды нынче не столько используются, сколько использовались раньше по количеству, у многих на данный момент всё на диалогах/текстдравах, потому это не то направление, где уместна активная доработка прироста скорости.
Тут же мы будем иметь действительно уйму систем, одной-то защитой обхода логина не ограничится.
Я к тому, что команды - грубо говоря прошлый век, и гнаться за их производительностью уже смешно не потому, что за ней гонятся до такой степени, а потому, что они просто для многих перестают быть актуальной темой, всё необходимое уже в той области "изобретено".


То бишь, оптимизировать нужно только большие объёмы памяти. Но 1000 ячеек - не большой объём памяти... Ты, видиимо, используешь строки в 10к символов и более, да?
Нет


Лол, и что? 0,179 миллисекунды при самом худшем исходе, который просто не сможет произойти в силу особенностей интернета. Вопрос всё тот же: много ли ты выиграл, поставив на кон 1000 ячеек?
Так а много ли я проиграл? "Целых 1000!!" только и слышу. Это всего-лишь 1 килобайт (лол, и то меньше же)


Настолько трезво, что кладёшь болт на логику (на эту часть моего сообщения не отвечай. Лучше удели время моему вопросу в конце)
Уделю, не волнуйся. Опять-же, нет, не кладу


Оптимистичные расчёты. Только вот если бы ты умел в математику, ты бы знал, что там не десятые доли секунды, а сотые доли миллисекунды. Игроки оценили
А, опечатка. Тем не менее игроки также и оценили твои 4 килобайта


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


Ты действительно считаешь, что гораздо логичнее информацию, которая будет использоваться исключительно при входе на сервер, хранить всё время, а не только в момент, когда игрок входит на сервер? Можешь даже не отвечать на всё то, что я написал выше. Ответ на этот вопрос расставит все точки над "i": либо ты начнёшь противоречить своим замечаниям в сторону Geebrox, либо ты настолько "оптимизатор-3000", что разговор дальше не имеет смысла быть.
Нет, не считаю.
Отвечу на всякий случай третий раз, авось дойдёт: я описал минусы пваров в самом начале, одним из них и являлось то, что они уступают в скорости переменным.
А противоречить "замечаниям" Geebrox'а мне незачем, ибо удобство для каждого по своему понимается.

DeimoS
14.07.2016, 11:29
Нет, не считаю.
Отвечу на всякий случай третий раз, авось дойдёт: я описал минусы пваров в самом начале, одним из них и являлось то, что они уступают в скорости переменным.

Засим и закончим.
Главное не узнай, что обращение к последним ячейкам массива быстрее, нежели к первым (или к одной переменной). А то начнёшь, ради прироста к скорости, создавать по 1000 переменных для каждого игрока...
Если ты до сих пор не понял, то всё это время я пытался тебе объяснить, что нет у pVar существенных минусов: ни в скорости (тесты и расчёты есть), ни в удобстве использования, ни в чём либо ещё. Спорил бы ты с Созоновым, он бы назвал это синдромом утёнка...
Желаешь без повода раскидываться памятью - пожалуйста. Но учить этому других не стоит. Учить подобному - удел п-и.

P.S. И переставай уже пытаться строить из себя такую мессию, постоянно пытаясь сказать, что говоришь мне про одно и то же, а я, дурак такой, всё никак не могу понять тебя. Это у тебя фишка такая: участвовать в споре на определённую тему, отстаивая свою точку зрения, и постоянно заканчивать его одним и тем же? Хотя это риторический вопрос, есчо


Засим и закончим.

- - - Добавлено - - -



В сравнении с тестом DeimoS'а разница куда большая. Возможно это из-за того, что в первом образце кода нет создания переменной в цикле. (Как можно было вообще додуматься так насиловать стек?

Это создано с целью уровнять условия, не? Хотя, в идеале, к SetPVar нужно было прикрутить ещё и разные имена, дабы функция постоянно резервировала новые участки "своей" памяти, а не работала с одним. Так я думал изначально.
Но уже после публикации теста я понял, что предыдущие мои мысли не верны и, во-первых, pVar работают чуть иначе, и, во-вторых, вряд ли их работа сравнима с резервацией стэка.
В любом случае, суть теста была не в точности, а в том, что различие в скорости там совсем несущественные (хоть разница между переменными/pVar и большая, но если взять конкретно результат pVar и вычислить примерное время обращения к одному pVar, можно понять, что ничего страшного не произойдёт (не будет ничего виснуть и т.п.). Именно в этом и заключалась суть всего моего повествования и моего кривого теста, в том числе.

Была бы в Pawn иная альтернатива хоть какой-то динамической памяти - можно было бы использовать её. Но пока выбирать не приходится и, как по мне, логичнее подобную временную информацию хранить временно, а не держать её постоянно только ради того, чтоб сэкономить пару тысячных миллисекунды.

И да, я говорю про "правильное" использование pVar, с удалением оных после использования, а не присвоения им нулевого значения, как делают многие. Тогда они копиться не должны (использовал при авторизации, загрузив в них пароль, сверил и удалил. Использовал в какой-нибудь команде, дабы передать введённые игроком параметры в диалог, и удалил. И так со всей временной информацией), хоть это и не является большой проблемой

Nexius_Tailer
14.07.2016, 14:13
Главное не узнай, что обращение к последним ячейкам массива быстрее, нежели к первым (или к одной переменной). А то начнёшь, ради прироста к скорости, создавать по 1000 переменных для каждого игрока...
Давно знал. Так это уже в удобстве проигрывает)


Если ты до сих пор не понял, то всё это время я пытался тебе объяснить, что нет у pVar существенных минусов: ни в скорости (тесты и расчёты есть), ни в удобстве использования, ни в чём либо ещё.
Ну а если ты не понял - ты мне объяснял про то, что я трачу память, но увеличиваю лишь чуть-чуть скорости, а я тебе про то - что увеличиваю скорость, тратя лишь чуть-чуть памяти. Я уж думал ты сам глубже зайдёшь и вдруг напишешь, что повторяем мы друг другу одно и то же, а ведь понять это оказалось более чем сложным. Я-то сразу сказал на этот счёт свою точку зрения: мне важнее скорость, чем память (даже в ситуациях, когда и того и другого потребляется мизерное количество).


Желаешь без повода раскидываться памятью - пожалуйста. Но учить этому других не стоит. Учить подобному - удел п-и.
Ну вот и опять
На это можно смотреть с разных сторон, и если я опять повторю, типо, "желаешь раскидываться скоростью - пожалуйста", то вангую, что ты напишешь мне опять про мизерное количество этой скорости, продолжая описывать свои сэкономленные 4 килобайта.


P.S. И переставай уже пытаться строить из себя такую мессию, постоянно пытаясь сказать, что говоришь мне про одно и то же, а я, дурак такой, всё никак не могу понять тебя. Это у тебя фишка такая: участвовать в споре на определённую тему, отстаивая свою точку зрения, и постоянно заканчивать его одним и тем же? Хотя это риторический вопрос, есчо
Вот что из себя и пытался строить, так это в последнюю очередь мессию, честно

Geebrox
14.07.2016, 21:25
Этот спор можно продолжать вечно, кто-то считает, что тратит мизерное кол-во памяти, но при этом получает быстрый функционал. А кто-то считает, что теряет мизерное кол-во скорости, но при этом не тратит памяти, которое можно использовать в других целях. Каждый отстаивает свою точку зрения (глаза видят только то, что разум готов постичь). Если оба оппонента уверены в своей правоте и не желают слушать других, то есть ли смысл продолжать такой спор? Может хватит?!? Все привели свои аргументы и факты. Люди, прочитав эти доказательства, выберут для себя верный способ.

//DeimoS: Мы и так закончили уже ведь :)

123
04.08.2016, 23:45
Подскажите, как все же обойти регистрацию этим способом (для теста)

Nexius_Tailer
05.08.2016, 00:59
Подскажите, как все же обойти регистрацию этим способом (для теста)
Только сторонним софтом.

TBoPoIIIoK
05.08.2016, 11:14
Подскажите, как все же обойти регистрацию этим способом (для теста)

https://www.youtube.com/watch?v=OD6a52nnEAw

123
07.08.2016, 17:14
https://www.youtube.com/watch?v=OD6a52nnEAw

Спасибо, а обход сработает, если авторизация / регистрация вызывается в OnPlayerConnect, а не в OnPlayerRequestClass? Просто не получается повторить, как я понял, после нажатия Wait Connect, нужно тыкать на разморозку в собейте, но при нажатие у меня на полсекунды появляется экран возле особняка, после камера возвращается обратно на регистрацию / авторизацию.

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

TBoPoIIIoK
07.08.2016, 17:49
Спасибо, а обход сработает, если авторизация / регистрация вызывается в OnPlayerConnect, а не в OnPlayerRequestClass? Просто не получается повторить, как я понял, после нажатия Wait Connect, нужно тыкать на разморозку в собейте, но при нажатие у меня на полсекунды появляется экран возле особняка, после камера возвращается обратно на регистрацию / авторизацию.

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

Сработает, если в добавок перекрыть вывод диалогов и изменение позиции камеры ;)