[ROZWIĄZANE] Ilość znaków w stringu, usuwa...
Najlepsza odpowiedź GwynBleidD 06.09.2014 08:52
Sniper Elite
05.09.2014
Witam.
Próbuję wykorzystać poradnik GwynBleidD http://amxx.pl/topic...in-baza-danych/
aby stworzyć lepszy zapis mysql na moim serwerze.
Mam teraz problem z wykonaniem taska który automatycznie zapisuje doświadczenie do bazy. Otóż nie wiem jak w końcowym wpisie usunąć przecinek. Może i błache, ale nigdy się tym nie zajmowałem i nie mam pomysłu jak to zrobić.
Moje pytania:
- jak usunąć x ostatnich/pierwszych znaków w stringu?
- jak zwrócić ilość znaków w stringu (nie chodzi mi tu o rozmiar maksymalny tablicy, ale o to ile znaków jest tam przechowywanych)?
Dzięki za pomoc.
Puchate
05.09.2014
Operacje na tablicach w PAWNie niestety nie sa przyjemne
- jak usunąć x ostatnich/pierwszych znaków w stringu?
Kodem na usuniecie znaku na pozycji X moze byc cos takiego - wklepane w notatniku i nietestowane, wiec moze nie dzialac
stock removeChar(string[], pos) { new len = strlen(string) if(pos > len) return replace(string[pos], len - pos, string[pos], "") }
strlen
- jak zwrócić ilość znaków w stringu (nie chodzi mi tu o rozmiar maksymalny tablicy, ale o to ile znaków jest tam przechowywanych)?
Sniper Elite
05.09.2014
Zrobiłem sobie funkcje testową która ma za zadanie wypisać zapytanie jakie jest wysyłane do bazy danych. Oto ona:
public WypiszZapytanie() { new name[48] for(new id = 1; id <= g_maxplayers; id++) { if(!is_user_connected(id) || !klasa_gracza[id]) continue; get_user_name(id, name, 47); replace_all(name, 47, "'", "\'"); giLen += formatex(ZapiszExp[giLen], giMax-giLen," ('%s',%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d),", name,klasa_gracza[id],poziom_gracza[id],doswiadczenie_gracza[id],inteligencja_gracza[id],zdrowie_gracza[id],wytrzymalosc_gracza[id],kondycja_gracza[id],grawitacja_gracza[id],niewidzialnosc_gracza[id],celneoko_gracza[id],moc_gracza1[id],moc_gracza2[id],moc_gracza3[id],quest_dzienny[id][0],klasa_pro[id],monety[id],honor[id],s_aw[id],s_apw[id],s_pas[id],quest_gracza[id],ile_juz[id],ile_wykonano[id],quest_dzienny[id][1],quest_dzienny[id][2]) name = "" } new DlugoscStringa = strlen(ZapiszExp) replace(ZapiszExp[DlugoscStringa-1], DlugoscStringa, ZapiszExp[DlugoscStringa-1], "") giLen += formatex(ZapiszExp[giLen], giMax-giLen," ON DUPLICATE KEY UPDATE `lvl`=VALUES(`lvl`), `exp`=VALUES(`exp`), `int`=VALUES(`int`), `zdr`=VALUES(`zdr`), `wyt`=VALUES(`wyt`), `kon`=VALUES(`kon`), `gra`=VALUES(`gra`), `nie`=VALUES(`nie`), `cel`=VALUES(`cel`), `moc1`=VALUES(`moc1`), `moc2`=VALUES(`moc2`), `moc3`=VALUES(`moc3`), `m_dzien`=VALUES(`m_dzien`), `pro`=VALUES(`pro`), ") giLen += formatex(ZapiszExp[giLen], giMax-giLen,"`zlo`=VALUES(`zlo`), `hon`=VALUES(`hon`), `s_aw`=VALUES(`s_aw`), `s_apw`=VALUES(`s_apw`), `s_pas`=VALUES(`s_pas`), `q_gracza`=VALUES(`q_gracza`), `ile_juz`=VALUES(`ile_juz`), `ile_wyk`=VALUES(`ile_wyk`), `ile_qd1`=VALUES(`ile_qd1`), `ile_qd2`=VALUES(`ile_qd2`)") log_to_file("test_zapis.log", "%s", ZapiszExp); ZapiszExp = "" giLen=0, giMax=sizeof(ZapiszExp) - 1 giLen += formatex(ZapiszExp[giLen], giMax-giLen,"INSERT INTO `cod_tablet` (`nick`,`klasa`,`lvl`,`exp`,`int`,`zdr`,`wyt`,`kon`,`gra`,`nie`,`cel`,`moc1`,`moc2`,`moc3`,`m_dzien`,`pro`,`zlo`,`hon`,`s_aw`,`s_apw`,`s_pas`,`q_gracza`,`ile_juz`,`ile_wyk`,`ile_qd1`,`ile_qd2`) VALUES") return PLUGIN_CONTINUE; }
Pokombinowałem trochę i udałosię usunąć ten przecinek, ale powstał kolejny problem.
Nie dodaje kolejnych linijek po użyciu funkcji replace tj.
giLen += formatex(ZapiszExp[giLen], giMax-giLen," ON DUPLICATE KEY UPDATE `lvl`=VALUES(`lvl`), `exp`=VALUES(`exp`), `int`=VALUES(`int`), `zdr`=VALUES(`zdr`), `wyt`=VALUES(`wyt`), `kon`=VALUES(`kon`), `gra`=VALUES(`gra`), `nie`=VALUES(`nie`), `cel`=VALUES(`cel`), `moc1`=VALUES(`moc1`), `moc2`=VALUES(`moc2`), `moc3`=VALUES(`moc3`), `m_dzien`=VALUES(`m_dzien`), `pro`=VALUES(`pro`), ") giLen += formatex(ZapiszExp[giLen], giMax-giLen,"`zlo`=VALUES(`zlo`), `hon`=VALUES(`hon`), `s_aw`=VALUES(`s_aw`), `s_apw`=VALUES(`s_apw`), `s_pas`=VALUES(`s_pas`), `q_gracza`=VALUES(`q_gracza`), `ile_juz`=VALUES(`ile_juz`), `ile_wyk`=VALUES(`ile_wyk`), `ile_qd1`=VALUES(`ile_qd1`), `ile_qd2`=VALUES(`ile_qd2`)")
I zapytanie wygląda tak:
INSERT INTO `cod_tablet` (`nick`,`klasa`,`lvl`,`exp`,`int`,`zdr`,`wyt`,`kon`,`gra`,`nie`,`cel`,`moc1`,`moc2`,`moc3`,`m_dzien`,`pro`,`zlo`,`hon`,`s_aw`,`s_apw`,`s_pas`,`q_gracza`,`ile_juz`,`ile_wyk`,`ile_qd1`,`ile_qd2`) VALUES ('Sniper Elite',2,2,120,0,2,0,0,0,0,0,0,0,0,-1,0,0,0,0,0,1,-1,0,0,0,0)
Wiesz może czemu?
GwynBleidD
05.09.2014
2. po replace giLen powinno zostać zaktualizowane, a tego nie robisz. string kurczy się o 1 znak, przez co dalszy ciąg napisu jest za nullem, zostanie on więc zignorowany.
replace powinien zwrócić nową długość, tak jak inne funkcje operujące na stringach. Jeśli zwraca, to po prostu dodaj przed nim giLen =
jeśli nie zwraca, po prostu odejmij od giLen 1 po użyciu replace.
Sniper Elite
05.09.2014
Zrobiłem, działa
Zrobię większą tablicę (na 64 wpisy). Gracze będą do niej dopisywani gdy rozłączą się z serwerem lub zmienią klasę + dodatkowo sprawdzę czy nie ma już wpisu z tym samym nickiem i nr klasy (co by się nie dublowało)
Funkcję zapisu expa do bazy danych będę wywoływał co 2-3 min + dodatkowo w plugin_end.
GwynBleidD
05.09.2014
Puchate
05.09.2014
Jako że używasz MySQL'a to mam radę jak lepiej zbudować takie zapytanie.
Teraz budujesz takie zapytanie
INSERT INTO `tabela` (`wartosc1`, `wartosc2`) VALUES ('123', '123') ON DUPLICATE KEY UPDATE `wartosc1` = 'hihihi', `wartosc2` = 'blabla'
Żebyś nie miał za łatwo to pokażę Ci na przykładzie PHP jak można ułatwić budowanie takiego zapytania do MySQL, przy założeniu ze aktualizujesz to samo co dodajesz.
// obecnie zapytanie budujesz z 3 (a nawet 4 w PAWNIE) kawalkow $insert = "INSERT INTO `tabela` (`wartosc1`, `wartosc2`) VALUES"; $values = "('wartosc1', 'wartosc2')"; $duplicate = "ON DUPLICATE KEY UPDATE `wartosc1` = 'hihihi', `wartosc2` = 'blabla'"; // a pozniej laczysz je w calosc i masz gotowe zapytanie $sql = implode(" ", array($insert, $values, $duplicate)); // // A MOZNA ZROBIC TO LATWIEJ :) // $insert = "INSERT INTO `tabela` SET"; $values = "`wartosc1` = 'hihihi', `wartosc2` = 'blabla'"; $sql = implode(" ", array($insert, $values, "ON DUPLICATE KEY UPDATE", $values));
O ile w PHP budowa takiego zapytania w obu wersjach jest łatwa, o tyle w pawnie... sam widzisz
Użytkownik Puchate edytował ten post 05.09.2014 19:47
GwynBleidD
05.09.2014
Puchate
05.09.2014
przy założeniu ze aktualizujesz to samo co dodajesz.
Zauważ róźnicę w "`wartosc1` = 'hihihi'" i "`wartosc1` = VALUES(`wartosc1`)" przy wykonywaniu zapytania dla kilku rekordów na raz. Poza tym sam SET już taką operację utrudnia.
Spójrz w zapytanie z pluginu. Przy pisaniu zapytania wstałem bzdetne dane, niekoniecznie pasujące do omawianego sposobu.
Sniper Elite
05.09.2014
Daj później IP serwera, postaram się to zepsuć i pokażę Ci dlaczego sprawdzanie ile graczy już jest do listy zapisanych jest niezbędne. Ewentualnie możesz porównywać długość zapytania.
Wiem o co biega i zrobiłem zabezpieczenie, które pozwoli maksymalnie na 64 wpisy.
Miałem jeszcze zapytać o asynchroniczne i synchroniczne zapytanie do bazy danych. Jakiego używa się w plugin end i jak ono wygląda?
GwynBleidD
05.09.2014
Sniper Elite
06.09.2014
Dzięki
Zrobiłem cały zapis i jak na razie sprawuje się nieźle (ip masz w sygnaturze jak chcesz zepsuć - cod mod)
Może niedługo napiszę własny poradnik jak zrobić takie zapis od podstaw.
Można zamknąć.