>===>>=====> >=>>=> >=>
>=> >=>>=> >=> >=> >> >=>
>=> >> >=> >=> >==> >> >==> >=> >=> >=>>==>
>=> >=> >=> >=> >=> >=> >> >=> >=>
>=> >=> >=> >=> >=> >=> >> >=> >=>
>=> >=> >=> >=> >=> >=> >=> >=> >=> >=>
>=> >======> >=>>=> >==> >==> >=> >=> >=>
>=>
______ _
( / _/_ o //
/ , , / __ _ , __, //
_/ (_/_(__(_)/ (_(_(_/(_(/_
Autor: Piotr Puczyński; Aktualizacja:
19.11.2006
Witam wszystkich. Jest to mój drugi tekst o pisaniu skryptów w T2 Script. Poprzedni się trochę zdeaktualizował i dlatego powstał ten tutorial.
Do czego może przydać Ci się ten tekst? T2 Script to język dla programu Taboret2 lub innego (jeśli ma obsługę T2 Script). Będe starał się pokazać podstawy teoretyczne i praktyczne pisania skryptów ze zrozumieniem i z odrobiną zabawy. Pisanie skryptów jest dobrą zabawą, łamigłówką - analogicznie tak jak składanie klocków w całość, tu również można składać poszczególne elementy tak, by uzyskać niepowtarzalny rezultat.
Każdy skrypt jest programem i prawa autorskie do skryptu należą do jego autora.
Jeśli zdecydowałeś/aś się czytać dalej, poznaj wymagania jakie powinieneś/powinnaś spełnić. Nie są one wygórowane.
Do nauki pisania skryptów w języku T2 Script wymagane są: program Taboret2, trochę czasu, parę kubków kawy też się przyda :-), użyteczne mogą okazać się również kartka papieru i ołówek.
Jeśli znajdziesz jakiś błąd w tekście, chcesz zadać jakieś pytanie lub chcesz mnie po prostu powiadomić, że czytałeś/aś mój tekst (co jest dla mnie o tyle ważne, że nie wiem, czy ktoś to czyta i czy mam aktualizować tekst, czy nie) - napisz do mnie na adres e-mail:
_ _
(_) ____ | |
_ __ _ ___ _ __ _ __ ___ __ _ / __ \__ ___ __ _ __ | |
| '_ \| |/ _ \ '__| '__/ _ \/ _` |/ / _` \ \ /\ / / '_ \ | '_ \| |
| |_) | | __/ | | | | __/ (_| | | (_| |\ V V /| |_) || |_) | |
| .__/|_|\___|_| |_| \___|\__, |\ \__,_| \_/\_/ | .__(_) .__/|_|
| | | | \____/ | | | |
|_| |_| |_| |_|
Tekst ten jest publikowany na licencji Creative Commons, dozwolone jest jego publikowanie, kopiowanie i wykorzystywanie go do swoich celów.
Idź do spisu treści
Komendy
Na początku była komenda...
Odnosząc się do parafrazy cytatu - komenda jest to słowo. Słowo, które identyfikuje jej funkcjonalność. Tłumacząc to na normalny, prosty język można powiedzieć, że znając komendę możemy spowodować, że program wywoła jakąś czynność. Np. zamiast klikać na status "zajęty" w programie Taboret2 moglibyśmy użyć komendy BUSY (ang. zajęty). Po wprowadzeniu komendy program sam "kliknie" na status, co da efekt taki, że nasz stan zmieni się na "zajęty".
Aby wprowadzić komendę do programu należy wpisać ją w dowolnym oknie rozmowy lub oknie Serwer w tym samym miejscu, którego używamy do rozmowy.
Aby program rozróżnił, że chodzi nam o komendę BUSY a nie o słowo "BUSY", musimy jako pierwszy znak wpisać "/" - jest to przełącznik komendy.
Przykłady:
Tu wypowiemy tekst "Busy":
Ten przykład wydaje się prosty? Polecam każde pojawiające się kody (odpowiednio oznaczone w żółtych prostokątach), jak te dwa powyżej od razu wpisywać u siebie i testować w swoim programie Taboret2.
Żeby nie było tak prosto podam parę wyjątków od tej reguły ;-). Przełącznik przed komendą stosujemy tylko dla pierwszej komendy (może się zdażyć, że będziemy używać paru komend w jednej linii) i tylko w oknach programu (później pojawią się skrypty w plikach - tam nie ma przełącznika nawet przy pierwszej komendzie).
Przykłady:
Parę komend w jednej linii wprowadzanych w okno rozmowy (tak się powinno zapisywać):
Niektóre komendy wyświetlają potwierdzenia, np. informacje o tym, że jakaś operacja została wykonana pomyślnie, skrypt został załadowany itp. Możemy wyłączyć te powiadomienia umieszczając znak małpy "@" przed nazwą dowolnej komendy, wtedy komenda działa cicho w tle:
Oprócz poznanej już komendy BUSY istnieje pareset innych komend. Ich spis znajduje się w pliku readme.txt dołączonym do programu Taboret2. Do szybkiego podglądu tego pliku istnieje również komenda ;-).
Jeśli w moim tekscie pojawi się jakaś nowa komenda, której nie znasz, wtedy użyj README i wyszukaj w tym pliku nieznaną Ci komendę i jej opis oraz parametry do komendy.
Nazwy komend nie są czułe na wielkość liter, np. pisząc "ReadMe" i "README" wywołamy tą samą komendę.
Parametry są to słowa występujące za pierwszą komendą. Parametrem może być nazwa innej komendy, zmienna (zmienne zostaną później omówione), tekst, cyfry itp.
Komenda BUSY nie ma parametrów, niektóre komendy mają parametry niewymagane (które możesz ale nie musisz wpisać) a do niektórych komend parametr jest wymagany. AWAY ma jeden parametr niewymagany. Działa tak samo jak BUSY z tym, że jej działanie zmienia stan "zaraz wracam" (a nie "zajęty" jak w przypadku BUSY). W AWAY możemy podać w parametrze przyczynę nieobecności jako ciąg znaków czy słów:
Jeśli komenda ma więcej niż jeden parametr, są one rozpoznawane jako słowa oddzielone spacjami. W praktyce oznacza to, że wszystkie parametry poza ostatnim (MaxParams-1) muszą być jednym wyrazem:
Ktoś dociekliwy mógłby zapytać co będzie, jeśli w jednej linii będziemy musieli wprowadzić wiele komend z różną ilością parametrów każda... Aż strach pomyśleć... zamieszanie.
Z pomocą w takiej sytuacji przychodzą komendy z rodziny MLC (Multi Line Command).
Są ich dwie: MLC (zwykłe) i MLCEXT (ang. extended - rozszerzone).
Budowa MLC:
Różnica polega na elemencie rozdzielającym komendy, który w zwykłym MLC jest zdefiniowany jako "||" a w MLCEXT możemy sami go ustawić na dowolny (ustalamy go w pierwszym parametrze).
Komendy w MLC są wykonywane po kolei od pierwszej do ostatniej, np. taka komenda:
MLCEXT powstało by rozwiązać problem zapętlania wielu MLC ze sobą. Mamy następujący problem:
Chcielibyśmy, aby w wyniku gdyby warunek nie był spełniony, program pokazał "o rany!" i "to fałsz!" a gdy spełniony tylko "to prawda". Błąd wynika z zastosowania dwóch MLC w jednej linii. Aby poprawić ten kod należy napisać:
Zastosowałem tutaj zagnieżdżenie MLC i MLCEXT przez co uniknęliśmy wcześniejszego błędu. Można jeszcze dodać, że komenda TEXTOUT wyświetla tekst podany w parametrze w oknie, z którego jest wywołana. Inne osoby w pokoju nie widzą co piszesz komendą TEXTOUT u siebie.
Składnia MLC jest troche męcząca. Napiszemy teraz komendę, która wyświetli nam okienko z tekstem w Taboret2.
A gdy pragnienie wolności owładnie tobą, zrzucisz jarzmo z twej szyi. Rdz 27, 40
Kontynuując teoretyczne rozważania nad komendami można zauważyć niedogodność ograniczenia wykonania naraz zawartości "skryptu" do jednej linii. Do tej pory takie skrypty pisaliśmy, ale w T2 Script można tworzyć również skrypty wieloliniowe. Dzięki temu jesteśmy w stanie napisać dowolny skrypt bez ograniczeń.
Skrypt wieloliniowy zapisywany jest w pliku o rozszerzeniu .tsc (Taboret SCript). Są dwa podstawowe typy skryptów w pliku:
Nie można łączyć razem w jednym pliku .tsc starej i nowej metody. Ale narazie nie przejmuj się tym, gdyż ucząc się wykorzystamy Centrum T2 i nie będziemy musieli zapisywać nic do plików (Centrum T2 umożliwia ładowanie skryptu bez zapisu do pliku) :-).
Centrum T2 to po prostu tekstowy edytor skryptów z możliwością ich bezpośredniego uruchamiania i obejrzenia efektu.
Aby otworzyć Centrum T2 naciśnij Ctrl+E w Taboret2. Zobaczysz zakładkę "Script Editor/Debugger". Rozglądnij się, to będzie Twoje środowisko pracy. Możesz popatrzeć na pozostałe dwie zakładki. Dodatkowo Centrum T2 oferuje podgląd zmiennych i ustawionych timerów. Te tematy będą omawiane w kolejnych rozdziałach.
W zakładce "Script Editor/Debugger" interesować nas będą narazie dwa przyciski: "Uruchom" (służy do ładowania starego typu skryptów) i "Ładuj" (służy do ładowania nowych skryptów jako funkcji). Narazie będziemy po napisaniu skryptu naciskać na "Uruchom", aby obejrzeć jak działa nasz skrypt. ;-). Można też zwrócić uwagę, że pod głównym białym obszarem do pisania znajduje się mniejsze szare pole - tam będą wyświetlane ewentualne błędy jakie popełnimy pisząc skrypt jak również inne informacje. Napiszmy w białym obszarze do pisania (pamiętamy, że w skryptach nie dajemy "/" przed komendami):
Nasz skrypt został wykonany w oknie Serwer (wszystkie skrypty z plików są tam domyślnie wykonywane). Jeśli zminimalizujemy Centrum T2 i zajrzymy do okna Serwer powinniśmy zobaczyć:
Częstym błędem popełnianym przez osoby początkujące jest właśnie zapominanie o tym, że skrypty są wykonywane w oknie Serwer. Np. jeśli byśmy chcieli ze skryptu wysłać wiadomość do osoby o nazwie T2_Scripter, użyjemy do tego komendy WND służącej do przekierowywania komendy na inne okno (warunek, że mamy otwarte okno priva z osobą T2_Scripter):
Analogicznie chcąc wysłać wiadomość na kanał #Towarzyski wpiszemy (warunek, że mamy otwarte okno kanału #Towarzyski):
Aby wyczyścić pola naciśnij na przycisk "Nowy" w Centrum T2. W następnym rozdziale zaczniemy pisać bardziej rozbudowany skrypt.
Idź do spisu treści
Elementy języka T2 Script
Biedny, kto gwiazd nie widzi bez uderzenia w zęby.
Napiszemy skrypt, który w pierwszej fazie będzie pytał użytkownika czy jest kobietą czy mężczyzną, następnie pytał o preferencje kolorów ubrań, losował odcień w wybranym kolorze i wyświetlał go w oknie Serwer jako propozycje koloru spodni (dla mężczyzny) lub sukienki (dla kobiety).
Odrazu podam cały gotowy kod, a następnie będę objaśniał. Nie przejmuj się złożonością kodu. Możesz go wpisać u siebie w Centrum T2, dać na "Uruchom" i zobaczyć jak działa skrypt.
Ten skrypt jest wprowadzającym w dział o zmiennych. Większą jego część zajmuje losowanie i wyświetlanie koloru - nie musisz rozumieć tego mechanizmu, dalej pokaże prostsze przykłady ze zmiennymi.
Zmienna jest to obiekt składający się z:
Nazwy zmiennych są czułe na wielkość liter, np. nazwy "kocur" i "Kocur" to dwie różne zmienne.
Wartość zmiennej w T2 Script może przechowywać dowolny typ danych - tekstowy, liczbowy, logiczny (1 lub 0) itd. bez konieczności konwersji na dane typy. Możemy np. ustalić zmienną "kot", której wartość najpierw będzie służyć do przechowywania liczby (np. ile kot ma łap), a później przypiszemy do jej wartości tekst (np. jakiego koloru jest kot).
Aby odwołać się w kodzie do nazwy zmiennej wpisujemy jej nazwę. Jeśli odwołujemy się do jej wartości wpisujemy jej nazwę poprzedzoną znakiem "$".
Do ustawiania zmiennych służą komendy SETVAR i SET. Różnica między nimi jest taka, że SET wymaga podania wartości w cudzysłowach a SETVAR nie.
Dzięki SET można w zmiennej zapisać wartość, która zawiera na początku lub na końcu spacje - SETVAR by je automatycznie obcieło.
Czasami jest potrzeba stworzenia zmiennej bez przypisywania jej na początku żadnej wartości (tzw. inicjalizacja zmiennej). Do tego celu służy również SETVAR ale bez drugiego parametru (jest opcjonalny).
W taki sam sposób można wyczyścić wartość już istniejącej zmiennej (czyszczenie zmiennej).
Do skasowania zmiennej z pamięci (zwolnienie zmiennej) służy komenda DELVAR.
Powracając do kodu generującego kolor zauważ, że niektóre linie zaczynają się od "//" - taka linia to komentarz i jest ignorowana w skrypcie (w Centrum T2 taka linia zaznacza się na szaro). Dobrze jest wstawiać komentarze w kodzie opisujące co dana część robi. Ułatwia to innym zrozumienie kodu i rownież Tobie może pomóc, jesli po dłuższym czasie wrócisz do skryptu pisanego przez siebie ;-).
Komenda USERBOX służy do pobrania od użytkownika odpowiedzi na pytanie (Tak lub Nie). W naszym przypadku odpowiedź jest zapisywana w wartości zmiennej user_sex (w przypadku gdy użytkownik odpowie Tak, zapisane zostanie 6; w przypadku Nie, zapisane zostanie 7).
IF już znasz. W tym wypadku jeśli użytkownik odpowiedział na Tak, ustawianana jest kolejna zmienna alt_text na wartość "spodni", jeśli odpowiedział na Nie (czyli jest kobietą ;-)), zmienna alt_text ustawiana jest na wartość "sukienek".
Być może zauważyłeś, że w skrypcie czasem w warunku IF w nawiasie stosuję "==" a czasem "===". Oba oznaczają równość, ale "==" jest sprawdzaniem bez brania pod uwagę wielkości liter, natomiast "===" sprawdza i porównuje również wielkość liter. W przypadku liczb, gdzie wielkość liter nie gra znaczenia używaj "===" (jest szybsze).
Ostatnie dwie linie w tym fragmencie są wywołaniem komendy USERINPUT - która pobiera wpisany tekst (w naszym wypadku nazwę koloru z trzech możliwych) od użytkownika i zapisuje do zmiennej user_color. Domyślny tekst w okienku wpisywania to wartość user_color przed wywołaniem USERINPUT (dlatego ustawiam wcześniej user_color za pomocą SETVAR na "niebieski").
Komenda RANDOM ustawia zmienną subcolor na losową liczbe z zakresu od 0 do 254. Następnie INC podnosi tę wartość o jeden (chcę aby subcolor zawsze był większy od zera). Komenda BASE służy do konwersji między systemami liczbowymi (w tym wypadku subcolor jest konwertowany z systemu dziesiętnego na szesnastkowy). Taka konwersja wiąże się z budową kolorów w T2 Script. W readme jest rozdział poświęcony kodom kolorów. Nie będę tu opisywał dokładnie kolejnego fragmentu - czyli jak odbywa się generowanie barwy. Jest to dla Ciebie teraz nieistotne.
Zauważ, że w parametrze TEXTOUT jest "$alt_text" - będzie on zamieniony na wartość zmiennej alt_text ("spodni" lub "sukienek" w zależności od tego co zostało wybrane przy określaniu płci użytkownika). Dla mężczyzny TEXTOUT wyświetli tekst "Sugerowany kolor spodni:" a dla kobiety "Sugerowany kolor sukienek:". :-)
Komenda BREAKLINE służy do wyświetlania kolorowej linii o wygenerowanym kolorze w oknie Serwer.
W tym fragmencie następuje zwalnianie wszystkich wykorzystanych w skrypcie zmiennych. Na tym kończymy omawianie tego skryptu. Zademonstruję teraz jedną z pętli w T2 Script.
Przykładem stałej występującej w pokojach i w oknach privów jest $room. Przechowuje ona nazwę okna. Często, jeśli chcemy używać stałej jako zmiennej (modyfikować ją lub używać jako parametru w postaci nazwy zmiennej), musimy najpierw ustawić ją komendą SETVAR:
Takie ustawianie stałych do zmiennych nazywamy potocznie globalizacją stałych. Teraz możemy używać zmiennej c_room jak każdej innej zmiennej.
Jeśli mamy wiele zmiennych, które chcemy przypisać do jednego zbioru, użyjemy tablicy zmiennych. Do zmiennej w tablicy odwołujemy się poprzez podanie indeksu. Tablice zmiennych w T2 Script nie są asocjacyjne (oznacza to, że jako indeks możemy podać wyłącznie liczbę a nie słowo). Są jednak od tego wyjątki (asocjacyjne elementy występują w tablicach stałych w pewnych funkcjach...). Narazie jednak zajmiemy się elementami nie asocjacyjnymi (liczbowymi). Pierwszy element każdej tablicy ma indeks równy zero. Zainicjalizujemy tablice o 5 elementach (o 5 zmiennych składowych).
Do poszczególnej zmiennej z tablicy, aby ją zmodyfikować, odwołamy się normalnie jak do każdej innej zmiennej komendą SETVAR:
Teraz wartość $tablica[3] (jest to czwarty element naszej tablicy) to "pies". Jeśli chcielibyśmy wstawić do wszystkich elementów słowo "pies", najłatwiej odrazu zainicjalizować tablice z tym słowem:
Teraz wszystkie elementy tablicy mają wartość "pies". Sytuacje, gdy chcemy ustawić inną wartość dla każdego z elementów tablicy, np. do każdego elementu wpisać jego numer jako liczbę, rozwiązujemy używając do tego pętli FOREACH przeznaczonej dla tablic:
Stała $int w pętli FOREACH oznacza aktualnie przetwarzany element tablicy. Elementy tablicy po wykonaniu takiej komendy zostaną ustawione na wartości:
Łatwo się domyślić, że tablice kasujemy analogicznie jak w przypadku zwykłych zmiennych komendą DELARRAY:
Zwolnieniu ulegną wszystkie elementy tablicy. Możemy też usuwać poszczególne elementy tablicy komendą DELVAR, ale trzeba pamiętać, że tablica musi zachować ciągłość w indeksach, np, jeśli wykasujemy z naszej tablicy element ze środka - elementy o większym indeksie nie będą już cześcią tablicy (zrobi się "dziura" w indeksach).
Napiszę teraz praktyczny przykład z wykorzystaniem tablic. Skrypt będzie wyświetlał liczbę otwartych okien rozmów w Taboret2 oraz nazwę każdego z nich.
Komenda EXPLODE służy do rozbijania tekstu do tablicy po separatorze umieszczonym w cudzysłowiach (u nas spacja ponieważ stała $_wnds to właśnie nazwy otwartych okien oddzielone spacjami). Jest tu niezbędna, opisywana już wcześniej globalizacja stałej, gdyż EXPLODE przyjmuje w parametrze nazwę zmiennej a dla stałej $wnds, de facto takiej nazwy nie ma (stałe mają tylko wartości).
Komenda ARRAYSIZE zapisuje do zmiennej ilość elementów w tablicy.
INFOOUT ma działanie zbliżone do TEXTOUT, ale ma dodatkowy parametr umożliwiający wyświetlenie tekstu jako informacji lub błędu.
Jest jeszcze jedna pętla, której działanie przypomina warunek IF. Mowa o WHILE. Pętla jest wykonywana dopóki warunek w parametrze jest spełniony:
W tym rozdziale poznałeś podstawowe elementy języka T2 Script :-). W następnych rozdziałach będę pokazywał jak można wykorzystać zdobytą wiedzę.
Idź do spisu treści
Aliasy, budowa własnej komendy
A ten, który posiada wiedzę, nie będzie narzekał. Syr 10,25
Spodobał Ci się już T2 Script? :-) Do tej pory wykorzystywaliśmy istniejące komendy do tworzenia własnych skryptów. Poza nimi T2 Script umożliwia definicję własnych komend. Taką stworzoną komendę nazywa się aliasem. Kiedyś aliasy odgrywały większą rolę, teraz sprowadzają się raczej do dodatku. Ten rozdział nie będzie długi ani trudny - tworzenie i obsługa aliasów nie stwarza problemów.
Stworzymy komendę SIEMA, która po wywołaniu będzie wysyłać na kanał wiadomość o treści "Jak się masz <osoba z parametru>?" jeśli będzie wywołana z parametrem. Natomiast komenda SIEMA wywołana bez parametru będzie odpowiedzią "Dzięki, czuję się świetnie.". Taki oto automat do ułatwienia bycia miłym ;-). Kod:
Komenda ALIASADD zwraca komunikat o poprawnym utworzeniu aliasa, ale dzięki użyciu @ na początku nie będzie on wyświetlany.
Po uruchomieniu skryptu w Centrum T2 przejdź do wybranego okna kanału i wydaj ręcznie z okna komendy do przetestowania aliasu:
Z aliasami związana jest stała $$, która służy do pobrania aktualnego parametru przekazywanego do komendy-aliasu. Natomiast wyrażenie "if ($$===)" można przeczytać: "jeśli parametr jest pusty".
Aby skasować alias używamy komendy ALIASDEL.
Warto zaznaczyć, że aby zmodyfikować już utworzony alias należy go najpierw usunąć i dopiero dodać ponownie. Spis zainstalowanych aliasów wyświetla komenda ALIAS.
Idź do spisu treści
Funkcje i ich rozszerzenia
A większą mi rozkoszą podróż niż przybycie! Leopold Staff
Wydaje Ci się, że to już blisko końca? O nie. ;-). Przed Tobą jeszcze parę ważnych zagadnień. Jednym z nich są funkcje. Czy wiesz jakby wyglądał duży, rozbudowany algorytm przy użyciu starego systemu skryptów? Jeśli nie wiesz, to ja Ci powiem - problemem w nim byłby brak podziału na segmenty i to, że skrypt fizycznie składałby się z wielu (kilkudziesięciu) plików .tsc.
Dlatego właśnie powstały funkcje aby temu zapobiec i ułatwić pisanie skryptów. Funkcja właściwie jest obiektem, w którym zapisane są linie kodu, umieszczonym w pamięci RAM. To jest dość istotna informacja, gdyż dzięki temu funkcje są bardzo szybkie w porównaniu ze starymi skryptami, które były ładowane z dysku przy każdym wywołaniu.
Funkcje są ładowane z pliku komendą LOAD (zwyczajowo już wyjątkiem jest Centrum T2, które może ładować funkcje bezpośrednio z obszaru wprowadzania tekstu przyciskiem "Ładuj"). Jak to wszystko działa? Otóż wyobraźmy sobie dwa krasnale. Jeden większy a drugi mniejszy. Większy odpowiada za wykonywanie kodu, ale nim zostanie do niego dopuszczony, kod musi być sprawdzony raz na początku przez mniejszego krasnala (komendę LOAD) i podzielony na odpowiednie częsci. Komenda LOAD działa właśnie jak mały krasnal a resztę wykonuje duży, czyli Taboret2.
Mały krasnal jest bardziej wyspecjalizowany i widzi tylko te linie w pliku, które rozpoczynają się od znaku #.
Otwórz Centrum T2 i wpisz następujący kod:
Aby załadować komendą LOAD plik t2.tsc wpiszemy w oknie Serwer:
Aby plik był ładowany za każdym razem, kiedy uruchamiasz Taboret2 na starcie:
Żeby wyładować funkcje z pliku t2.tsc:
Żeby wyładować funkcje z pliku t2.tsc i usunąć go z auto uruchamiania:
Można też do każdego z tych wariantów komendy dodawać flagę "i", która powoduje wyświetlanie szczegółowych informacji o procesie ładowania lub wyładowywania skryptu. Gdy skrypt będzie załadowany możesz uruchomić jego funkcje komendą FUNCTION:
Jako efekt powinieneś zobaczyć wyświetlony tekst "Jesteśmy w funkcji easy :-)".
W jednym pliku może być wiele funkcji o różnych nazwach i różnych ilościach wierszy każda.
Ogólny wzór na deklarację funkcji wygląda następująco:
Nazwy funkcji są czułe na wielkość liter, np. funkcje "easy" i "Easy" to różne funkcje.
Do tej pory Twoje funkcje easy i hard były funkcjami typu private() (funkcje prywatne) i nie posiadały rozszerzeń (typ prywatny jest prostszym typem, który nie pozwala na stosowanie rozszerzeń).
Typy funkcji w T2 Script:
Wspomniana wcześniej komenda PUT służy do przekazywania parametrów do funkcji zarówno prywatnych jak i publicznych.
Zmodyfikujmy nasz skrypt do postaci:
Całość ładujemy i sprawdzamy wywołując komendę
Rezultat powinien być taki:
Specjalnie wpisałem w funkcji easy dwa razy wywołania FUNCTION dla hard - chciałem pokazać, że parametr przekazany przez PUT jest widoczny jako stała akumulacyjna. Oznacza to, że po zakończeniu działania funkcji ta stała jest automatycznie kasowana (rozładowywana). W naszym przypadku po pierwszym wywołaniu funkcji hard rozładowywana jest stała $hard[skill_level] i przy drugim wywołaniu już nie jest zamieniana na wartość "trudny", gdyż jej po prostu już nie ma. Musielibyśmy przed drugim wywołaniem znów ustawić tę stałą za pomocą komendy PUT.
W tym przykładzie stała $hard[skill_level] jest ładowana przed oboma wywołaniami hard z easy. Dodatkowo pokazałem, że można używać PUT już podczas działania samej komendy, dla której ustawiana jest stała. Ilość łądowanych przez PUT stałych przed i w trakcie wywołania funkcji jest nieograniczona. Należy pamiętać, że raz ustawionej stałej nie da się zmienić dopóki funkcja nie zostanie rozładowana (zakończy się jej działanie).
Są wygodniejsze sposoby przekazywania do funkcji danych niż komenda PUT. Ale są one dostępne tylko dla funkcji publicznych, gdyż związane są z rozszerzeniami.
Tym razem mamy do czynienia z funkcjami publicznymi. Umożliwiają one dodawanie rozszerzeń (zwanych też czasem dyrektywami zasięgu). Funkcja prywatna może mieć wiele rozszerzeń. Każde z nich należy oddzielać " << " (ważna jest spacja przed i za <<).
W funkcji Kot wykorzystano rozszerzenie argvs. Działa ono tak, że przekazuje do funkcji stałą o wartości $Kot[argvs] jako ciąg znaków wpisany po wywołującej komendzie FUNCTION w parametrze. Zobacz na funkcje Zwierzaki:
W tym wypadku stała $Kot[argvs] przyjęła wartość "miau miau miau".
Rozszerzenie funkcji Pies to array. Ono również przekazuje parametr wpisany w wywołującej komendzie FUNCTION, ale parametr ten jest dzielony po spacjach na części i przekazywany jako tablica stałych (porównaj komenda EXPLODE z poprzednich rozdziałów). Dodatkowo metoda array udostępnia stałą $Pies[count], w której jest rozmiar przekazanej tablicy (ile tablica ma elementów).
Funkcja Piesokot ma oba te rozszerzenia i może korzystać z obu sposobów na raz. Jaki sposób wybrać dla własnych funkcji? Zależy od jej przeznaczenia. Do jednych funkcji lepsze jest rozszerzenie array (np. gdy mamy więcej przekazywanych parametrów) a do innych argvs.
Zasięg i rozszerzenia funkcji można zmienić już po załadowaniu funkcji do pamięci. Służy do tego komenda RANGE.
Takie użycie zmieni sposób w jaki będzie przekazywany parametr do funkcji Kot. Komendy RANGE można też użyć do zwolnienia funkcji z pamięci w sposób następujący:
Nie należy używać RANGE free() podczas działania zwalnianej funkcji (w tym wypadku z funkcji Kot) - spowodowałoby to błąd programu.
Omówiliśmy już wszystkie z dostępnych metod przekazywania stałych do funkcji. Przyszła pora na rozszerzenia wywołujące funkcje w określonych warunkach. Jednym z nich jest start_on_load (funkcja Zwierzaki), które uruchamia funkcję zaraz po załadowaniu jej z pliku. W takiej funkcji możemy np. umieścić algorytm instalujący lub ładujący ustawienia naszego skryptu. Jeśli funkcja z rozszerzeniem start_on_load wywołuje inne funkcje z tego samego pliku, powinna być ona umieszczona pod nimi (np. funkcja Zwierzaki jest ostatnia, na spodzie skryptu). W następnym rozdziale omówione zostaną dalsze rozszerzenia wywołujące funkcji publicznych.
Czy funkcja może zwrócić wynik? Napiszmy funkcję dodającą dwie liczby i zapisującą wynik do zmiennej.
Do obliczenia wyniku została użyta funkcja MATH, która wykonuje działania matematyczne na zmiennych. Inną ciekawą rzeczą jest zachowanie się funkcji Add w przypadku, jeśli nie podamy co najmniej 3 parametrów. Wyświetlany jest wtedy komunikat o błędzie i wywoływane jest RETURN - komenda ta służy do przerwania wykonywania funkcji. W linii, w której jest wywołany RETURN funkcja przerywa działanie.
Idź do spisu treści
Akcje jako rozszerzenia funkcji
Jeśli masz wątpliwości, to tak już zostanie. Prawo Murphiego
Można ustawić takie rozszerzenie dla funkcji publicznej by była ona automatyczne uruchamiana podczas pewnych zdarzeń. Wyobraźmy, na przykład, funkcję, która jest uruchamiana zawsze gdy ktoś pisze w oknie kanału. Tego typu rozszerzenia dla zdarzeń związanych z programem nazywamy akcjami.
Aby włączyć akcje w Taboret2 należy jednorazowo zaznaczyć odpowiednią opcję w ustawieniach programu "Wywołuj akcje w skryptach" lub jednorazowo użyć do tego celu komendy:
Przykład funkcji, która przekierowywuje wszystkie teksty z kanału #Towarzyski na kanał #biuro_szeryfow z użyciem rozszerzenia akcji:
Akcja on_msg przydziela podczas wywołania do funkcji stałe. Ich nazwy i znaczenie dla każdej akcji znajdują się w Readme. Dla przykładu opis akcji on_msg z Readme to:
Dla jednej funkcji można przydzielić, tak jak w przypadku przekazywania parametrów, wiele rozszerzeń akcji na raz. Funkcja, która wyświetli dodatkowe informacje o wejściu i wyjściu osób z pokoju wygląda następująco:
Akcja on_join zachodzi przy wejściu osoby na kanał a on_part przy wyjściu osoby z kanału. Nasuwa się pytanie jak rozróżnić, która akcja aktualnie wywołuje daną funkcję. :-). W przypadku akcji istnieje stała sender w tablicy funkcji. Zmieńmy naszą funkcję do postaci:
Jeśli wiele funkcji w jednym skrypcie korzysta z tych samych akcji, będą one wywoływane w kolejności w jakiej były załadowane. Innymi słowy, funkcje zadeklarowane wyżej w pliku są wywoływane przed funkcjami zadeklarowanymi poniżej. Przykład:
To chyba nie wymaga komentarza? :-). Nie będę omawiał dokładnie każdej z akcji. Tak jak już pisałem - ich aktualny spis i opisy dla stałych są zawarte w Readme.
Rozszerzenia funkcji można kombinować ze sobą do woli. Jedna funkcja może być równocześnie wywoływana akcjami, przekazywać parametry za pomocą funkcji FUNCTION (jak w poprzednim rozdziale), zwracać wyniki do zmiennych. Funkcja może wywoływać inne funkcje lub samą siebie (funkcja rekurencyjna).
Idź do spisu treści
Czas i timery
Ani się woda wróci, która upłynęła, także ani godzina, która już minęła.
Fakt, że dzięki T2 Script nie można cofnąc czasu i przenieść się np. na Dziki Zachód (przynajmniej w obecnej wersji tego języka ;-)) a jednak możemy naszymi zabiegami spowodować, że dany algorytm będzie wywoływany co określony czas lub zatrzyma się na chwilę w miejscu... Gdyby w życiu tak można było... :-).
Każdy skrypt wymaga określonego czasu do wykonania. Właściwie nie używa się określenia czas - gdyż czas jest uzależniony od wielu czynników - ale mówi się o koszcie wykonania algorytmu. Powinieneś projektować tak swoje skrypty, by miały jak najmniejszy koszt wykonania. Im mniej komend wykonywanych tym mniejszy koszt wykonania skryptu. Podam przykład skryptu, który działa, ale jego koszt wykonania jest niepotrzebnie duży (TAK MASZ NIE PISAĆ):
W tym skrypcie tablica ze słowami jest ustawiana za każdym razem gdy wywoływana jest akcja on_msg. Użyto również pętli FOREACH, która może jest wygodna, ale musi sprawdzać za każdym razem wielkość tej tablicy ze słowami. Budowa skryptu jest nieoptymalna.
Ten sam skrypt napisany optymalnie z uwzględnieniem kosztu wykonania (TAK PISZ):
Funkcja PrzygotujMojNick jest wywoływana tylko raz przy ładowaniu skryptu. Pętla wyszukująca słowa to w tym wypadku REPEAT a nie FOREACH. Dzięki takiej budowie odciążyliśmy ze zbędnego kodu akcje on_msg i zmniejszyliśmy koszt wykonania algorytmu.
Istnieje sposób na chwilowe zatrzymanie skryptu w jednym miejscu komendą SLEEP. Czasem zachodzi taka potrzeba:
W tym wypadku po wykonaniu komendy JOIN (inicjuje wejście do pokoju) trzeba odczekać chwilę (1000 milisekund - jedna sekunda) przed wysłaniem tekstu na kanał. Trzeba pozwolić na to by serwer przeniósł nas na ten kanał i otworzyło się okno rozmowy. Gdybyśmy w tym wypadku pominęli SLEEP tekst nie dotarłby na pokój.
Jak już wspomniałem na wstępie, istnieje także możliwość wywoływania algorytmu co określoną ilość czasu. Służą do tego timery. Timer w przeciwieństwie do komendy SLEEP umożliwia oczekiwanie bez przerywania wykonania skryptu (oczekuje w tle i co pewien, ustalony przez nas czas wywołuje daną funkcję). Jak zwykle poprę teorię kodem:
Ta komenda ustawi timer, który będzie wykonywał komendę co 2 sekundy (2000 milisekund) 5 razy. Po ostatnim wywołaniu timer automatycznie zostanie zwolniony. Parametr "auto" oznacza automatyczny przydział numeru timera na pierwszy wolny numer. Timery rozpoznajemy po ich numerze lub nazwie. Stała występująca w timerach $tint wskazuje na aktualny numer wywołania timera.
Moglibyśmy na przykład zainicjalizować timer o numerze 100:
Taki kod stworzy timer, ale nie uruchomi go po zainicjalizowaniu (taką właściwość ma komenda INITTIMER).
Aby uruchomić taki timer trzeba użyć komendy:
Istnieją też funkcje umożliwiające zatrzymanie timera na aktualnym wywołaniu (PAUSETIMER), wznowieniu jego pracy (RESUMETIMER) oraz zwolnieniu go przed zakończeniem pracy (KILLTIMER). Jest możliwość zwolnienia wszystkich pracujących timerów (KILLALLTIMERS) i sprawdzenia czy timer o podanym numerze jest zainicjalizowany (ISSETTIMER). Aktualna lista ustawionych timerów znajduje się w Centrum T2 w zakładce "Pamięć Timerów".
Jeśli jako ilość wywołań zostanie zadeklarowane -1, timer będzie wywoywał przypisaną mu komendę bez końca (w nieskończoność) do czasu wywołania w kodzie KILLTIMER testowy lub KILLALLTIMERS.
Na raz może pracować nieskończona liczba timerów.
Zmieniając troche temat, uznałem, że to też jest związane z czasem - w każdym miejscu skryptu można używać stałych $_time (aktualny czas) i $_date (aktualna data). Można korzystając z tego napisać skrypt działający jak budzik:
W kodzie budzika wykorzystano informacje, z którymi zapoznałeś się w tym i poprzednich rozdziałach. Budzik działa dość prosto. Jest to w zasadzie timer wywoływany co minutę (60000 milisekund) i sprawdzający czy aktualny czas równy jest czasowi, jaki został przekazany w parametrze funkcji UstawBudzik. Aktualny czas przed sprawdzeniem musi być obcięty z sekund komendą STRCOPY. Chciałbym zwrócić na nią większą uwagę:
Taka konstrukcja z $$z_time jest potrzebna, gdyż w rzeczywistości po ustawieniu timera kod w nim wykonywany co minutę wygląda następująco:
$z_time zamieniane jest na "_time". Gdybym nie posłużył się zmienną z_time, uzyskalibyśmy efekt, że w timerze jako parametr do komendy STRCOPY pojawiłby się czas, w którym ustawiliśmy timer a nie stała $_time. Na przykład:
Co spowodowałoby dysfunkcję całego budzika (czas by stał w miejscu dla niego). ;-).
W kodzie jest jeszcze jedna ciekawostka, na którą powinieneś zwrócić uwagę:
To przykład w jak prosty sposób można podpiąć pod funkcję alias z przekazaniem parametrów z aliasa. Aby uruchomić nasz budzik wystarczy wpisać teraz komendę BUDZIK z parametrem godziny i minuty, np:
Skrypt budzika, który przedstawiłem będzie działał prawidłowo gdy format czasu w Twoim systemie jest 24 godzinny, jeśli w systemie masz 12 godzinny format czasu, mogą wystąpić problemy (i trzeba będzie zmodyfikować skrypt).
Idź do spisu treści
Piszemy własny skrypt na autowykop (shit listę)
Nie żyje się, nie kocha się, nie umiera się - na próbę. Jan Paweł II
W tej części tekstu napiszesz skrypt na automatyczne wyrzucenie z pokoju osób o wybranym nicku lub IP. Osobiście nie jestem za stosowaniem tego typu funkcji na kanałach, jednak spotkałem się z wieloma pytaniami jak napisać taki właśnie algorytm.
W związku z tym, że ma to być praktyczna część sprawdzająca Twoje umiejętności nie podam na początku całego kodu, jak to miałem zwyczaj robić do tej pory. Chcę pokazać stadia projektowania skryptu - od czego się zaczyna, na czym się kończy.
Przed podaniem fragmentów kodu będę opisywał co ma robić dana funkcja - staraj się najpierw sam napisać własny algorytm na to, co jest w opisie a później dopiero porównuj go z moim kodem.
Przed napisaniem czegokolwiek trzeba dokładnie zaplanować założenia jakie ma spełnić skrypt.
Więc do dzieła! Zaczniemy od stworzenia szkieletów funkcji, które będą nam potrzebne. W Centrum T2 jest funkcja "Wstaw szablon > Wstaw funkcję", która ułatwi nam zadanie:
Jak widać struktura jest prosta. Całość będzie składać się z 4 funkcji publicznych z różnymi rozszerzeniami.
Zaczniemy pisanie kodu od funkcji ShitListOnLoad, która ma ładować z pliku tablicę z nickami i z IP dodanymi do shit listy. Musimy zdecydować się na jakiś sposób przechowywania tych danych. Proponuję przechowywać je na dysku w pliku ShitList.txt (wszystkie pliki dla zmiennych Taboret2 przechowuje w katalogu vars). Podczas ładowania skryptu z tego pliku ma zostać utworzona tablica zmiennych (funkcja ARRAYFROMFILE). Ponadto ShitListOnLoad ma tworzyć aliasa SHIT umożliwiającego w przyszłości korzystanie z funkcji ShitListAddNick. Oto mój kod:
Jest to prostsze niż myślałeś? :-). Następną funkcją jaką się zajmiemy jest główna funkcja shit listy ShitListOnJoin. Ma ona umożliwiać wyszukiwanie wchodzących nicków i IP (a właściwie domen, gdyż w pliku shit listy będą trzymane domeny w formacie szesnastkowym a nie IP w formacie dziesiętnym - zmniejszymy w ten sposób koszt wykonania algorytmu) komendą ArraySearch. Oczywiście, żeby to napisać trzeba znać sposób, w jaki serwer podaje nam te wiadomości. Mój kod:
Skrypt w tym momencie juz powinien działać po ręcznym utworzeniu pliku vars\ShitList.txt i wpisaniu do niego hostu w postaci np. A-53121a (adres IP 83.18.26.*) lub nicka. W każdej linii pliku będzie kolejny nick lub host z listy.
Następną tworzoną funkcją będzie ShitListAddNick umożliwiająca dodanie nicka, hosta lub IP do listy. Najłatwiej rozwiązać to korzystając z funkcji EXPLODE po kropce i sprawdzić czy dodawany jest adres IP (jeśli tablica będzie mieć więcej niż jeden element) - jeśli tak, tłumaczyć go na adres hosta w systemie szesnastkowym, jeśli nie, dodać nick lub host w formie niezmienionej na koniec tablicy. Mój kod:
Czasem dodatek może być bardziej skomplikowany niż najważniejsza funkcja. W tym wypadku tak jest. W czasie pisania powstała potrzeba dodania dodatkowej funkcji ShitListTranslateIP, która tłumaczy adres IP z formy, np. 83.15.26.* na A-53f1a. Kod w pętli w funkcji ShitListTranslateIP dodaje do $dodaj_mnie kolejne człony z tablicy przetłumaczone na system szesnastkowy. Na końcu wszystkie litery w dodaj_mnie są pomniejszane (LOWERCASE) i na początku zmiennej dodawane jest "A-".
Została ostatnia funkcja ShitListSave wywoływana akcją on_logout (zachodzi gdy rozłączamy się z serwerem lub gdy Taboret2 jest zamykany). W niej będzie prosty zapis tablicy do pliku tekstowego komendą ARRAYTOFILE.
Przedstawię teraz cały kod w jednym miejscu jako podsumowanie:
Co my wiemy, to tylko kropelka. Czego nie wiemy, to cały ocean. Isaac Newton
Dla osób znających język skryptowy PHP jest w T2 Script możliwość korzystania z niego i ze wszystkich jego przydatnych funkcji. Wszystko co należy zrobić by korzystać z PHP w T2 Script to:
Przy pomocy PHP możemy np. obsłużyć bazę danych MySQL z poziomu T2 Script lub korzystać z pobierania plików z FTP.
Skrypty w PHP pisze się podobnie jak w przypadku stron WWW, tylko tu, zamiast języka HTML, manipuluje się językiem T2 Script.
Poznawanie tajników pisania skryptów w PHP wykracza poza obszar tego tekstu. Pokażę tylko prosty skrypt przekazujący dwa parametry do PHP:
test.php:
Jak widać, parametry przekazane do skryptu PHP przez T2 Script są dostępne w tablicy $argv.
Istnieje również możliwość korzystania z bibliotek DLL w T2 Script. Możemy wywołać dowolną funkcję z dowolnej biblioteki.
Dzięki bibliotekom DLL można tworzyć własne okna, pluginy itp... Możliwości są ogromne. Przykładowe źródła bibliotek pisane w różnych językach programowania można znaleźć na stronie programu Taboret2.
Idź do spisu treści
Koniec
Acta est fabula. Caius Iulius Caesar Octavianus Augustus
Dobrnąłeś/aś do końca mojego tutoriala. :-). Brawo. Jeśli czytałeś uważnie i ze zrozumieniem będziesz miał podstawy do tworzenia własnych zaawansowanych skryptów w języku T2 Script, którymi możesz pochwalić się na forach lub przed kolegami. Apeluje jeszcze raz o wysyłanie mi listów z opiniami o tekście. Dziękuję za uwagę.
Szczególne podziękowania dla Oli za korektę tekstu i czujne oko. ;-).
O autorze: