Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [php][mysql] update bazy 24h co pare sekund
Forum PHP.pl > Forum > PHP
prz3kus
Witam mam pytanie trapiące moją ciekawość, jak w grach online robią przyrost surowców może coś sie dowiem czego nie wiem

Próba 1:
Wrzuciłem wykonywanie skryptu do crontaba jenak ma to wade wykonuje się co minuta niby ok ale wizualnie do kitu no i jak wiemy w tych grach często liczą się sekundy
Próba 2:
Użyłem biblioteki jquery i odświeżam sobie stronkę zapisując aktualną datę do bazy powiedzmy co 15s. Wizualnie wszytko OK jednak wada jest taka ze wylogowując się surowce nie rosną , chodź po kolejnym lgowaniu przyrost się wyrównuje to jednak nie ma to sensu.

Próba3:
Strona odświeżająca się co 15s jednak trzymać ciągle on-line mało stabilne rozwiązanie.

Odpowiadając na trapiące pytania nie piszę gry jednak jestem bardzo ciekawy jak to jest rozwiązywane w tych grach on-line.

Pozdrawiam
prz3kus
r4xz
może ajax? (ale głowy niedaję winksmiley.jpg
Void
Było to już chyba kilka razy smile.gif
Przy odświeżaniu strony przez użytkownika sprawdzany jest ostatni stan surowców zapisany w bazie oraz czas ostatniej aktywności użytkownika. Czas ten jest odejmowany od aktualnej godziny i na jego podstawie przeliczane jest ile surowców powinno zostać wydobytych przez ten czas (uwzględnia się przy tym poziom odpowiednich budynków, bonusów itp.). Podobnie dzieje się ze wszystkimi innymi danymi użytkownika (sprawdzanie zakończenia trwania jakichś misji, budowy itp.) i zaktualizowane dane wraz z czasem zapisywane są w bazie. Można do tego dodać javascript, w którym na bieżąco przelicza się i zmienia wartości pól wyświetlających stan surowców (jednak w bazie nic się nie zmienia do czasu odświeżenia strony) - daje to wrażenie nieustannej pracy gry. Po wylogowaniu rzeczywiście na koncie nic się nie dzieje, do czasu ponownego zalogowania użytkownika LUB wykonania na użytkowniku jakiejś akcji przez innego użytkownika (np. szpiegowanie - musi przecież dostarczyć aktualnych informacji o użytkowniku).
prz3kus
Aha czyli każda akcja np. wysłania ataku czy szpiegowania wykonuje update o tym nie pomyślałem (to dlatego banują w pewnej grze za robienie zbyt wielu akcji na jednym koncie w jednym czasie:) dzięki Void już myślałem że jestem jakiś inny i jest jakiś super skrypt w stylu ajaxa działający po stronie serwera a tu wystarczy mieć wyobraźnie.

Sorki jeżeli takie tematy już były nie znalazłem wcześniej odpowiedzi a dzięki temu będe spał spokojniej smile.gif
Jeszcze raz dzięki Void



Po przemysleniu mam jeszcze jedną lukę w umyśle postaram sie wyjaśnieć na przykładzie:

-Nie ma mnie na koncie surka rosnie
-Ktoś wysłał zwiad czy tam atak trwa on z 30min wiec koles wyszedl z kona. Nie ma kto odswiezyc danych a jednak akcja się musiała wykonać bo powiedzmy pozostały jakieś szczątki po bitwie.

I co wy na to? smile.gif
kfc4
Rozpoczynając atak już wszystko wyliczasz. Tylko nie podajesz tych informacji dopóki teraz nie będzie później niż czas który wyliczyłeś jako koniec bitwy.
prz3kus
Cytat(kfc4 @ 4.09.2009, 18:03:23 ) *
Rozpoczynając atak już wszystko wyliczasz. Tylko nie podajesz tych informacji dopóki teraz nie będzie później niż czas który wyliczyłeś jako koniec bitwy.


No tak to już na pewno nie jest, po pierwsze nie rozwiązuje to moje pytanie jak sie wykonuje update pod koniec akcji a po dwa nie może tak byc bo zawsze może ktoś inny wcześniej dotrzeć i sie wyliczenia zmienią.
thek
A pomyślałeś o czymś w stylu sleep() ? Z tego co wnioskuję to prawdopodobnie grasz w Delirium winksmiley.jpg Walisz sleep na ileś sekund lub ustawiasz wręcz określoną godzinę poprzez time_sleep_until() i zapominasz.
franki01
Tworzysz klasę/funkcję (użyję przykładu klasy) User_Updater. Robisz metody odpowiedzialne za aktualizowanie surowców - User_Updater::minerals($userID), odświeżanie wysłanych skanów/ataków - UserUpdater::attacks($userID) itd. W tych metodach piszesz skrypty obliczające aktualną ilość surowców (sposób podany jest wyżej), sprawdzających i przetwarzających ataki, które się skończyły jakiś czas temu i cokolwiek dusza zapragnie. Zawsze, gdy jest potrzebna aktualna ilość surowców gracza, stan jego floty albo ilość aktualnie wyprodukowanych jednostek do walki, wywołujesz te metody. Muszą być napisane przemyślanie i z głową, żeby nie było sytuacji, gdy po ataku gracz zabierze tyle surowców, ile jest w tym momencie, a nie godzinę temu, kiedy atak się odbył. Jest wiele innych sposób na rozwiązanie problemu. Mi akurat takie coś przyszło do głowy.

EDIT:
Cytat(thek @ 4.09.2009, 21:51:25 ) *
A pomyślałeś o czymś w stylu sleep() ? Z tego co wnioskuję to prawdopodobnie grasz w Delirium winksmiley.jpg Walisz sleep na ileś sekund lub ustawiasz wręcz określoną godzinę poprzez time_sleep_until() i zapominasz.

sleep() usypia cały interpretator PHP, żaden inny skrypt w tym czasie nie będzie się wykonywał.
thek
To chyba troche dziwnie u mnie na localu działał jak widzę winksmiley.jpg Bo puszczałem skrypt na kilkanaście minut, dawałem ignore_user_abort, set_time_limit(0), logowałem do pliku każde wybudzenie by sprawdzić czy aby działa i dawałem sleep(20) a robiłem sobie dalej na localu co chciałem. A przecież wtedy każde wywołanie jakiejkolwiek strony powinno leżeć do czasu obudzenia interpretera według tego co mówisz. Tymczasem wsio śmigało prawidłowo. Albo więc działa to inaczej niż mówisz, albo ja mam cudowny interpreter PHP. Jak dla mnie bowiem to zatrzymywane jest działanie skryptu, a nie całego interpretera.
prz3kus
Czyli funkcja time_sleep_until() potrafi wykonać samodzielnie skrypt php po stronie serwera bez odświeżania strony?questionmark.gifquestionmark.gifquestionmark.gifquestionmark.gifquestionmark.gif
Przyznaje się bez bicia że nigdy jej nie używałem chyab czas na kawalek lektury z google chyba że coś źle rozumuje.
thek
Funkcja sleep(X) zatrzymuje wykonywanie skryptu na X sekund, zaś time_sleep_until(X) zatrzymuje go do czasu X określonego jako timestamp. Ja używałem sleep(20) w swoim skrypcie w rekurencji na zasadzie:
- ustaw time limit, ignore user abort i parę innych,
- zrób coś,
- sleep(20),
- wywołaj pewien kontroler,
- wywołaj sam siebie,
- exit.

Dzięki temu skrypt mógł działać w nieskończoność. Jego zatrzymanie było uzależnione od "zrób coś", gdyż był tam warunek stopu. Gdyby nie to, to skrypt był niemal nie do zatrzymania, bo co chwilę tworzył swoje własne wątki i musiałbyś mieć dostęp do shella by to próbować skillować. Dlatego najpierw gruntownie go testowałem na localhoście. Służy mi on do wysyłki maili na jednym z serwisów. Mam jego uruchomienie w cronie, więc pełen automat o jakim można zapomnieć że chodzi winksmiley.jpg Sam skrypt jest wstrzymany na 20 sekund przy każdym "wątku", ale w żaden sposób nie wpływa na cały interpreter php. Gdyby tak było to serwis leżałby każdej nocy na długi czas.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.