Autor Wątek: petla wysylajaca informacje o graczach  (Przeczytany 6669 razy)

Offline Psiryj

  • Użytkownik

# Maj 28, 2014, 21:56:20
@Xion, tak, wywoluje za kazdym odebraniem pakietu od jakiegokolwiek gracza, co do ograniczenia widocznosci graczy bede to implementowal, lecz dopiero wtedy gdy wysylanie informacji bedzie dzialalo tak jak powinno, hm, myslalem tez nad upakowaniem tych danych w jeden pakiet i pewnie tak tez zrobie, ale kiedy indziej, powod taki sam jak wyzej wymieniony

Offline Mr. Spam

  • Miłośnik przetworów mięsnych

Offline Xion

  • Redaktor
    • xion.log

# Maj 28, 2014, 22:02:47
W takim razie remz przez przypadek wyjaśnił, jak ten mechanizm działa (o ile "wysyła pakiet do" zastąpi się przez "sprawia, że serwer wysyła pakiet do"). Zaimplementowałeś komunikację typu każdy-z-każdym, mimo że tego nie potrzebujesz (bo to w końcu masz serwer). Wysyłaj update'y w sposób, który nie zależy od ilości podłączonych klientów, np. co określony czas, mierzony osobno dla każdego klienta.

Offline Psiryj

  • Użytkownik

# Maj 28, 2014, 22:10:41
dzieki za podpowiedz, jutro po pracy postaram sie to napisac i zobaczymy co z tego wyjdzie, tym czasem zycze dobrej nocy ^^

Offline Malkavian Ass...

  • Użytkownik

# Maj 28, 2014, 22:49:02
W takim razie remz przez przypadek wyjaśnił, jak ten mechanizm działa (o ile "wysyła pakiet do" zastąpi się przez "sprawia, że serwer wysyła pakiet do"). Zaimplementowałeś komunikację typu każdy-z-każdym, mimo że tego nie potrzebujesz (bo to w końcu masz serwer). Wysyłaj update'y w sposób, który nie zależy od ilości podłączonych klientów, np. co określony czas, mierzony osobno dla każdego klienta.
No, zatem nie rozumiem skąd "LOLWUT" pod moim postem. "Wywal jedną z pętli" == "Nie implementuj komunikacji każdy z każdym".

Offline Xion

  • Redaktor
    • xion.log

# Maj 29, 2014, 00:11:01
@up: Jeśli wywalisz jedną z tych pętli, nie będziesz już powiadamiał wszystkich klientów o pozycji wszystkich innych klientów. Innymi słowy, klienci nie będą dostawali wszystkich informacji, których potrzebują.

Tak jak napisałem wyżej, problem jest nie tyle w samej funkcji rozsyłającej te dane, tylko tym, gdzie i kiedy jest wywoływana.

Offline Psiryj

  • Użytkownik

# Maj 29, 2014, 20:56:26
udalo mi sie napisac cos takiego, jednak nie chce dzialac, debuger wywala blad przy ifie wskazanym komentarzem, co jest nie tak? : o
void Server::SendMapInfo()
{
    std::vector<int> visibleplayers;
    int g;
    g=0;
    if(inGame>1)
    {
        for( int i=0;i<inGame;++i )
        {
            for( int j=0;j<inGame;++j)
            {
                if(inGameClients[j]->ClientID!=inGameClients[i]->ClientID&&inGameClients[i]->inGame==true&&inGameClients[j]->inGame==true)
                {
                    if(inGameClients[i]->Char.X/maps[inGameClients[i]->Char.MapID]->tilesize-1<=inGameClients[j]->Char.X/maps[inGameClients[i]->Char.MapID]->tilesize
                        && inGameClients[i]->Char.X/maps[inGameClients[i]->Char.MapID]->tilesize+1 >= inGameClients[j]->Char.X/maps[inGameClients[i]->Char.MapID]->tilesize
                        && inGameClients[i]->Char.Y/maps[inGameClients[i]->Char.MapID]->tilesize-1 <= inGameClients[j]->Char.Y/maps[inGameClients[i]->Char.MapID]->tilesize
                        && inGameClients[i]->Char.Y/maps[inGameClients[i]->Char.MapID]->tilesize+1 >= inGameClients[j]->Char.Y/maps[inGameClients[i]->Char.MapID]->tilesize
                    )
                    {
                        visibleplayers.push_back(j);
                    }
                }
                ++g;
            }
            if(g>visibleplayers.size())
            {
                inGameClients[i]->family=Packet::PACKET_WORLD;
                inGameClients[i]->action=Packet::PACKET_REQUEST;
                inGameClients[i]->send<<inGameClients[i]->family<<inGameClients[i]->action<<visibleplayers.size();
                std::string str;
                str=std::to_string(inGameClients[i]->ClientID);
                for( int x=0;x<visibleplayers.size();++x)
                {
                    if(visibleplayers[x]!=inGameClients[visibleplayers[x]]->ClientID) /// tutaj program serwer sie wysypuje po wejsciu 2 gracza(sprawdzenia warunku)
                    inGameClients[i]->send<<inGameClients[x]->Char.Name<<visibleplayers[visibleplayers[x]]<<inGameClients[visibleplayers[x]]->Char.X<<inGameClients[visibleplayers[x]]->Char.Y;
                    str+=" ";
                    str+=inGameClients[visibleplayers[x]]->Char.Name;
                    str+=" ";
                    str+=std::to_string(inGameClients[visibleplayers[x]]->Char.X);
                    str+= " ";
                    str+=std::to_string(inGameClients[visibleplayers[x]]->Char.Y);
                }
                if(inGameClients[i]->Send()==true)
                {
                    visibleplayers.clear();
                    inGameClients[i]->SMsg(str.c_str());
                }
            }
        }
    }
}


@edit, juz wiem dlaczego :v

i kolejne pytanie a raczej prosba o objasnienie bo nie wiem za bardzo jak mam to sieknac, w jaki sposob zrobic by dla kazdego klienta serwer sprawdzil i wyslal te informacje raz?
« Ostatnia zmiana: Maj 29, 2014, 21:13:06 wysłana przez Psiryj »

Offline Psiryj

  • Użytkownik

# Maj 29, 2014, 21:51:05
sory za double post, ale coz : D, pojawil sie tez problem z zamuleniem serwera, gdy na 3 postaciach sobie testuje serwer, chodzac jedna postacia przed dluzszy czas serwer nie wyrabia co skutkuje zamuleniem wszystkich klientow, jak moge temu zazegnac? po za timerem ofc, tym bardziej ze gra ma byc real-time, wiec status gry musze aktualizowac u kazdego klienta jesli ktorys z nich wykona jakikolwiek ruch, protokol TCP, jakies podpowiedzi czy porady? :)

Offline remz

  • Użytkownik

# Maj 29, 2014, 22:35:58
Napisać to wszystko od nowa, bo ten kod wygląda strasznie.

Parę ciekawych linków:
http://www.gabrielgambetta.com/fpm1.html
http://gafferongames.com/networking-for-game-programmers/what-every-programmer-needs-to-know-about-game-networking/

Ogólnie chodzi o to, żeby nie wysyłać danych po każdym uaktualnieniu stanu gry, tylko robić to co jakiś czas (np. 15 razy na sekundę) a płynny ruch u klienta uzyskiwać za pomocą interpolacji. Dodatkowo wysyłanie i odbieranie pakietów nie powinno blokować serwera (co najprawdopodobniej jest problemem w twoim przypadku), więc przydałby się jakiś system do kolejkowania pakietów / odbierania pakietów w innym wątku.
« Ostatnia zmiana: Maj 29, 2014, 22:50:39 wysłana przez remz »

Offline Psiryj

  • Użytkownik

# Maj 31, 2014, 20:58:50
uzywam sfml network, na leniwo :D, i nie chce uzywac watkow za bardzo, myslalem nad gniazdami nieblokujacymi, to tylko udp czy przez tcp istnieje taka mozliwosc?

Offline remz

  • Użytkownik

# Czerwiec 01, 2014, 21:05:12
Metoda setBlocking() działa zarówno dla UDP jak i TCP i jeśli nie chcesz korzystać z wątków to 'gniazda nieblokujące' są jedynym sensownym rozwiązaniem.

Offline Xion

  • Redaktor
    • xion.log

# Czerwiec 02, 2014, 00:30:50
Metoda setBlocking() działa zarówno dla UDP jak i TCP i jeśli nie chcesz korzystać z wątków to 'gniazda nieblokujące' są jedynym sensownym rozwiązaniem.

Niezupełnie. Jednowątkowa pętla wisząca na select() też będzie działać.

Offline Psiryj

  • Użytkownik

# Czerwiec 02, 2014, 16:39:53
oki dzieki za pomoc, mam jeszcze pytanie odnosnie socketow nieblokujacych, mam je ustawic tez na selektorze? oraz jak wyglada komunikacja asynchroniczna w sfml? na forum sfml nic nie ma, wiec pewnie jednak bede musial uzyc watkow, do tego rozpackalem kod tak ze klient mi sie zapycha przy logowaniu, caly ja : D