Skocz do zawartości

2 buffer nie działa


oLuju

Rekomendowane odpowiedzi

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

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 :P 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

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

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ę
  • Ostatnio przeglądający   0 użytkowników

    • Brak zarejestrowanych użytkowników przeglądających tę stronę.
×
×
  • Dodaj nową pozycję...