,

Хак на память Warcraft3

» опубликован
» Способ реализации: vJass
» Тип: Наработка
» Версия Warcraft: 1.26 и ниже
Собственно тот знаменитый хак на память который нам радостно предоставил DracoL1ch, который позволяет нам больше не морочится с системами отлова урона, или вовсе узнать координаты курсора без стороннего по.
Для сохранения требуется: экспериментальная версия pjass.exe
Причём не все подходят, меньше всего проблем было с этой версией
В хаке присутствует только 1 пример на изменение белой атаки у героя, остальные готовые функции можно найти на:
Хайве
Гитхабе
Просто копируем саму функцию, все остальное для её работы есть в наработке и сохраняем.
Так же на хайве есть инструкция по созданию собственных функций для чтения\изменения данных в памяти игры.


Просмотров: 44 934



» Лучшие комментарии


ScorpioT1000 #451 - 7 месяцев назад 0
JMacTep, оно в процессе компиляции происходит, да и нет такого понятия в pure jass
quq_CCCP #452 - 7 месяцев назад 2
Типы целей:
air 00000004
aliv 01000000
alive 01000000
alli 00004000
allies 00004000
ally 00004000
ancient 80000000
bridge 00000400
dead 02000000
deco 00000200
decoration 00000200
debr 00000100
debris 00000100
enem 00010000
enemies 00010000
enemy 00010000
grou 00000002
ground 00000002
frie 00006000
friend 00006000
hero 00400000
invu 00200000
invulnerable 00200000
item 00000020
mech 08000000
mechanical 08000000
neut 00008000
neutral 00008000
none 00000001
nonancient 40000000
nonh 00800000
nonhero 00800000
nonsapper 10000000
nots 0001E000
notself 0001E000
orga 04000000
organic 04000000
play 00002000
player 00002000
sapper 20000000
self 00001000
stru 00000008
structure 00000008
tote 00000010
totem 00000010
tree 00000040
vuln 00100000
vulnerable 00100000
wall 00000080
ClotPh #453 - 7 месяцев назад 0
Хм, а если декор сделать юнитом прямо в процессе игры или наоборот? Фатал будет? Декор можно будет выделить, дать ему скорость перемещения, атаку? А можно исходный декор сделать и декором и юнитом?
quq_CCCP #454 - 7 месяцев назад 4
ClotPh, добрый фей драколич щяс подарил еще пару интересных функций, чуть чуть попозже опубликую...
ScorpioT1000 #455 - 7 месяцев назад 0
ClotPh, там другие наборы данных, да и юниты числятся в разнообразных сортировках для поиска в радиусе
DracoL1ch #456 - 6 месяцев назад 1
ты не можешь превращать один тип в другой, это очевидно, по множеству причин
ScorpioT1000 #457 - 6 месяцев назад (отредактировано ) 2
DracoL1ch, можно удалить декор и создать юнита, а мемхак поможет оставить тот же хендл айди, вот это здравая идея. Только это надо делать атомарно
DracoL1ch #458 - 6 месяцев назад 2
но зачеееееем вы пытаетесь лечить насморк клизмой?
Steal nerves #459 - 6 месяцев назад (отредактировано ) 0
лучше бы обновлялись данные версиями мем хака
quq_CCCP, а где вы публикуете? пробовал найти свежую версию, так час искал. Пока в теме не нашел (как потом оказалась, что свежее есть еще в вашей системе урона).
Steal nerves #460 - 6 месяцев назад (отредактировано ) 0
Кстати, у меня из-за обновления виндовс 10, теперь не всегда охотно работает JNGP (хотя добавил в исключения). Даже некоторые купленные игры не работают. такие уж придурки маркрософт.
Приходится заранее выключать антивирус виндовса, чтоб включить.
а в программе Word теперь не могу читать в спец-режиме. нафига 5000 офис покупал
ClotPh #461 - 6 месяцев назад 0
//////
был вопрос от 16гб, можно ли сделать через мемхак ренджа милишником без морфа?
что ответили - не помню, в общем, интересен ответ
а в связи с этим xgm.guru/p/wc3/208254#lastpost интересно, можно ли через мемхак сделать негероя героем и наоборот прямо в процессе игры
DracoL1ch #462 - 6 месяцев назад 0
можешь ренж редактировать, морф - это морф, у него свои особенности, в т.ч. смена ида
нет, герой - это огромный блок классов, на лету их не создать
ClotPh #463 - 6 месяцев назад 0
DracoL1ch, т. е. мной понято так: параметры ренджа менять можно (ну это и так сомнений не было), ренджа милишником и негероя героем теоретически реально, но нужно многое менять сразу и учесть (и, ятп, таких функций нет еще и не протестированы побочные эффекты).
DracoL1ch #464 - 6 месяцев назад 2
морф типа атаки простейшее, не думаю, что там есть подводные камни. Допустим, класс сплеша создается при инициализации юнита, на лету его создавать не умею сейчас, поэтому сплеша на лету никак не могу дать - только выдать изначально, а потом снимать. пока не нужен. Героем же сделать почти нереально на данном этапе, там огроменная функция создания юнита и обработки его геройских корней в т.ч. Естественно, это возможно, код-то рабочий, но практически даже не пытался.
pro100master #465 - 6 месяцев назад 0
Если работать с мемхак месте с textmacro или externalblock то не запустят карту хотя пройдет без ошибок
Diaboliko #466 - 6 месяцев назад 0
Есть задумка по использованию модели хелс-бара, мана-бара и еще пары оверлей-баров (щит и статусный эффект). Ничего нового в этой идее нет, но реализовать ее хотелось бы не через даммиков (двигать 4 даммика с малым периодом для юнита - само по себе не слабая нагрузка), а через аттач-эффектов. Проблема встает в проигрывании анимаций эффекта по индексу.
Обоснованная критика/помощь?
DracoL1ch #467 - 6 месяцев назад 0
ну если найдете, как задавать анимацию эффекту, то говно вопрос. Пока что близзы сами не нашли такой функции
Diaboliko #468 - 6 месяцев назад (отредактировано ) 0
Ах, печаль-беда. Эффекты проигрывают анимацию смерти при уничтожении, так что, я надеялся, что такая возможность, все-таки, есть.
quq_CCCP #469 - 6 месяцев назад 0
DracoL1ch, погодь лич, вспомни стадо носорогов у бистмастера, как они там слепили? Мб можно как то залезьть в хендл эффекта или снаряда и управлять анимацией?
Diaboliko #470 - 5 месяцев назад 1
Господа, так что там с прикручиванием счетчика зарядов к любым абилкам? :) Мне ни коим образом не горит, но очень интересно пощупать.
DracoL1ch #471 - 5 месяцев назад 4
ну вот код, внедрение должно быть довольно понятным
я понятия не имею, какие у вас там настройки, но выделенная через malloc память должна быть больше, чем 55000 :)
Diaboliko #472 - 5 месяцев назад (отредактировано ) 1
Танцы с бубном не эффективны. Методом тыка не могу осуществить приготовления т.к. понятия не имею что происходит при вызовах тех или иных функций :) Нужен код подготовки к вызову InitCustomChargesData()
Моих сил ванги хватает лишь чтобы предсказать что нужно как-то использовать маллок и CallFastCallWith1Args
DracoL1ch #473 - 5 месяцев назад (отредактировано ) 3
там, где AllocateExecutableMemory вызывается, указан объем выделяемой памяти
поставь туда 70000 и вперед, остальное набирай дальше
пример использования
((код jass
call VisualChargesSystem_SetCharges(u,'A064',3)//записывает юниту в абилку колво зарядов
call VisualChargesSystem_Init(u,'A064')//активирует отображение зарядов на этом id на этом юните
call VisualChargesSystem_InitHookOnAbility(u,'A064')//включает хук на эту абилку (основу) для отображения
))
В коде _Init() рядом лежит отключатель, если отображать не нужн
InitCustomChargesData вызываешь где-то в мейн, не принципиально, она хук основной рисует
quq_CCCP #474 - 5 месяцев назад 1
DracoL1ch, работает так же на сов с ракетами или на все абилки?
DracoL1ch #475 - 5 месяцев назад 3
это универсально для любой абилки
ClotPh #476 - 5 месяцев назад 0
DracoL1ch, куда именно здесь поставить 70 000, в local integer retval?
function AllocateExecutableMemory takes integer size returns integer
	local integer retval = 0
	if pVirtualAlloc != 0 then 
		if pReservedExecutableMemory2 == 0 then 
			if pMergeUnitsOffset == 0 then
				set pMergeUnitsOffset = CreateJassNativeHook(pMergeUnits, Memory[pVirtualAlloc] )
			else
				call WriteRealMemory(pMergeUnitsOffset,Memory[pVirtualAlloc])
			endif
			set retval = B2I(MergeUnits(0,size+4,0x3000,0x40))
			call WriteRealMemory(pMergeUnitsOffset,pMergeUnits)
			return retval
		else 
			set retval = CallStdcallWith4Args(Memory[pVirtualAlloc],0,size+4,0x3000,0x40)
		endif 
		
	endif
	
	if retval == 0 then 
		return 0
	endif
	
	return (retval + 4) / 4 * 4
endfunction
DracoL1ch #477 - 5 месяцев назад 2
ты в неё передаешь size, убедись что он достаточен (60к)
Steal nerves #478 - 5 месяцев назад 0
DracoL1ch, не понимаю. у меня что-то не работает =( вылетает ^_^
вот карта
прикреплены файлы
DracoL1ch #479 - 5 месяцев назад (отредактировано ) 6
потому что у тебя вообще нет инита функций мемхака
которые включают в себя AllocateExecutableMemory
set pCallFastCallWith1Args=AllocateExecutableMemory(64000)
	
	set Memory[pCallFastCallWith1Args/4]=0

	set pCallFastCallWith2Args=pCallFastCallWith1Args + 1000
	set Memory[pCallFastCallWith2Args/4]=0
вот это всё
Steal nerves #480 - 5 месяцев назад 2
DracoL1ch, короче понял
так понимаю, на пассивках это работать не будет. критует.
вот сделал систему когда прибавляет при убийстве blademaster-ом
прикреплены файлы
ClotPh #481 - 5 месяцев назад 0
Steal nerves, в принципе можно псевдопассивку с кд 0 сделать на основе виндволка... а во всех триггерах активки с кд < 1 не учитывать, у меня они уже практически нигде такие не учитываются
DracoL1ch #482 - 5 месяцев назад 4
Эм, ну да, на пассивках не тестил, ибо в этом плане сломанные Afla проще
Там просто нет этой функции на пассивках вообще, ясно откуда вылет.
» фикс под пассивки
по крайней мере часть пассивок
function InitCustomChargesData takes nothing returns nothing
	set ChargesIndicatorDataHandle=GetHandleId(ChargesIndicatorData)
	set Memory[pCustomChargesDisplayer/4 + 0] = 0x0824448B
	set Memory[pCustomChargesDisplayer/4 + 1] = 0x7C8B5756
	set Memory[pCustomChargesDisplayer/4 + 2] = 0x57500C24
	set Memory[pCustomChargesDisplayer/4 + 3] = 0x8DE8F18B
	set Memory[pCustomChargesDisplayer/4 + 4] = 0x85000372
	call WMem(pCustomChargesDisplayer+4*3 + 3,GameDLL+0x378A0 - (pCustomChargesDisplayer+4*3 + 3) - 4)
	set Memory[pCustomChargesDisplayer/4 + 5] = 0x397C75FF
	set Memory[pCustomChargesDisplayer/4 + 6] = 0x777F407E
	set Memory[pCustomChargesDisplayer/4 + 7] = 0x51605E5F
	set Memory[pCustomChargesDisplayer/4 + 8] = 0x4E8B9090
	set Memory[pCustomChargesDisplayer/4 + 9] = 0xCC40B830
	set Memory[pCustomChargesDisplayer/4 + 10] = 0xD0FF6F2D
	call WMem(pCustomChargesDisplayer+4*9 + 2,GameDLL+0x2DCC40)
	set Memory[pCustomChargesDisplayer/4 + 11] = 0x6974C085
	set Memory[pCustomChargesDisplayer/4 + 12] = 0x8B905159
	set Memory[pCustomChargesDisplayer/4 + 13] = 0x3476FFD8
	set Memory[pCustomChargesDisplayer/4 + 14] = 0x99996850
	set Memory[pCustomChargesDisplayer/4 + 15] = 0x10B89999
	call WMem(pCustomChargesDisplayer+4*14 + 2,ChargesIndicatorDataHandle)
	set Memory[pCustomChargesDisplayer/4 + 16] = 0xFF6F3CAB
	call WMem(pCustomChargesDisplayer+4*15 + 3,GameDLL+0x3CAB10)
	set Memory[pCustomChargesDisplayer/4 + 17] = 0x0CC483D0
	set Memory[pCustomChargesDisplayer/4 + 18] = 0x4C74C085
	set Memory[pCustomChargesDisplayer/4 + 19] = 0x90905990
	set Memory[pCustomChargesDisplayer/4 + 20] = 0x828B168B
	set Memory[pCustomChargesDisplayer/4 + 21] = 0x00000308
	set Memory[pCustomChargesDisplayer/4 + 22] = 0x53347E8B
	set Memory[pCustomChargesDisplayer/4 + 23] = 0xD0FFCE8B
	set Memory[pCustomChargesDisplayer/4 + 24] = 0x533476FF
	set Memory[pCustomChargesDisplayer/4 + 25] = 0x99999968
	set Memory[pCustomChargesDisplayer/4 + 26] = 0xB8D88B99
	call WMem(pCustomChargesDisplayer+4*25 + 1,ChargesIndicatorDataHandle)
	set Memory[pCustomChargesDisplayer/4 + 27] = 0x6F3CAA90
	call WMem(pCustomChargesDisplayer+4*27 + 0,GameDLL+0x3CAA90)
	set Memory[pCustomChargesDisplayer/4 + 28] = 0xC483D0FF
	set Memory[pCustomChargesDisplayer/4 + 29] = 0x51C88B0C
	set Memory[pCustomChargesDisplayer/4 + 30] = 0xCF8BD38B
	set Memory[pCustomChargesDisplayer/4 + 31] = 0x332E10B8
	set Memory[pCustomChargesDisplayer/4 + 32] = 0x6AD0FF6F
	call WMem(pCustomChargesDisplayer+4*31 + 1,GameDLL+0x332E10)
	set Memory[pCustomChargesDisplayer/4 + 33] = 0x8BD38B01
	set Memory[pCustomChargesDisplayer/4 + 34] = 0x2E40B8CF
	set Memory[pCustomChargesDisplayer/4 + 35] = 0xD0FF6F33
	call WMem(pCustomChargesDisplayer+4*34 + 2,GameDLL+0x332E40)
	set Memory[pCustomChargesDisplayer/4 + 36] = 0x5F07EB5B
	set Memory[pCustomChargesDisplayer/4 + 37] = 0x0008C25E
	set Memory[pCustomChargesDisplayer/4 + 38] = 0xC2615990
	set Memory[pCustomChargesDisplayer/4 + 39] = 0x90900008
//	call echo(Int2Hex(pCustomChargesDisplayer))

set Memory[pCustomChargesDisplayer/4 + 40] = 0x0824448B
	set Memory[pCustomChargesDisplayer/4 + 41] = 0x7C8B5756
	set Memory[pCustomChargesDisplayer/4 + 42] = 0x57500C24
	set Memory[pCustomChargesDisplayer/4 + 43] = 0x8390F18B
	set Memory[pCustomChargesDisplayer/4 + 44] = 0x859008C4
	set Memory[pCustomChargesDisplayer/4 + 45] = 0x397C75FF
	set Memory[pCustomChargesDisplayer/4 + 46] = 0x777F407E
	set Memory[pCustomChargesDisplayer/4 + 47] = 0x51605E5F
	set Memory[pCustomChargesDisplayer/4 + 48] = 0x4E8B9090
	set Memory[pCustomChargesDisplayer/4 + 49] = 0xCC40B830
	set Memory[pCustomChargesDisplayer/4 + 50] = 0xD0FF6F2D
	call WMem(pCustomChargesDisplayer+4*49 + 2,GameDLL+0x2DCC40)
	set Memory[pCustomChargesDisplayer/4 + 51] = 0x6974C085
	set Memory[pCustomChargesDisplayer/4 + 52] = 0x8B905159
	set Memory[pCustomChargesDisplayer/4 + 53] = 0x3476FFD8
	set Memory[pCustomChargesDisplayer/4 + 54] = 0x99996850
	set Memory[pCustomChargesDisplayer/4 + 55] = 0x10B89999
	call WMem(pCustomChargesDisplayer+4*54 + 2,ChargesIndicatorDataHandle)
	set Memory[pCustomChargesDisplayer/4 + 56] = 0xFF6F3CAB
	call WMem(pCustomChargesDisplayer+4*55 + 3,GameDLL+0x3CAB10)
	set Memory[pCustomChargesDisplayer/4 + 57] = 0x0CC483D0
	set Memory[pCustomChargesDisplayer/4 + 58] = 0x4C74C085
	set Memory[pCustomChargesDisplayer/4 + 59] = 0x90905990
	set Memory[pCustomChargesDisplayer/4 + 60] = 0x828B168B
	set Memory[pCustomChargesDisplayer/4 + 61] = 0x00000308
	set Memory[pCustomChargesDisplayer/4 + 62] = 0x53347E8B
	set Memory[pCustomChargesDisplayer/4 + 63] = 0xD0FFCE8B
	set Memory[pCustomChargesDisplayer/4 + 64] = 0x533476FF
	set Memory[pCustomChargesDisplayer/4 + 65] = 0x99999968
	set Memory[pCustomChargesDisplayer/4 + 66] = 0xB8D88B99
	call WMem(pCustomChargesDisplayer+4*65 + 1,ChargesIndicatorDataHandle)
	set Memory[pCustomChargesDisplayer/4 + 67] = 0x6F3CAA90
	call WMem(pCustomChargesDisplayer+4*67 + 0,GameDLL+0x3CAA90)
	set Memory[pCustomChargesDisplayer/4 + 68] = 0xC483D0FF
	set Memory[pCustomChargesDisplayer/4 + 69] = 0x51C88B0C
	set Memory[pCustomChargesDisplayer/4 + 70] = 0xCF8BD38B
	set Memory[pCustomChargesDisplayer/4 + 71] = 0x332E10B8
	set Memory[pCustomChargesDisplayer/4 + 72] = 0x6AD0FF6F
	call WMem(pCustomChargesDisplayer+4*71 + 1,GameDLL+0x332E10)
	set Memory[pCustomChargesDisplayer/4 + 73] = 0x8BD38B01
	set Memory[pCustomChargesDisplayer/4 + 74] = 0x2E40B8CF
	set Memory[pCustomChargesDisplayer/4 + 75] = 0xD0FF6F33
	call WMem(pCustomChargesDisplayer+4*74 + 2,GameDLL+0x332E40)
	set Memory[pCustomChargesDisplayer/4 + 76] = 0x5F07EB5B
	set Memory[pCustomChargesDisplayer/4 + 77] = 0x0008C25E
	set Memory[pCustomChargesDisplayer/4 + 78] = 0xC2615990
	set Memory[pCustomChargesDisplayer/4 + 79] = 0x90900008
endfunction

function VisualChargesSystem_InitHookOnAbility takes unit u, integer id returns nothing
	local integer a
	local integer b
	set a=GetUnitAbility(u,id)
	if a!=0 then
		if RMem(RMem(a)+0x1C4)==GameDLL+0x378A0 then
			call SaveUnlockWriteMemory(RMem(a)+0x1C4,pCustomChargesDisplayer,true,true)
		elseif RMem(RMem(a)+0x1C4)==GameDLL+0x20AF0 then
			call SaveUnlockWriteMemory(RMem(a)+0x1C4,pCustomChargesDisplayer+40*4,true,true)
		else
			call BJDebugMsg("Unknown base ability, hook is not possible")
		endif
	endif
endfunction
на выжег маны и уклонение работает, в случае чего плюнет ошибку и ниче не сделает.
ScopteRectuS #483 - 2 недели назад 0
там, где AllocateExecutableMemory вызывается, указан объем выделяемой памяти
поставь туда 70000 и вперед, остальное набирай дальше
пример использования
А можно меньше 70000 сделать, если мне столько не нужно.
Внизу set pCustomChargesDisplayer = pCallFastCallWith1Args + 35000.
        set pCallFastCallWith1Args                      = AllocateExecutableMemory( 40000 )
        set pCallFastCallWith2Args                      = pCallFastCallWith1Args + 1000
        set pCallFastCallWith3Args                      = pCallFastCallWith1Args + 2000
        set pCallFastCallWith4Args                      = pCallFastCallWith1Args + 3000
        set pFUCKINGCallWith4Args                       = pCallFastCallWith1Args + 4000
        set pCallFastCallWith5Args                      = pCallFastCallWith1Args + 5000
        set pCallFastCallWith6Args                      = pCallFastCallWith1Args + 6000
        set pCallFastCallWith7Args                      = pCallFastCallWith1Args + 7000
        set pCallFastCallWith8Args                      = pCallFastCallWith1Args + 8000        
        set pCallStdcallWith1Args                       = pCallFastCallWith1Args + 9000
        set pCallStdcallWith2Args                       = pCallFastCallWith1Args + 10000
        set pCallStdcallWith3Args                       = pCallFastCallWith1Args + 11000
        set pCallStdcallWith4Args                       = pCallFastCallWith1Args + 12000
        set pCallStdcallWith5Args                       = pCallFastCallWith1Args + 13000
        set pCallStdcallWith6Args                       = pCallFastCallWith1Args + 14000        
        set pCallCdeclWith1Args                         = pCallFastCallWith1Args + 15000
        set pCallCdeclWith2Args                         = pCallFastCallWith1Args + 16000
        set pCallCdeclWith3Args                         = pCallFastCallWith1Args + 17000
        set pCallCdeclWith4Args                         = pCallFastCallWith1Args + 18000
        set pCallCdeclWith5Args                         = pCallFastCallWith1Args + 19000
        set pCallCdeclWith6Args                         = pCallFastCallWith1Args + 20000
    //  set pReadStack                                  = pCallFastCallWith1Args + 21000
        set pBitwiseOR_ExecutableMemory                 = pCallFastCallWith1Args + 22000
        set pBitwiseXOR_ExecutableMemory                = pCallFastCallWith1Args + 23000
        set pBitwiseAND_ExecutableMemory                = pCallFastCallWith1Args + 24000
        set pReservedMemoryForMissileHandler            = pCallFastCallWith1Args + 25000
    //  set pReservedMemoryForDamageHandler             = pCallFastCallWith1Args + 26000
        set pGetAbilityOrderID                          = pCallFastCallWith1Args + 27000
    //  set pReservedMemoryForPacketHandler             = pCallFastCallWith1Args + 28000
    //  set pReservedMemoryForPacketHandler2            = pCallFastCallWith1Args + 29000
        set pCallFastCallWith11Args                     = pCallFastCallWith1Args + 30000
        set pCallFastCallWith12Args                     = pCallFastCallWith1Args + 31000
    //  set pReservedMemoryForBerserkHook               = pCallFastCallWith1Args + 32000
    //  set pReservedMemoryForAttackPrepareHandler      = pCallFastCallWith1Args + 34000
        set pCustomChargesDisplayer                     = pCallFastCallWith1Args + 35000
ClotPh #484 - 2 недели назад 0
конечно понимаю что уже в который раз спрашиваю, но все-таки еще раз прошу уточнить насчет функции получения золотостоимости предмета
дико нужна для разных систем
ту замуту упоротую с созданием магазинов и продажи в них предметов и сверкой стоимости золота мне НЕ надо, потому что, во-первых, это правой рукой чесать левое ухо через голову, во-вторых, мне там в коде видятся утечки, т. е. еще и утечки править, а в итоге все равно не оптимальный вариант получается
бд это понятно через прочность или еще что у шмота или просто само по себе через переменные, но бд - тоже косой выход
так что очень прошу еще раз что там по функции просто подсчитать голдкост
типа function GetItemGoldCost takes item returns integer
чтобы принимала предмет и возвращала его цену
в этот раз сразу себе в "основной справочник" всю инфу скину, если получу точную информацию, в идеале готовую функцию, а не "наводку"
вот вроде была где-то полезная "наводка" на адрес, что ли, мб у меня получилось бы самостоятельно составить функцию, но ща я и этой "наводки" не могу отыскать, только вот тот изврат с магазинами продажей и сверкой золота а его не хочу, хочу мемхаком голдкост предмета получать
заранее благодарю
JMCode #485 - 2 недели назад 0
ClotPh, а зачем мемхак если можете узнать сколько потратил например при продаже узнаем текуший монет и записиваем или за убиства записиваем все у игрока, при покупке сверяем данные и текуший монету и узнаете сколько стоит даже бд не надо
ClotPh #486 - 2 недели назад 0
JMCode, это все равно намного менее удобно + при продаже нужно еще "расходы" всякие учитывать