oLuju Opublikowano 22 Września 2017 Udostępnij Opublikowano 22 Września 2017 Hej, otóż udało mi się ogarnąć Networking w GMS'ie, jednak natknąłem się na pewien błąd, którego nie potrafię rozwiązać. Otóż oprócz posiadania podstawowego buffer'a do wysyłania danych na temat pozycji graczy potrzebuje utworzyć 2 odpowiedzialny za wysyłanie danych z Servera do Clientów. Bufferem tym wysyłane są dane nad którymi kontrolę ma tylko server (np.: aktualny czas rozgrzewki, kiedy rozpocząć kolejną rundę, kiedy zakończyć/rozpocząć mecz [rozpocząć po rozgrzewce]). Wygląda to tak: nazwa obiektu - nazwa zdarzenia oServer - Networking: switch(async_load[? "type"]){ case network_type_connect: case network_type_non_blocking_connect: server_handle_connect(async_load[? "socket"]); break; case network_type_data: server_handle_message(async_load[? "id"], async_load[? "buffer"]); break; case network_type_disconnect: server_handle_disconnect(async_load[? "socket"]); break; } Script - server_create: server_buffer = buffer_create(128, buffer_fixed, 1); Script - server_handle_message: var socket_id = argument0, buffer = argument1, client_id_current = clientmap[? string(socket_id)].client_id; buffer_seek(server_buffer, buffer_seek_start, 0); buffer_write(server_buffer, buffer_u16, match_end); buffer_write(server_buffer, buffer_u16, warmuptime); buffer_write(server_buffer, buffer_u16, global.matchstart); with(oServerClient){ if(client_id != client_id_current){ network_send_raw(self.socket_id, other.server_buffer, buffer_tell(other.server_buffer)); //self and other }} oClient - Networking: switch(async_load[? "type"]){ case network_type_data: client_handle_message(async_load[? "buffer"]); break; } Script - client_connect: server_buffer = buffer_create(128, buffer_fixed, 1); Script - client_handle_message: var buffer = argument0; buffer_seek(server_buffer, buffer_seek_start, 0); match_end = buffer_read(server_buffer, buffer_u16); warmuptime = buffer_read(server_buffer, buffer_u16); global.matchstart = buffer_read(server_buffer, buffer_u16); oPlayer.match_end = match_end oPlayer.warmuptime = warmuptime //global.matchstart = matchstart próbowałem jeszcze tak (bez "server_buffer = buffer_create..." w skrypcie "client_connect"): var buffer = argument0; buffer_seek(buffer, buffer_seek_start, 0); match_end = buffer_read(buffer, buffer_u16); warmuptime = buffer_read(buffer, buffer_u16); global.matchstart = buffer_read(buffer, buffer_u16); oPlayer.match_end = match_end oPlayer.warmuptime = warmuptime //global.matchstart = matchstart Nie działa. Gracze nie otrzymują danych na temat zmiennych pomimo tego, że server poprawnie je kontroluje (np.: po zakończeniu rozgrzewki ustala zmienną odpowiedzialną za start meczu na 1). Gdy do gry dołączy pierwszy gracz nic się nie dzieje - zmiennych nie odczytuje, ale można się poruszać po mapie. Gdy do gry dołączy drugi gracz czasem od razu, a czasem po pewnym czasie wywala takiego errora: ___________________________________________ ############################################################################################ ERROR in action number 1 of Async Event: Networking for object oClient: Attempting to read from outside the buffer, returning 0 at gml_Script_client_handle_message ############################################################################################ -------------------------------------------------------------------------------------------- stack frame is gml_Script_client_handle_message (line 0) gml_Object_oClient_Other_68 Wie ktoś co może robię źle? Mi skończyły się już pomysły co do tego jak rozwiązać ten problem. Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
I am Lord Opublikowano 23 Września 2017 Udostępnij Opublikowano 23 Września 2017 A jakbyś robił łączenie zwykłe a nie non_blocking? Pamiętam jak ja miałem z tym ogromne problemy zanim doszedłem co było nie tak. Edit: Chciałem zrobić z tego asset na MP ale jeszcze wymaga dużo pracy i się chyba zbyt skomplikowało to i tak nie ukończę. Może ci się na coś przyda: https://drive.google.com/file/d/0B-1vrtiAAheiZlFHQTdPUHZiZG8/view?usp=sharing W "oGameController" w create musisz zmienić IP na swoje. W przykładzie jest zrobione, łączenie się dowolnej ilości klientów z serverem po non_blocking, Client posiada swój nick oraz kolor gracza który sobie ustawił i server to odczytuje wszystko. Po podłączeniu się przenosi klienta na czat, czat jest kolorowy, rozpoznaje kolory graczy. Jest też ping, wyświetla się on w prawym górnym rogu. Mechaniki gry nie zaimplementowałem, są tam jedynie jakieś ściany i podłogi które nic nie robią. Aha i bardzo fajna funkcja, aplikacja zapisuje logi z czata i logi zwyczajne do debugów. W windowsie 10 znajdziesz je w : "%localappdata%/Multi_zabawy" aha i w macro są Porty do ustawienia, po UDP idzie ping a po TCP idzie czat Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
oLuju Opublikowano 23 Września 2017 Autor Udostępnij Opublikowano 23 Września 2017 Tylko, że ja właśnie robię "zwykłe" połączenie. W szczególności, że nie używam tego: network_set_config(network_config_connect_timeout, 1000); network_set_config(network_config_use_non_blocking_socket, 1); Z ciekawości dopisałem to w Creacie swojego oServer'a i nie zależnie czy jest: network_set_config(network_config_use_non_blocking_socket, 1); lub: network_set_config(network_config_use_non_blocking_socket, 0); nie powoduje to żadnego wpływu na wysyłane dane - gracze poruszają się po staremu i wszystko funkcjonuje normalnie. Wysyłanie danych z Servera za pomocą bufora: "server_buffer" jak nie działało tak nie działa dalej. Przejrzałem też twój projekt, problemem jest odmienny "styl napisanego skryptu" przez co jest mi się trochę trudno połapać o co chodzi. Próbowałem też wysyłania danych surowych i skompresowanych, lecz to również nie przyniosło żadnego efektu. Nie pojmuje tego błędu - jakim prawem dane nie są wysyłane skoro wszystko działa dokładnie tak samo jak pierwszy buffer odpowiedzialny za wysyłanie informacji pomiędzy klientami. Jedyną różnicą jest to że dane wysyłane są z bezpośrednio z Servera do Clientów, a nie: od Clienta do Servera, a stamtąd do innych użytkowników (Clientów). EDIT: Okej, udało mi się rozwiązać problem. Nie wiem jakim cudem. Generalnie pokombinowałem jeszcze z kolejnością wysyłania zmiennych i odczytywaniem nazw bufferów. Grunt, że działa. Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Rekomendowane odpowiedzi
Jeśli chcesz dodać odpowiedź, zaloguj się lub zarejestruj nowe konto
Jedynie zarejestrowani użytkownicy mogą komentować zawartość tej strony.
Zarejestruj nowe konto
Załóż nowe konto. To bardzo proste!
Zarejestruj sięZaloguj się
Posiadasz już konto? Zaloguj się poniżej.
Zaloguj się