Jump to content

Recommended Posts

Jak pisać po stronie servera, a jak po stronie clienta ?

Zbyt ogólne pytanie.. Odesłałbym Cię raczej do tutoriali LUA (z perspektywy pisania pod MTA). Pisze się tak samo, tylko wykorzystuje różne funkcje. Rozróżnienie istnieje po to, bo wykonywanie szeregu funkcji o których serwer nie musi wiedzieć po stronie serwera wymagałoby dużej ilości transferów i lagowałoby (coś jak SAMP), natomiast pisanie akcji, które są krytyczne dla serwera (stan zdrowia itd) po stronie klienta, powoduje, że serwer nie ma kontroli nad grą (a mieć musi).

Tylko prosze bez pisania poszukaj w google, bo nie od tego jest forum...

Nie jest też od powtarzania w kółko tego samego, nie jest także od prowadzenia kogoś za rączkę od A-Z, gdyż na niektóre pytania zadające przez nowych odpowiadało się referatem wielkości książki. A trochę to schodzi napisać, a ta wiedza jest już zapisana przez kogoś.

Im konkretniejsze pytanie, tym konkretniejsza i szybsza odpowiedź ;)

A tablice służą temu, żeby nie tworzyć kolejnych zmiennych. Załóżmy, że chcesz pobrać listę wszystkich markerów. Nie chcesz mieć nowych zmiennych dla każdego markera, bo jak to przedstawisz w kodzie, nie wiedząc ile ich jest? Zrobisz 1000 zmiennych?

Ano zrobisz coś w rodzaju (uwaga, pseudokod):

local tablica_z_markerami = pobierz_jakiestam_markery(); 

,

potem kolejne elementy tablicy, tj. tablica_z_markerami[1], tablica_z_markerami[2], tablica_z_markerami[3] - to są kolejne markery. nawet się je policzyć da i łatwo wykonać akcję na wszystkich markerach

Link to comment

Problem jest taki iż nie wiem jak to zrobić. Nie wiem jak odwołać się nawet w danym pliku, do innego pliku. Mógłbyś mi to rozjaśnić ? : P (używam podstawowego skryptu logowania, wraz z wzrostem doświadczenia zrobie swój.)

Mam jeszcze pare pytań, co to jest "trigger event" "addEvent"(po co to jak jest addEventHandler[a czasem pisze się po coś oba 0.0]), "root", "getRootElement()" To co podałem ostatnie, to jest już wogłóle chore. Byłbym wdzięczny gdybyś umiał mi to wytłumaczyć, troche tego dużo, ale dla ciebie to pewnie pestka ;d

Link to comment

TriggerEvent służy do wywołania funkcji połączonej z eventem stworzonym za pomocą "addEvent". Wytłumaczę Ci kodem.

addEvent ( "mojwlasniestworzonyevent", true ) 
  
function TextTest ( ) 
outputChatBox ( "TEXT TEXT TEXT" ) 
end 
addEventHandler ( "mojwlasniestworzonyevent", getRootElement(), TextTest ) 

Korzystając teraz z triggerClientEvent ( "mojwlasniestworzonyevent", getRootElement() ) wywołasz funkcję TextTest.

Link to comment

Lepiej zacząć od podstaw:

Server – komputer na którym jest zainstalowana i uruchomiona aplikacja serwera, służy do synchronizacji danych pomiędzy klientami, a w grach które są od początku projektowane jako multiplayer (nie MTA) może także obsługiwać fizykę świata.

Client – w przypadku MTA to komputer na którym zainstalowane jest GTA i aplikacja klienta MTA, służy do wyświetlania interfejsu użytkownika i grafiki, a w przypadku MTA w 100% odpowiada za fizykę świata...

Jedyny przypadek kiedy client i server to ten sam komputer jest wtedy gry uruchamiasz server na swoim domowym PC a potem się z nim bezpośrednio łączysz, w pozostałych przypadkach mamy do czynienia z 1 serverem i od 0-(mak ilość graczy na serverze) clientami i każdy jest osobnym komputerem.

Ponieważ w MTA server nie ma bezpośredniego dostępu do silnika gry informacje o wszystkim przechowywane są w strukturze o nazwie 'drzewo elementów' (element tre) – drzewiasta struktura rodzic-dziecko w której każde dziecko ma tylko 1 rodzica, ale rodzic może mieć dowolną liczbę dzieci. U podstaw struktury leży korzeń (rootelement lub po prostu root) który nie ma rodzica, a sam jest bezpośrednim rodzicem graczy (gracz i client to praktycznie to samo) i zasobów. Gracze natomiast są rodzicami swoich awatarów (pedów) a np. zasób play jest rodzicem wszystkich samochodów przez niego utworzonych. W przypadku niektórych funkcji wykonanych na rodzicu, funkcja ta będzie wykonana także dla wszystkich dzieci o typie właściwym dla tej funkcji:

local markers = getElementsByType('marker') -- funkcja ta domyślnie wykonywana jest dla 'root' więc znajdzie wszystkie markery na serverze 
local markers = getElementsByType('marker',getResourceRootElement(getResourceFromName('jakiś tam zasób')))-- teraz funkcja znajdzie wszystkie markery utworzone przez jakiś tam zasób 

Każdy Client ma własną kopię drzewa elementów i jeśli jakoś nowy element zostanie stworzony przez server to kopia drzewa wszystkich clientów jest uaktualniona, natomiast jeśli coś jest utworzone przez clienta, to z reguły wie o tym tylko ten client który to stworzył – celowo lub nie może dojść do sytuacji że dwóch graczy stojących obok siebie widzi różne rzeczy!

Kolejne ważne pojęcie to gracz lokalny (loaclPlayer) jest to element który istnieje tylko po stronie clienta (na serverze wszyscy gracze są równorzędni) i przedstawia gracza który jest właścicielem danego clienta.

Fizyka gry istnieje tylko w promieniu 500m od gracza lokalnego, dalej niż ta odległość większość elementów (na samochody) po prostu znika, a wszelkie obiekty tracą kolizję.

Gracz lokalny zawsze jest synchronizowany (niezbędne informacje takie jak pozycja awatara wysyłane są na server, i dalej do innych clientów)

Przechodnie (pedy) nie kontrolowane przez żadnego gracza domyslnie synchronizowane są tylko w promieniu 100m od lokalnego gracza (jeśli ped był utworzony przez server to zmiana jego pozycji po stronie clienta, pod warunkiem że pozycja startowa i końcowa są w zasięgu synchronizacji, będzie widoczna dla wszystkich graczy)

W przypadku pojazdów nie sperowanych przez gracza zasięg synchronizacji jest nieco większy (chyba 150), ale ped w pojeździe traktowany jest jako ped (zasięg 100)

Pozostałe elementy nie są synchronizowane (przesunięcie bramy po stronie clienta będzie widoczne tylko dla clienta który dokonał zmiany)

W danym momencie dany element (ped, pojazd) może być synchronizowany tylko przez jednego gracza, zmiana odbywa się automatycznie gdy element wyjdzie poza zasięg jednego gracza, ale znajdzie się w zasięgu innego lub ręcznie na pomocą setElementSyncer (Uwaga – zasada zasięgu dalej obowiązuje).

Skrypty:

Skrypty po stronie serwera działają od razu po ich uruchomieniu, natomiast te po stronie clienta muszą być pobrane z servera (pobierane są także pliki z obrazkami i dźwiękiem jeżeli dany zasób takowe zawiera), domyślnie skrypt clienta zacznie działać dopiero po pobraniu wszystkich niezbędnych plików. Czasu pobierania nie da się przewidzieć bo każdy gracz ma inny sprzęt (ale istnieje pewien trick o którym później)

Uwaga: różnice w sprzęcie oznaczają że ten sam skrypt może działać inaczej na niektórych komputerach lub w przypadku szaderów w ogóle nie zadziałać!

Ręczna komunikacja Client-Server Server-Client:

setElementData – jest to funkcja która wprowadza zmianę do drzewa elementów i pozwala na edycję istniejących wpisów lub też tworzenie całkiem nowych w obrębie danego elementu.

triggerServer/Client/Event po jednej stronie w połączeniu z addEvent i addEventHandler – ten zestaw funkcji pozwala na przesyłanie pakietów danych i nie wprowadza zmian w drzewie elementów (ale z niego korzysta)

funkcja trigger (odpal) wymaga podania:

-clienta w przypadku triggerClientEvent, root jest domyślny i oznacza wszystkie clienty

-tekstu oznaczającego nazwę wydarzenia

-elementu źródłowego (po drugiej stronie będzie ukrytym parametrem 'source')

-opcjonalnie dodatkowych parametrów

po drugiej stronie:

-rejestrujemy wydarzenie (robimy to tylko raz) za pomocą addEvent (podajemy nazwę eventu i podajemy czy może być uruchamiany zdalnie – prawie zawsze chcemy żeby był uruchamiany zdalnie)

-następnie dodajemy funkcję obsługującą (tu nie ma limitu tych funkcji) za pomocą addEventHandler.

Musimy podać nazwę eventu, element do którego event jest przyczepiony (może być konkretny lub root) oraz funkcje która ma być uruchomiona.

Funkcja będzie miała ukryty parametr o nazwie source oraz tyle innych parametrów ile podaliśmy w funkcji trigger.

Przykład – dajmy serverowi znać że client pobrał wszystkie pliki i można bez problemu dzielić się z nim informacjami:

client:

  
triggerServerEvent('onFileDownloadNazwaZasobu',getLocalPlayer())--na końcu pliku clienta 
  

server:

  
addEvent('onFileDownloadNazwaZasobu',true) 
addEventHandler('onFileDownloadNazwaZasobu',root,function() 
    outputChatBox ( getPlayerFromName(source).." pobrał plik" )  
end) 
  

Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...