Skocz do zawartości

[39dll] Odbieranie wiadomości?


Rekomendowane odpowiedzi

No więc biorę się za 39dll, żeby nie być gorszym :P . I mam problem. Serwer nie tworzy obiektu Client, gdy dołącza gracz do gry. O to kod step serwera:

GML
socket = tcpaccept( tcp, true );

 

if ( !socket )

exit;

 

while( true )

{

message = receivemessage( socket );

 

if ( message <= 0 )

break;

 

caption = readbyte();

 

switch( caption )

{

case 0:

// doszedl gracz

_name = readstring();

_x = readint();

_y = readint();

 

if ( playC < 10 )

{

for( i = 0; i < 10; i += 1; )

{

if ( play[ i ] == -1 )

{

play[ i ] = true;

 

playO[ i ] = instance_create( _x, _y, Client );

playO[ i ].i = i;

playO[ i ].name = _name;

 

playC += 1;

break;

}

}

}

 

clearbuffer();

 

writebyte( 0 );

writebyte( i );

writestring( _name );

writeint( _x );

writeint( _y );

sendmessage( socket );

break;

case 1:

// odszedl jakis gracz

_id = readint();

 

with( playO[ _id ] )

instance_destroy();

 

playC -= 1;

play[ _id ] = -1;

 

clearbuffer();

 

writebyte( 1 );

writebyte( _id );

sendmessage( socket );

break;

case 2:

// gracz wykonal jakis ruch

_id = readbyte();

 

_x = readint();

_y = readint();

 

playO[ _id ].x = _x;

playO[ _id ].y = _y;

 

clearbuffer();

 

writebyte( 2 );

writebyte( _id );

writeint( _x );

writeint( _y );

 

sendmessage( socket );

break;

}

}

A to Create gracza:

GML
dllinit( 0, true, false );

 

x = random( 300 );

y = random( 300 );

 

name = get_string( "Podaj nazwę gracza:", "nowy_gracz" );

 

tcp = tcpconnect( get_string( "Podaj ip serwera:", "localhost" ), 123, true );

 

if ( !tcpconnected( tcp ) )

{

show_message( "Nie udało się połączyć z serwerem!" );

 

dllfree();

game_end();

}

 

myid = -1;

 

socket = tcpaccept( tcp, true );

clearbuffer();

 

writebyte( 0 );

writestring( name );

writeint( x );

writeint( y );

 

sendmessage( socket );

Dam jeszcze na wszelki wypadek step klienta:

GML
if ( myid == -1 )

exit;

 

socket = tcpaccept( tcp, true );

 

if ( !socket )

exit;

 

while( true )

{

message = receivemessage( socket );

 

if ( message <= 0 )

break;

 

caption = readbyte();

 

switch( caption )

{

case 0:

// doszedl gracz

_id = readbyte();

_name = readstring();

_x = readint();

_y = readint();

 

if ( myid == -1 )

myid = _id;

else

{

_i = instance_create( _x, _y, Client );

_i.i = _id;

}

break;

case 1:

// odszedl jakis gracz

_id = readint();

 

global.i = _id;

 

with( Client )

{

if ( _id == global.i )

instance_destroy();

}

break;

case 2:

// gracz wykonal jakis ruch

_id = readbyte();

 

_x = readint();

_y = readint();

 

with( Client )

{

if ( _id == global.i )

{

x = _x;

y = _y;

}

}

break;

}

}

Co jest źle :P ?

Odnośnik do komentarza
Udostępnij na innych stronach

a gdy gracz dochodzi do gry to wysyła bajta 0? i w ogole chyba zle robisz ale nie wiem.. bo w serwerze powinienes zrobic create:

GML
socket=tcplisten(port,iloscgraczymax,1)

//i wtedy dopiero w step:

jakisclient=tcpaccept(socket,1)

chyba ze to tcp jako socket masz w create to sorry.

edit: aha i przed odbieraniem nie robi sie clearbuffer()

Odnośnik do komentarza
Udostępnij na innych stronach

  • Administratorzy

create gracza:

GML
dllinit( 0, true, false );

 

x = random( 300 );

y = random( 300 );

 

name = get_string( "Podaj nazwę gracza:", "nowy_gracz" );

 

//tcp = tcpconnect( get_string( "Podaj ip serwera:", "localhost" ), 123, true );

socket = tcpconnect( get_string( "Podaj ip serwera:", "localhost" ), 123, true );

 

//if ( !tcpconnected( tcp ) )

if ( !socket )

{

show_message( "Nie udało się połączyć z serwerem!" );

 

dllfree();

game_end();

exit;

}

 

myid = -1;

 

//socket = tcpaccept( tcp, true );

clearbuffer();

 

writebyte( 0 );

writestring( name );

writeint( x );

writeint( y );

 

sendmessage( socket );

Odnośnik do komentarza
Udostępnij na innych stronach

  • Administratorzy

Ale wiesz co, w Almorze mam np. tak, że serwer jak przyjmuje nowego gracza ( tcpaccept() ), to ustawia tylko setnagle( socket , true); i tworzy klienta i to on w stepie zajmuje się odbieraniem pozycji:

 

GML
while (true)

{

size = receivemessage( socket );

if ( size <= 0 ) break;

 

packet = readbyte();

switch ( packet )

 

// itd.</span></span>

 

Edit: jak masz tcpaccept to tam masz socket nowego połączenia, więc ten step serwera nie działa już po tym jak gracz się połączy.

Odnośnik do komentarza
Udostępnij na innych stronach

  • Administratorzy

wiec to by chyba musiało być tak:

 

step serwera:

GML
socket = tcpaccept( listen, 1 );

if socket

{

setnagle(socket,true);

a = instance_create(0,0,objKlient);

a.socket = socket;

}

 

step serwera, objKlient:

 

GML
while (true)

{

size = receivemessage( socket );

if ( size <= 0 ) break;

 

packet = readbyte();

switch ( packet ) { /*case*/ }

// tutaj także pakiet z pozycją, nickiem itd., jak będą złe, to usuwamy gracza i rozłączamy

// itd...

}

 

jak to nie dziala, to juz nie wiem, przepisałem Ci prawie Almorę, obciąłem tylko sprawdzanie wersji klienta i liczby graczy :P

Odnośnik do komentarza
Udostępnij na innych stronach

  • Administratorzy

brakuje na serwerze:

 

socket = tcpaccept( listen, 1 );
if socket
{
setnagle(socket,true);
a = instance_create(0,0,objKlient);
a.socket = socket;
}

 

a kod step z serwera, trzeba przenieść do objektu graczy bodaj

Odnośnik do komentarza
Udostępnij na innych stronach

  • Administratorzy

nie rozumiesz:

 

SERWER nasłuchuje, czy ktoś dołącza, (tcpaccept zwraca socket > -1 ), tworzy nowy obiekt GRACZ i ustawia mu zmienną SOCKET na socket. SERWER nasłuchuje nadal na następnych NOWYCH graczy. TCPACCEPT zwraca > -1 tylko, gdy dołącza ktoś nowy, tych zaakceptowanych już nie zwraca.

GRACZ sprawdza w pętli rozmiar wiadomości która przyszła na socket (size = receivemessage( socket );). Jeżeli jest większa od zero, to robi switcha i tam case, a jak nie to break. Jak za długo nie dostanie nic (można dodawać co step ping +1 jak nie doszły dane i ping=0 gdy doszły), to go kasujemy i zamykamy socket.

 

Wazne info. Gdy wyrzucamy gracza z serwera, lub gracz w KLIENCIE rozłącza się z serwerem, NIE WOLNO od razu zamknąć socketa, bo wtedy zamknie się zanim dane zostaną wysłane. Trzeba odczekać ok. 1s i wtedy zamknąć socket z graczem, lub z serwerem.

Odnośnik do komentarza
Udostępnij na innych stronach

To na dole jest nieważne, gdy ping = 0 :P . Ale gnysku, ja to rozumiem. Ale napisz mi kod step klienta. I nie mów o skopiowaniu, bo podczas gdy mam usunąć i dodać zarazem 100 linijek kodu, jaka jest szansa, że nie popełnię błędu?

 

GRACZ to KLIENT NA SERWERZE, czy GRACZ U KLIENTA?

 

Ja już kompletnie nie kumam tego 39dll. Zrobisz mi taki przykład najprostszy, który ja próbowałem zrobić? Zaglądałem do setek artykułów i przykładów - i każdy ma inną strukturę odbierania i wysyłania danych :/ .

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ę...