Перейти к содержанию

Помогите сделать телепорт


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

54 minutes ago, Foxhound said:

Если не трудно, растолкуй, что делает
shr ax,#15

GetAsyncKeyState возвращает тип SHORT, у которого последний бит может быть 0 (не нажато с последнего вызова этой функции) и 1 (нажато, соотв). SHORT - это 2 байта, т.е. 2*8 бит, итого 16, проверяется последний бит. Как проверяется? Например, побитовым сдвигом, что и делает shr - в данном случае, пихает 16-й бит (считаем с нуля) в регистр ax. Дальше идет проверка, есть ли там 1. GAKS - не самая надежная функция, хорошо она работает только с одним монитором, без виртуальных рабочих столов и без кучи разных потоков, но для наших нужд вполне сгодится.

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

28 minutes ago, keng said:

для наших нужд вполне сгодится

 

Спасибо, в целом понятно.

 

Тогда поясни ещё пожалуйста, есть ли принципиальная разница между:

    call GetAsyncKeyState
    shr ax,#15
    cmp ax,1

    jne

и

    call GetAsyncKeyState
    cmp al,1

    jne

или например

    call GetAsyncKeyState
    test al,al
    jz

Чисто внешне все варианты как-будто работают нормально. Это просто разные способы реализации одного и того же действия или первый вариант со сдвигом предпочтительнее? Если да, то чем?

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

3 часа назад, Foxhound сказал:

Это просто разные способы реализации одного и того же действия или первый вариант со сдвигом предпочтительнее? Если да, то чем?

Эта функция вернет ноль в EAX/RAX только если у нее не получится выполнить свою работу. В остальных случаях она вернет результат, состояние "нажато" - "не нажато" которого будет определяться 16-м битом. То есть test или cmp всегда сработают, независимо от положения этого самого шестнадцатого бита. По-хорошему нужно делать именно сдвиг и смотреть на бит.

 

Вот пример. Допустим, что пришел нам результат в EAX:

Spoiler

EAX:
11111111111111111111111111111101 - нажато

AX:
1111111111111101

делаем shr 15, двигая все влево:
10000000000000

Теперь делаем cmp 1 и получаем ОК

EAX
11111111111111111111111111111100 - не нажато

AX:
1111111111111100

делаем shr 15, двигая все влево:
00000000000000

Теперь делаем cmp 1 и получаем НЕ ОК



Если делать это без сдвига, то cmp и test вернут ОК в обоих случаях, вот и вся разница.

 

  • Плюс 2
Ссылка на комментарий
Поделиться на другие сайты

Just now, keng said:

Вот пример.

 

Спасибо, очень наглядно.
Так... Правильно ли я понял по твоему примеру, что в случае со сдвигом мы определяем состояние только последней (первой?) единицы, которая нас интересует, а остальные как бы отбрасываем, т.е. их состояние роли не играет и может быть каким угодно? А во втором случае, без сдвига, проверка нажатия будет нормально работать только если на месте всех этих "лишних" единичек будут нули, в противном случае мы получим постоянное срабатывание независимо от состояния интересующей нас единицы, поскольку проверяем в т.ч. и "лишние"? ЗЫ. Сорри за корявое изложение.

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

33 minutes ago, Foxhound said:

 

Спасибо, очень наглядно.
Так... Правильно ли я понял по твоему примеру, что в случае со сдвигом мы определяем состояние только последней (первой?) единицы, которая нас интересует, а остальные как бы отбрасываем, т.е. их состояние роли не играет и может быть каким угодно? А во втором случае, без сдвига, проверка нажатия будет нормально работать только если на месте всех этих "лишних" единичек будут нули, в противном случае мы получим постоянное срабатывание независимо от состояния интересующей нас единицы, поскольку проверяем в т.ч. и "лишние"? ЗЫ. Сорри за корявое изложение.

Все так. Вот у тебя байт: "00000000", 8 бит, в каждом - ноль. В этом случае cmp 0 скажет ОК, cmp 1 скажет НЕ ОК. То есть когда ноль везде - то это однозначно ноль, а когда есть хоть где-нибудь единица - то уже НЕ ноль. А нас интересует только самый последний бит. Shr при этом не только "двигает" бит, но и все предыдущие заполняет нулями. Вот так: 0001 -> 0010 -> 0100 -> 1000.  Shl делает то же самое, но двигает в другую сторону (побитовый сдвиг влево - left / right).

 

ОффтопЪ: В моем посте с примером под спойлером чота все куда-то поехало в теге code. Как-то криво все-таки bb-тэги работают, или просто я не очень умный.

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

Just now, keng said:

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

 

Уяснил, спасибо за науку. :)

  • Плюс 1
Ссылка на комментарий
Поделиться на другие сайты

Вопрос в продолжение темы.
Как с помощью СЕ можно изменять только один бит? Скажем, значение = FF, т.е. 11111111. Как изменить или заморозить только одну-две-три из этих единичек в произвольных сочетаниях?
В игре каждая единичка означает какой-либо статус юнита - положительный, отрицательный или специальный. Нужно иметь возможность фиксировать/менять одни статусы, не трогая другие.

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

16 минуту назад, Foxhound сказал:

Вопрос в продолжение темы.
Как с помощью СЕ можно изменять только один бит? Скажем, значение = FF, т.е. 11111111. Как изменить или заморозить только одну-две-три из этих единичек в произвольных сочетаниях?
В игре каждая единичка означает какой-либо статус юнита - положительный, отрицательный или специальный. Нужно иметь возможность фиксировать/менять одни статусы, не трогая другие.

Можно попонятнее?)
Возможно отвечу :)

А так это фильтры делать больше сказать не могу.

Изменено пользователем what228
Ссылка на комментарий
Поделиться на другие сайты

29 minutes ago, Foxhound said:

Вопрос в продолжение темы.
Как с помощью СЕ можно изменять только один бит? Скажем, значение = FF, т.е. 11111111. Как изменить или заморозить только одну-две-три из этих единичек в произвольных сочетаниях?
В игре каждая единичка означает какой-либо статус юнита - положительный, отрицательный или специальный. Нужно иметь возможность фиксировать/менять одни статусы, не трогая другие.

Побитовым сдвигом в скрипте, как мне кажется. Команды "SHL"/"SHR". Или через Lua, но я его не люблю и не пользуюсь, так что тут не подскажу.

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

Just now, what228 said:

Можно попонятнее?)

 

Смотри. Скажем, есть юнит в военной игре. У него могут быть разные игровые статусы, положительные и отрицательные: усталость, паника, воодушевление и т.д.. Могут быть также специальные статусы: сапёры разминируют, инженеры наводят понтон, пехота окапывается и т.п.. Все эти статусы одновременно выражены одни числом, каждый бит которого отвечает за наличие/отсутствие отдельного статуса. Например, пехота устала - 01, пехота окапывается - 02, пехота в панике - 04. Тогда усталая пехота в панике будет - 05, а если она при этом ещё и окапывается, то 07 или в двоичной 111, где каждая единица означает есть или нет статус. Так вот как из этого 111 обнулить и заморозить первую и последнюю единицы, не трогая вторую, т.е. убрать усталость и панику, но оставить окапывание?

 

 

Just now, keng said:

Побитовым сдвигом в скрипте, как мне кажется. Команды "SHL"/"SHR".

 

Тоже так подумал (потому и спросил здесь), но не знаю как.

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

2 минуты назад, Foxhound сказал:

 

Смотри. Скажем, есть юнит в военной игре. У него могут быть разные игровые статусы, положительные и отрицательные: усталость, паника, воодушевление и т.д.. Могут быть также специальные статусы: сапёры разминируют, инженеры наводят понтон, пехота окапывается и т.п.. Все эти статусы одновременно выражены одни числом, каждый бит которого отвечает за наличие/отсутствие отдельного статуса. Например, пехота устала - 01, пехота окапывается - 02, пехота в панике - 04. Тогда усталая пехота в панике будет - 05, а если она при этом ещё и окапывается, то 07 или в двоичной 111, где каждая единица означает есть или нет статус. Так вот как из этого 111 обнулить и заморозить первую и последнюю единицы, не трогая вторую, т.е. убрать усталость и панику, но оставить окапывание?

 

 

 

Тоже так подумал (потому и спросил здесь), но не знаю как.

На какой игре это ты хочешь проделать? Хочу проверить и отпишусь если что.
Ну и если можно то дать не много данных :D а то самому искать с нуля не очень хочетЦа.

Изменено пользователем what228
Ссылка на комментарий
Поделиться на другие сайты

Just now, Foxhound said:

Тоже так подумал (потому и спросил здесь), но не знаю как.

Предположу, что тебе нужно сделать самый сложный вариант - выбрать бит, который ты меняешь. Заводишь под него флаг. Находишь инструкцию, которая читает значение, что тебе нужно изменить. Делаешь инъекцию. В инъекции еще один флаг (как в телепорте) - нужно ли делать замену бита. Дальше механизм такой. Нужное значение кладешь в регистр, номер бита (из второго флага) - в другой регистр. И делаешь XOR, типа XOR EAX,EBX. После этого, если в EAX лежало нужное тебе значение, бит под номером EBX поменяется на противоположный. Кладешь новое значение из EAX обратно туда, где оно было при инъекции. Сбрасываешь нужные флаги. Все.

  • Плюс 1
Ссылка на комментарий
Поделиться на другие сайты

Just now, keng said:

Все.

 

Спасибо.
Да уж... Не, для меня это пока слишком сложно.

 

 

Just now, what228 said:

На какой игре это ты хочешь проделать? Хочу проверить и отпишусь если что.
Ну и если можно то дать не много данных :D а то самому искать с нуля не очень хочетЦа.

 

Мне хотелось понять сам принцип, можно ли это сделать и насколько сложно. Такая конструкция статусов применяется нередко. В настоящий момент я пробую на серии стареньких пошаговых стратегий Panzer Campaigns, там всё просто ломается даже для меня. Если хочешь, можешь поэкспериментировать.
Официальный сайт серии:
http://www.johntillersoftware.com/PanzerCampaigns.html
Прямая ссылка на официальный сайт на скачивание полноценной демо (144МВ):
http://www.johntillersoftware.com/download/Mius43_101.msi
Ну или в "одном хорошем месте", сам знаешь где, есть вся серия.
Самодельный скрипт на структуру выделенного в данный момент юнита, подходит почти на любую игру из серии:

Spoiler

[ENABLE]

aobscan(INJECT,8B 6F 10 89 44 24 1C 03 C2)
alloc(newmem,$1000)

label(code)
label(return)
label(pMan)
registersymbol(pMan)
registersymbol(INJECT)

newmem:

pMan:

 dd 0

code:
    mov ebp,[edi+10]
    mov [pMan],edi
    mov [esp+1C],eax
    jmp return

INJECT:
	jmp code
	nop
	nop

return:

[DISABLE]

INJECT:
	mov ebp,[edi+10]
	mov [esp+1C],eax

unregistersymbol(pMan)
unregistersymbol(INJECT)
dealloc(newmem)

 

По адресу pMan+10 - численность юнита, а по адресу pMan+1C - тот самый "побитовый" статус.

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

Ухх 5 гигов ( если с торрентов ) А на какой игре лучше посмотреть? ( На какой именно ты смотришь )
 

Скрытый текст
4 минуты назад, Foxhound сказал:

 

Спасибо.
Да уж... Не, для меня это пока слишком сложно.

 

 

 

Мне хотелось понять сам принцип, можно ли это сделать и насколько сложно. Такая конструкция статусов применяется нередко. В настоящий момент я пробую на серии стареньких пошаговых стратегий Panzer Campaigns, там всё просто ломается даже для меня. Если хочешь, можешь поэкспериментировать.
Официальный сайт серии:
http://www.johntillersoftware.com/PanzerCampaigns.html
Прямая ссылка на официальный сайт на скачивание полноценной демо (144МВ):
http://www.johntillersoftware.com/download/Mius43_101.msi
Ну или в "одном хорошем месте", сам знаешь где, есть вся серия.
Самодельный скрипт на структуру выделенного в данный момент юнита, подходит почти на любую игру из серии:

  Показать содержимое



[ENABLE]

aobscan(INJECT,8B 6F 10 89 44 24 1C 03 C2)
alloc(newmem,$1000)

label(code)
label(return)
label(pMan)
registersymbol(pMan)
registersymbol(INJECT)

newmem:

pMan:

 dd 0

code:
    mov ebp,[edi+10]
    mov [pMan],edi
    mov [esp+1C],eax
    jmp return

INJECT:
	jmp code
	nop
	nop

return:

[DISABLE]

INJECT:
	mov ebp,[edi+10]
	mov [esp+1C],eax

unregistersymbol(pMan)
unregistersymbol(INJECT)
dealloc(newmem)

 

По адресу pMan+10 - численность юнита, а по адресу pMan+1C - тот самый "побитовый" статус.

 

 

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

Just now, what228 said:

Ухх 5 гигов

 

Зачем 5 гигов-то, куда столько? Это ж вся серия небось. В данный момент проверяю на Kursk'43, она вроде метров 300 занимает.
А на официальной демке, что я дал ссылку, проверить не хочешь? Практически та же игра, только сценарии другие.

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

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

 

Зачем 5 гигов-то, куда столько? Это ж вся серия небось. В данный момент проверяю на Kursk'43, она вроде метров 300 занимает.
А на официальной демке, что я дал ссылку, проверить не хочешь? Практически та же игра, только сценарии другие.

Да я пока просто сижу смотрю еще Guild II . Да и уже скачал почти :D.

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

28 минуты назад, Foxhound сказал:

 

Зачем 5 гигов-то, куда столько? Это ж вся серия небось. В данный момент проверяю на Kursk'43, она вроде метров 300 занимает.
А на официальной демке, что я дал ссылку, проверить не хочешь? Практически та же игра, только сценарии другие.

Что-то я не много ( МНОГО ) не понял. Где там кол-во войск и прочее ;? Ладно я пойду спать :D Если сможешь объясни что и как там делать.

Изменено пользователем what228
Ссылка на комментарий
Поделиться на другие сайты

31 minutes ago, what228 said:

Что-то я не много ( МНОГО ) не понял. Где там кол-во войск и прочее ;? Ладно я пойду спать :D Если сможешь объясни что и как там делать.

 

Да, эти игры имеют довольно высокий порог вхождения. Если что, в меню Help есть пункт Getting Started, там основные действия расписаны в картинках, а в папке игры есть pdf мануалы.
Грузишь сценарий. На карте кликаешь по любому цветному квадратику, изображающему юнита. В отдельном поле сбоку или снизу карты появится небольшое прямоугольное окошко (или несколько, по числу юнитов в гексе), где по центру будет рисунок выбранного юнита (солдат, танк, пушка и т.д.), а слева/справа основные данные - численность, запас хода, мораль и усталость. Выбери, например, пехоту. У неё слева будет надпись "Men ZZZ (100%)". Здесь ZZZ - численность (целое, 4 байта), а проценты в скобках - сколько от максимума. Для танка или самоходки надпись будет Vehicles, для артиллерии - Guns.
Игра ломается очень легко, но если лень искать, запускаешь скрипт, что я дал. В таблицу выводишь два пункта - указатели pMan+10 и pMan+1C, 4 байта. Кликаешь по любому юниту. Первый указатель покажет численность из ZZZ. Второй - все текущие статусы юнита, включая скрытые. Теперь, к примеру, вводишь в значение статуса FFFFFFFF, тогда выбранный юнит получит все 32 статуса разом, включая несовместимые. Переключаешься на игру, снова кликаешь по уже выбранному юниту чтобы обновить картинку и любуешься результатом: в окошке юнита появятся названия нескольких статусов (все не влезут), иконка юнита сменит вид и т.д.. Вот эти статусы меня и интересуют.

  • Плюс 2
Ссылка на комментарий
Поделиться на другие сайты

5 часов назад, Foxhound сказал:

игры имеют довольно высокий порог вхождения

Foxhound, хорошо сформулировано! 

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

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

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

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

Находясь на нашем сайте, Вы автоматически соглашаетесь соблюдать наши Условия использования.