Skocz do zawartości
  • 👋 Witaj na MPCForum!

    Przeglądasz forum jako gość, co oznacza, że wiele świetnych funkcji jest jeszcze przed Tobą! 😎

    • Pełny dostęp do działów i ukrytych treści
    • Możliwość pisania i odpowiadania w tematach
    • System prywatnych wiadomości
    • Zbieranie reputacji i rozwijanie swojego profilu
    • Członkostwo w jednej z największych społeczności graczy

    👉 Dołączenie zajmie Ci mniej niż minutę – a zyskasz znacznie więcej!

    Zarejestruj się teraz

Gość

Rekomendowane odpowiedzi

Opublikowano

UWAGA! Jeśli jedynym twoim pragnieniem jest napisanie prostego bota, który będzie w kółko szukał obrazka i klikał w niego, to ten poradnik do niczego się tobie nie przyda. Poradnik jest przeznaczony dla osób już w miarę dobrze rozumiejących AutoIT oraz wykazujących chęć pisania projektów bardziej rozbudowanych, niż kilka(dziesiąt) MouseClick i Sleep.

UWAGA! Nie jestem autorem przedstawionej tutaj biblioteki. Jej autorami są trancexx, ProgAndy, monoceres i Kip, oryginalnie udostępnili ją na oficjalnym forum AutoIT, a jest ona rozprowadzana na licencji Artistic License 2.0.

UWAGA! Tutorial jest nieco przydługi.

AutoIT jest językiem proceduralnym. Co to znaczy? Istnieje wiele paradygmatów programowania. Paradygmat programowania to(bez wchodzenia w szczegóły) "styl pisania" w danym języku. Proceduralny to taki w którym kod jest dzielony na procedury(funkcje) wykonujące określone zadania. AutoIT początkowo miał być tylko prostym języczkiem do tworzenia makr oraz automatyzowania różnych czynności wykonywanych w Windowsie, a więc wybór programowania proceduralnego był dość oczywistym rozwiązaniem. Od wersji 1 do obecnej 3.3.coś.tam wiele się zmieniło, ale paradygmat został taki sam. Jednakże w AutoIT istnieją obiekty. Używa się ich rzadko, bądź są ukryte w funkcjach. Przykłady? Winhttp, oprócz tego... IE.au3. Jeśli otworzymy tą bibliotekę i będziemy wiedzieli czego szukać, to wkrótce dostrzeżemy takie fragmenty kodu:

IsObj($oResult)
$oObject.visible = $iVisible
ObjCreate("Shell.Explorer.2")

I podobne. Są to wszystko obiekty COM, czyli taki twór Microsoftu. W AutoIT mamy do dyspozycji kilka prostych funkcji i operator wyłuskania(dostania się "wewnątrz" obiektu), dzięki których możemy ich używać. Ale jest jedna rzecz: są one tworzone przez inne aplikacje/system, a nie AutoIT. My możemy tylko korzystać z gotowych.

Ale czy na pewno?

Jakiś czas temu(czyt. 5 lat) grupka 4 osób postanowiła stworzyć bibliotekę, która pozwalałaby na tworzenie, modyfikowanie i używanie własnych obiektów run-time(w trakcie działania programu). Oryginalny wątek na oficjalnym forum AutoIT wygląda tak:

http://www.autoitscript.com/forum/topic/110379-autoitobject-udf/

W każdym razie - da się. W dziwny i oficjalnie niewspierany sposób, bez wielu miłych narzędzi obecnych w innych językach. Ale przejdźmy do kolejnego tematu, czyli pytania: "Co to jest programowanie obiektowe?".

Dla tych którzy nie wiedzą, co to jest pozwolę sobie zacytować Wikipedię(z drobnymi wtrąceniami):

Programowanie obiektowe (ang. object-oriented programming) — paradygmat programowania, w którym programy definiuje się za pomocą obiektów — elementów łączących stan (czyli dane( zmienne), nazywane najczęściej polami) i zachowanie (czyli procedury(funkcje), tu: metody). Obiektowy program komputerowy wyrażony jest jako zbiór takich obiektów, komunikujących się pomiędzy sobą w celu wykonywania zadań.
Podejście to różni się od tradycyjnego programowania proceduralnego, gdzie dane i procedury nie są ze sobą bezpośrednio związane. Programowanie obiektowe ma ułatwić pisanie, konserwację i wielokrotne użycie programów lub ich fragmentów.

Przekładając to na prosty i praktyczny język: tworzymy sobie specjalną zmienną, która jest tak naprawdę skomplikowanym zestawem zmiennych oraz funkcji, która ma wykonywać określone zadania.

Klasa - specjalny typ danych, który może zawierać pola i metody
Pole - zmienna w klasie
Metoda - funkcja w klasie
Obiekt - zmienna, której typem jest klasa

Oprócz tego istnieje wieeele innych elementów, z których żaden nie jest stworzony po nic i każdy(co do jednego) da się wykorzystać. Nie opiszę ich tu jednak, gdyż przedstawię tu tylko niezbędne podstawy. Zrozum powyższy tekst i zapoznaj się z pojęciami(jeśli nie znasz ich z innych języków), a następnie idź dalej. To już koniec teorii.

Download: http://www.mediafire.com/download/0751b21pg725dbf/AutoItObject+1.2.8.2.zip
Skan: https://www.virustotal.com/pl/file/16e550ba266b289cfe77e4a2ebefa63f416e9e0a0bddab480e1b4fce48599ee1/analysis/

Zaczyna się praktyka - pobieramy i rozpakowujemy. Znajdziemy tam kilka plików i folderów, interesują nas:

  • AutoItObject.au3 - przenosimy do folderu Includes, znajduje się on tam gdzie zainstalowaliśmy AutoIT
  • AutoItObject.chm - jest to plik z dokumentacją, przenieśmy go w miejsce w którym będziemy mieć do niego łatwy dostęp
  • Examples - w tym folderze znajdują się przykłady programów napisanych z użyciem programowania obiektowego

Mamy już wszystko, czego nam potrzeba.
 
Przygotowanie

#include <AutoItObject.au3>
_AutoItObject_Startup()
_AutoItObject_Shutdown()

3 linijki kodu - pierwsza to znane wszystkim dołączenie biblioteki, druga to jej wstępne przygotowanie, a trzecie to jej wyłączenie(tak jak jest np. w GDI+).
 
Tworzenie klasy
 
O ile inne języki mają specjalne mechanizmy służące temu celowi, o tyle w Au3 nie ma takiego luksusu. Klasa będzie mieć formę... funkcji, która tworzy obiekt przy wywołaniu. Przykład:

Func Zwierze($imie = "", $kolor = 0xFFFFFF, $wzrost = 100)
	Local $this = _AutoItObject_Create()
	Return $this
EndFunc

Pusty obiekt tworzy się za pomocą _AutoItObject_Create(), następnie zwracamy gotowy - oczywiście.
 
Tworzenie pól

	_AutoItObject_AddProperty($this, "imie", $ELSCOPE_PRIVATE, $imie)
	_AutoItObject_AddProperty($this, "kolor", $ELSCOPE_PRIVATE, Hex($kolor, 6))
	_AutoItObject_AddProperty($this, "wzrost", $ELSCOPE_PRIVATE, $wzrost)

Obiekt to taki zlepek zmiennych(a klasa to wzór na tworzenie go) - w taki sposób dodajemy do niego kolejne zmienne, sklejając je w jedną kupę. Pierwszy parametr jest oczywisty, drugi to nazwa pola, czwarty to początkowa wartość tego pola. Jeśli chodzi o trzeci, to:

  • $ELSCOPE_PRIVATE powoduje że do pola można uzyskać dostęp tylko z kodu metod
  • $ELSCOPE_READONLY powoduje że do pola można uzyskać dostęp z kodu metod, a z reszty programu można je tylko odczytywać
  • $ELSCOPE_PUBLIC powoduje że do pola można uzyskać dostęp z dowolnego miejsca w kodzie

Po co ograniczać dostęp? Bo obiekt powinien udostępniać tylko to, co jest potrzebne do korzystania z niego - przykładowo gdy będziemy tworzyć jakąś grę wyścigową, to obiekt wroga powinien dać się wyświetlać, aktualizować, dawać odczytywać prędkość itd.. Natomiast pokazywanie wszystkim swoich wektorów prędkości lub tekstur nie ma sensu(bo można coś łatwo zepsuć). Obiekt powinien być w pewnym sensie jak funkcja - pozwalać innym coś zrobić, aczkolwiek nie pokazywać jak to zrobić.
O metodach i używaniu obiektów później.
 
Tworzenie metod

	_AutoItObject_AddMethod($this, "Oddychaj", "Zwierze_Oddychaj", false)
	_AutoItObject_AddMethod($this, "Jedz", "Zwierze_Jedz", false)
	_AutoItObject_AddMethod($this, "Opisz", "Zwierze_Opisz", false)

Na naszym zlepku danych warto by wykonywać jakieś operacje - do tego służą metody, a dodaje się je tak jak widać powyżej. Pierwszy parametr znowu jest oczywisty, drugi to nazwa metody, trzeci to nazwa funkcji która zostanie użyta jako metoda(więcej na ten temat za chwilę). Czwarty parametr pełni podobną rolę to trzeci przy tworzeniu pól:

  • false - metoda jest dostępna w dowolnym miejscu w kodzie
  • true - metoda jest dostępna tylko w kodzie metod

Implementacja metod


Func Zwierze_Oddychaj($this)
	MsgBox(0,"Komunikat od " & $this.imie, "Oddycham hejtem...", 2)
EndFunc
Func Zwierze_Jedz($this)
	MsgBox(0,"Komunikat od " & $this.imie, "Jem RAM...", 2)
	Local $roznica = Int(Random(1,5))
	$this.wzrost += $roznica
	Local $string = "użytkowników"
	If $roznica == 1 Then
		$string = "użytkownika"
	EndIf
	MsgBox(0,"Komunikat od " & $this.imie, "Urosłem o " & $roznica & " " & $string & "!", 2)
EndFunc
Func Zwierze_Opisz($this)
	MsgBox(0,"Podsumowanie " & $this.imie, _
	"KOLOR: #" & $this.kolor & @CRLF & _
	"WZROST: " & $this.wzrost,5)
EndFunc

Kilka normalnych funkcji - za to widać jakiś parametr $this. Mianowicie podczas wywoływania funkcji:

$pupil.Jedz()

tak naprawdę nastąpi:

Zwierze_Jedz($pupil)

 - obiekt zostanie pierwszym parametrem, ja tutaj nazwałem go $this bo tak nazywa się ta rzecz w innych językach(aczkolwiek czasami możecie natrafić na nazwę $self). W przypadku większej ilości parametrów:

$jakisObiekt.JakasMetoda(1, "2", False)

argumenty będą w praktyce wyglądać tak:

JakasKlasa_JakasMetoda($jakisObiekt, 1, "2", False)

Aczkolwiek zapisy te nie są równoważne. Oczywiście nazwy funkcji będą zależeć od tego, jakie podacie w _AutoItObject_AddMethod.
 
Widać jeszcze zapis $this.imie oraz podobne - jak można się domyślić, w ten sposób dobiera się do danego pola.
 
Tworzenie obiektu

$pupil = Zwierze("MPC Forum", 0x333333, 1000000)

Widać wszystko na tacy - po prostu wywołujemy naszą funkcję i dostajemy obiekt.
 
Używanie obiektu

$pupil.Oddychaj()
$pupil.Jedz()
$pupil.Opisz()

Niszczenie obiektu
W celu zniszczenia obiektu i zwolnienia zajmowanej przez niego pamięci po prostu ustawiamy jego wartość na Null.

$pupil = NULL

Podsumowanie podstaw
Wystarczy połączyć kod w całość i widzimy że wszystko działa.

  • 1 rok później...
Opublikowano

Witam, i dziękuję za fajowy tutek. lecz trapi mnie pytanko :

Jak się dostać  i korzystać z obiektów w jakiejś grze np. metin2 , znając ich nazwy ? (metin2 posiada obiekty  napisane w języku python)

Opublikowano

Stwórz sobie udf z potrzebnymi funkcjami i obsługą pythona pewnie będziesz musiał napisać sobie to sam od zera. 

Mózg to nie mydło; nie ubędzie Ci go, gdy go użyjesz.

Opublikowano
Stwórz sobie udf z potrzebnymi funkcjami i obsługą pythona pewnie będziesz musiał napisać sobie to sam od zera. 

Witam, jesteś tego pewien?.Zapodaj może jakiś przykład czy link, niech inni też korzystają ;).

Opublikowano

Nie interesuje mnie ta gra więc to problem autora skryptu stworzyć jej obsługę na postawie informacji o grze jakie posiada a nie mój. Ma dane, dokumentacje i potrzebne pliki do zaczęcia pracy. 

Nie wiem jak ty to sobie wyobrażałeś że ja sobie z dupy wezmę dane o obiektach o których mówisz, a nie mam o nich  kompletnie pojęcia i nagle zrobię ci przykład do obsługi gry której nie posiadam i nie zamierzam nawet pomagać w tworzeniu bo po co.  

 

Jak napisałem da się skorzystać jak sobie napiszesz obsługę i połączenie z pythonem, ktoś to kiedyś opisywał na forum dla Metina, a czy coś pisał więcej czy publikował na ten temat nie wiem, poszukaj sobie. 

Mózg to nie mydło; nie ubędzie Ci go, gdy go użyjesz.

Opublikowano

Witam, i dziękuję za fajowy tutek. lecz trapi mnie pytanko :

Jak się dostać  i korzystać z obiektów w jakiejś grze np. metin2 , znając ich nazwy ? (metin2 posiada obiekty  napisane w języku python)

 Cały ten tutorial opisuje funkcje do obsługi obiektów COM, a nie Pythonowych(a tamte oczywiście działają inaczej). Nic z tego co tutaj jest do czegoś takiego nie użyjesz.

Opublikowano

Bezpośrednio nie zadziała, dlatego należy w jakiś sposób połączyć obsługę. 

 

Kiedyś usiłowałem podobne rzeczy robić nie do metina ale to wymaga znajomości z obydwu stron obsługi. Prościej napisać obsługę obiektów pythona w grze i potem nimi sterować obiektowo 

Mózg to nie mydło; nie ubędzie Ci go, gdy go użyjesz.

Opublikowano

Tak w ogóle to juz myślałem że złapałem Boga za nogi a tu lipa :(( .Znowu muszę szukać bo moja wiedza jest za mała, ale i tak dziękuję Wam za poświęcenie mi czasu.

Opublikowano

Moja też ograniczona, od 2-3 lat nic nie piszę prawie poza poprawianiem własnych kodów do botów.  

 

Poszukaj coś o PyWin, coś na wzór COM-serwera można było używać w AutoIt , chyba tylko w betach dostępne.  

Mózg to nie mydło; nie ubędzie Ci go, gdy go użyjesz.

Opublikowano

@metinplayer

Oczywiście że możesz wykorzystać do tego obiekty które gdzieś tam siedzą w metinie, jednak jeśli nie masz kodu gry to możesz się tylko domyślać za co odpowiedzialne jest dane pole. Nie wiem jak w autoit, jednak w c++ spokojnie możesz ustawić wskaźnik na dany obiekt, a następnie czytać z niego dane nieco bardziej przejrzyście niż dodając kolejne offsety, jednak należy pamiętać, że ułożenie danych elementów w strukturze jest takie, jak zaplanowali sobie twórcy, dlatego czasem trudno domyślić się który element jest za co odpowiedzialny, nie musisz jednak znać przeznaczenia wszystkich pól, wystarczą tylko te, które cię interesują. Przykładowo masz takie coś

struct Player
{
    char paddle[0x4]; // 4 bajty których przeznaczenia nie znasz
    int hp; // 4 bajty których przeznaczenie znasz, jest to hp
    int mp; // kolejne 4 bajty których przeznaczenie znasz.
};

Teraz wystarczy, że ustawisz wskaźnik danego gracza na powyższą strukturę i możesz zrobić takie coś chcą uzyskać wartość hp:

int myHp = localPlayer->hp;

Zamiast pisać:

int myHp = *(int*)(localPlayer + 0x4);

Łatwo można się pomylić gdy masz dużo offsetów.

Przydatne w szukaniu początku struktury/offsetów do danych wartości może być to, jak gra odwołuje się do danego pola, przykładowo taka linijka:

int myHp = localPlayer->mp;

Znaczy mniej więcej tyle co:

MOV EAX, DWORD PTR DS : [EDX + 0x8]

(Oczywiście rejestry losowe) W tym wypadku wskaźnik na pierwsze pole struktury jest ukryty pod EDX, a offset do wartości mp to 0x8.

Jescze dodam, że takie bezpośrednie branie wartości typu localPlayer->mp nie jest do końca dobre, i proponowałbym zrobić gettery w których oprócz zwracania wartości sprawdzałbyś, czy wskaźnik na strukturę nie jest równy nullptr(proponuję jakieś makro, chodzi mi o #define), zaoszczędzi ci to nerwów i crashów.

 

Mam nadzieję, że nie popełniłem gdzieś jakichś dużych błędów.

Bot do gry NosTale:


[bOT] NosBota 1.3v

Opublikowano

To to wiem, lecz jak się odnieść do danego obiektu w pythonie z poziomu autoit nie wiem a informacji na ten temat brakuje w necie.

Umiem tworzyć obiekty w pythonie i je obsługiwać, tam jest to bardzo proste, natomiast z poziomu autoit ani je obsługiwać ani tworzyć nie umiem, a chciałbym właśnie to zrobić. Jakąś nadzieje daje PyWin lub autoitX, lecz na dzień dzisiejszy muszę to dopiero ogarniać.

Myślę że jest łatwiej ogarniać te obiekty z poziomu c++ i dla tego jest mało info jak to robić z poziomu autoit.Ja należę do ludzi którzy przygodę z programowaniem zaczęli od nauki autoit i teraz widzę że czas zacząć się uczyc c++ , a nie chciał bym tego ponieważ autoit jest bardzo łatwy i ma spore możliwości (wierzę w autoit i tyle ;)). Myślę że błędem polskich programistów jest to że nie przykładają większej uwagi do nauki innych Polaków zaczynających przygodę z programowaniem.Wystarczy porównać fora o autoit polskie i angielskie.

Co tu zresztą duzo pisać na ten temat jak Polak mający 10 lat jest od startu na przegranej pozycji.

Podam przyklad:

Od czego zaczyna Polak wiek 10 lat chcący programować ?.Odp. Od nauki jezyka angielskiego ponieważ niemal że wszystkie języki są po angielsku.

Od czego zaczyna Anglik wiek 10 lat chcący programować ?.Odp. od nauki programowania poniewaz jezyk angielski juz ma opanowany.

Na tych przykladach widać juz przepaść.Na pytanie dlaczego informacje na polskich forach są skąpe?.Polak programista za bardzo ceni swoją wiedzę aby się dzielić nią z innymi bo po prostu poświęcił zbyt duzo czasu aby się tego nauczyć, a i tez względy zarobkowe.

Tak wiec wyłania się obraz polskiej sceny programistycznej dostępnej tylko dla wąskiego grona osób typu a ja wiem ale nie powiem - domyśl sie - szukaj jak ja ;).Ten stan trwa juz badzo długo i końca nie widać i mamy to co mamy czyli dół.

Dziekuję za przynajmniej odrobinę poświecenia czasu na moje bazgroły oraz za pomoc ;).

Zarchiwizowany

Ten temat przebywa obecnie w archiwum. Dodawanie nowych odpowiedzi zostało zablokowane.

×
×
  • Dodaj nową pozycję...