Linux_Shines Posted May 7, 2013 Share Posted May 7, 2013 Heloł. Przepraszam za spam i za to, że piszę problem również w polskim dziale, lecz pisząc w ogólnym nie otrzymałem odpowiedzi, a potrzebuję załatwić sprawę szybko, zwłaszcza, że niżej napisany kod jest całym moim "skryptem". No i tak - nie znam się aż nadto na MySQL i LUA, ale ciągle próbuję opanować te języki. Dlatego też zdecydowałem się stworzyć prosty panel logowania na mój serwer. Niefortunnie - gdy skrypt zostaje załadowany a baza stworzona, nie mogę się zarejestrować (pokazuje się "Wystąpił nieznany błąd."). Dodam też, że po wpisaniu /debugscript 3 nie widzę nic złego. No i wpis w acl.xml też popełniłem. -- Strona serwera: local host = 'localhost' local user = 'Shiny' local password = 'test123' local db = 'baza' local tablename = 'konta' local nick = 'Pseudonim' local pass = 'Haslo' handler = mysql_connect(host, user, password, db) function CreateTableInDatabase(res) local create_database = mysql_query(handler, "CREATE TABLE IF NOT EXISTS `" ..tablename.. "` (`" ..nick.. "` varchar(255) DEFAULT NULL, `" ..pass.. "` varchar(255) DEFAULT NULL) ENGINE = MyISAM DEFAULT CHARSET = utf8;") outputDebugString("CREATE TABLE IF NOT EXISTS `" ..tablename.. "` (`" ..nick.. "` varchar(255) DEFAULT NULL, `" ..pass.. "` varchar(255) DEFAULT NULL) ENGINE = MyISAM DEFAULT CHARSET = utf8;") outputDebugString("Połączenie z bazą MySQL zostało pomyślnie zainicjowane."); end addEventHandler("onResourceStart", getRootElement(), CreateTableInDatabase) function passwordHandler(player, oldpassword, newpassword) local account = getPlayerAccount(player) if (account) then if (isGuestAccount(account)) then outputChatBox("Musisz się zalogować, aby zmienić hasło.", player) return end local playerName = getPlayerName(player) local password_check = getAccount(playerName, oldpassword) if (password_check ~= false) then if (string.len(newpassword) >= 3) then setAccountPassword(account, newpassword) triggerClientEvent(player, "hidePasswordWindow", getRootElement()) else outputChatBox("Twoje nowe hasło musi mieć długość co najmniej " ..string.len(newpassword).. " znaków!", player) end else outputChatBox("Stare hasło podane przez Ciebie jest nieprawidłowe.", player) end end end function loginHandler(player, username, password) local login = mysql_query(handler,"SELECT * FROM " ..tablename.. " WHERE " ..nick.. " = '"..mysql_escape_string(handler, user).."' AND " ..pass.. " = '"..mysql_escape_string(handler, sha256(pass)).."';") if(login ~= false) then local rows = mysql_num_rows(login) if rows == 1 then triggerClientEvent(player, "hideLoginWindow", getRootElement()) outputChatBox("Pomyślnie logujesz się na swoje konto.", player, 255, 255, 255) outputChatBox("Jeżeli chcesz zmienić swoje hasło, użyj /changepw", player) spawnPlayer(player, 0,0,3) fadeCamera(player, true) setCameraTarget(player, player) mysql_free_result(login) else triggerClientEvent (player, "unknownError", getRootElement()) end else triggerClientEvent (player, "loginWrong", getRootElement()) end end -- I think that this function isn't working, but... I've message at client trigger about "nickname was taken". function registerHandler(player, username, password) local login = mysql_query(handler,"SELECT * FROM " ..tablename.. " WHERE " ..nick.. " = '"..mysql_escape_string(handler, user).."' AND " ..pass.. " = '"..mysql_escape_string(handler, sha256(pass)).."';") if(login ~= false) then triggerClientEvent(player, "registerTaken", getRootElement()) else local rows = mysql_num_rows(login) if rows == 0 then mysql_query(handler, "INSERT INTO " ..tablename.. " (`" ..nick.. "`, `" ..pass.. "`) VALUES ('" ..username.. "', '" ..sha256(password).. "')") triggerClientEvent(player, "hideLoginWindow", getRootElement()) outputChatBox("Pomyślnie logujesz się na swoje konto.", player, 255, 255, 255) outputChatBox("Jeżeli chcesz zmienić swoje hasło, użyj /changepw", player) mysql_free_result(login) else triggerClientEvent (player, "unknownError", getRootElement()) end end end addEvent("submitChangepw", true) addEvent("submitLogin", true) addEvent("submitRegister", true) addEventHandler("submitChangepw", root, passwordHandler) addEventHandler("submitLogin", root, loginHandler) addEventHandler("submitRegister", root, registerHandler) -- Strona klienta: local localPlayer = getLocalPlayer() local playerName = getPlayerName(localPlayer) function createPasswordWindow() windowChangepw = guiCreateWindow(0.3859,0.349,0.2219,0.1628,"Zmień hasło",true) guiSetSize(windowChangepw, 165, 21) guiSetAlpha(windowChangepw,0.80000001192093) editOldpw = guiCreateEdit(110,29,165,21,"",false,windowChangepw) guiSetAlpha(editOldpw,1) guiEditSetMasked(editOldpw,true) labelOldpw = guiCreateLabel(10,29,90,21,"Stare hasło:",false,windowChangepw) guiSetAlpha(labelOldpw,1) guiLabelSetColor(labelOldpw,255,255,255) guiLabelSetVerticalAlign(labelOldpw,"center") guiLabelSetHorizontalAlign(labelOldpw,"left",false) editNewpw = guiCreateEdit(110,60,165,21,"",false,windowChangepw) guiSetAlpha(editNewpw,1) guiEditSetMasked(editNewpw,true) guiEditSetMaxLength(editNewpw,50) labelNewpw = guiCreateLabel(10,60,90,21,"Nowe hasło:",false,windowChangepw) guiSetAlpha(labelNewpw,1) guiLabelSetColor(labelNewpw,255,255,255) guiLabelSetVerticalAlign(labelNewpw,"center") guiLabelSetHorizontalAlign(labelNewpw,"left",false) buttonChangepw = guiCreateButton(10,91,265,23,"Zmień hasło",false,windowChangepw) guiSetAlpha(buttonChangepw,1) guiSetVisible(windowChangepw, false) addEventHandler("onClientGUIClick", buttonChangepw, clientSubmitChangepw, false) end function createLoginWindow() windowLogin = guiCreateWindow(0.3945,0.3646,0.2109,0.2018,"PSD",true) guiSetSize(windowLogin, 270, 155, false) guiSetAlpha(windowLogin,1) labelUsername = guiCreateLabel(10,52,59,24,"Pseudonim:",false,windowLogin) guiSetAlpha(labelUsername,1) guiLabelSetColor(labelUsername,255,255,255) guiLabelSetVerticalAlign(labelUsername,"center") guiLabelSetHorizontalAlign(labelUsername,"left",false) labelPassword = guiCreateLabel(10,86,59,24,"Hasło:",false,windowLogin) guiSetAlpha(labelPassword,1) guiLabelSetColor(labelPassword,255,255,255) guiLabelSetVerticalAlign(labelPassword,"center") guiLabelSetHorizontalAlign(labelPassword,"left",false) labelInfo = guiCreateLabel(10,26,250,17,"Proszę się zalogować, bądź zarejestrować.",false,windowLogin) guiSetAlpha(labelInfo,1) guiLabelSetColor(labelInfo,255,255,255) guiLabelSetVerticalAlign(labelInfo,"top") guiLabelSetHorizontalAlign(labelInfo,"center",false) guiSetFont(labelInfo,"default-bold-small") editUsername = guiCreateEdit(79,52,181,25,playerName,false,windowLogin) guiSetAlpha(editUsername,1) guiEditSetMaxLength(editUsername, 50) editPassword = guiCreateEdit(79,86,181,25,"",false,windowLogin) guiSetAlpha(editPassword,1) guiEditSetMasked(editPassword, true) guiEditSetMaxLength(editPassword, 50) buttonLogin = guiCreateButton(10,121,120,21,"Zaloguj się",false,windowLogin) guiSetAlpha(buttonLogin,1) buttonRegister = guiCreateButton(143,121,117,21,"Zarejestruj się",false,windowLogin) guiSetAlpha(buttonRegister,1) guiSetVisible(windowLogin, false) addEventHandler("onClientGUIClick", buttonLogin, clientSubmitLogin, false) addEventHandler("onClientGUIClick", buttonRegister, clientSubmitRegister, false) end function resourceStart() createLoginWindow() if (windowLogin ~= nil) then guiSetVisible(windowLogin, true) else outputChatBox("Wystąpił nieznany błąd.") end showCursor(true) guiSetInputEnabled(true) end function changePw() createPasswordWindow() guiSetVisible(windowChangepw, true) showCursor(true) guiSetInputEnabled(true) end function clientSubmitLogin(button, state) if button == "left" and state == "up" then local username = guiGetText(editUsername) local password = guiGetText(editPassword) if username and password then triggerServerEvent("submitLogin", getRootElement(), localPlayer, username, password) else guiSetText(labelInfo, "Wpisz nazwę użytkownika i hasło.") end end end function clientSubmitRegister(button, state) if button == "left" and state == "up" then local username = guiGetText(editUsername) local password = guiGetText(editPassword) if username and password then triggerServerEvent("submitRegister", getRootElement(), localPlayer, username, password) else guiSetText(labelInfo, "Wpisz nazwę użytkownika i hasło.") end end end function clientSubmitChangepw(button, state) if button == "left" and state == "up" then local oldpassword = guiGetText(editOldpw) local newpassword = guiGetText(editNewpw) if oldpassword and newpassword then triggerServerEvent("submitChangepw", getRootElement(), localPlayer, oldpassword, newpassword) else outputChatBox("Wpisz stare i nowe hasło.") end end end function hideLoginWindow() guiSetInputEnabled(false) guiSetVisible(windowLogin, false) showCursor(false) end function hidePasswordWindow() guiSetInputEnabled(false) guiSetVisible(windowChangepw, false) showCursor(false) end function unknownError() guiSetText(labelInfo, "Wystąpił nieznany błąd.") end function loginWrong() guiSetText(labelInfo, "Błędna nazwa użytkownika bądź hasło.") end function registerTaken() guiSetText(labelInfo, "Ta nazwa użytkownika jest już zajęta.") end addEvent("hidePasswordWindow", true) addEvent("hideLoginWindow", true) addEvent("unknownError", true) addEvent("loginWrong", true) addEvent("registerTaken", true) addEventHandler("hidePasswordWindow", getRootElement(), hidePasswordWindow) addEventHandler("hideLoginWindow", getRootElement(), hideLoginWindow) addEventHandler("unknownError", getRootElement(), unknownError) addEventHandler("loginWrong", getRootElement(), loginWrong) addEventHandler("registerTaken", getRootElement(), registerTaken) addEventHandler("onClientResourceStart", getResourceRootElement(getThisResource()), resourceStart) addCommandHandler("changepw", changePw) Mógłbym prosić o pomoc? Link to comment
dzek (varez) Posted May 7, 2013 Share Posted May 7, 2013 1) Dlaczego w zapytaniu MySQL mającym na celu sprawdzenie czy istnieje taki user - sprawdzasz login i hasło? Sam login powinieneś. 2) wg wiki mysql_query zwraca albo handler MySQLResult albo nil, ty przyrównujesz to do false (choć chyba lua rzutuje zmienne przy ~= a sprawdza dokładnie typ zmiennych przy ~== - niestety już nie pamiętam). W każdym razie, zmianna login będzie nil tylko w momencie jak zapytanie MySQL się nie powiedzie! To, że nie wybrało żadnego rekordu nie oznacza, że samo zapytanie się nie powiodło! Link to comment
Linux_Shines Posted May 7, 2013 Author Share Posted May 7, 2013 No okej, zrobiłem tak jak piszesz (tak mi się wydaje, bo zrozumiałem tylko część z tego co napisałeś, gdyż jestem jeszcze początkujący i miałem dość długą przerwę w LUA, którego wcześniej też się uczyłem) i rejestracja już działa poprawnie. Niestety - tylko rejestracja. Zalogować się dalej nie mogę, bo mam komunikat, że "wystąpił nieznany błąd". Aktualnie rejestracja wygląda tak: function registerHandler(player, username, password) local register = mysql_query(handler, "SELECT 1 FROM " ..tablename.. " WHERE " ..nick.. " = '"..mysql_escape_string(handler, user).."' AND " ..pass.. " = '"..mysql_escape_string(handler, sha256(pass)).."';") if(not register) then triggerClientEvent(player, "registerTaken", getRootElement()) else if mysql_num_rows(register) == 0 then mysql_query(handler, "INSERT INTO " ..tablename.. " (`" ..nick.. "`, `" ..pass.. "`) VALUES ('" ..username.. "', '" ..sha256(password).. "')") triggerClientEvent(player, "hideLoginWindow", getRootElement()) outputChatBox("Pomyślnie logujesz się na swoje konto.", player, 255, 255, 255) outputChatBox("Jeżeli chcesz zmienić swoje hasło, użyj /changepw", player) mysql_free_result(register) else triggerClientEvent (player, "unknownError", getRootElement()) end end end a logowanie tak: function loginHandler(player, username, password) local login = mysql_query(handler,"SELECT 1 FROM " ..tablename.. " WHERE " ..nick.. " = '"..mysql_escape_string(handler, user).."' AND " ..pass.. " = '"..mysql_escape_string(handler, sha256(pass)).."';") if(not login) then triggerClientEvent (player, "loginWrong", getRootElement()) else if mysql_num_rows(login) == 1 then triggerClientEvent(player, "hideLoginWindow", getRootElement()) outputChatBox("Pomyślnie logujesz się na swoje konto.", player, 255, 255, 255) outputChatBox("Jeżeli chcesz zmienić swoje hasło, użyj /changepw", player) spawnPlayer(player, 0,0,3) fadeCamera(player, true) setCameraTarget(player, player) mysql_free_result(login) else triggerClientEvent (player, "unknownError", getRootElement()) end end end Link to comment
dzek (varez) Posted May 7, 2013 Share Posted May 7, 2013 Dziwi mnie, szczerze dziwi, że ta rejestracja Ci działa pseudo-pseudokod, dla mnie coś takiego będzie najczytelniejsze (to jest rejestracja!) local sQuery = "SELECT .... LIMIT 1"; -- LIMIT spowoduje, ze zapytanie bedzie delikatnie szybsze w przypadku kiedy znajdziemy odpowiednik (nie trzeba bedzie przeszukiwac reszty wierszow). NIE SPRAWDZAJ TU PODANEGO HASLA! bo jak bedzie bledne, to skrypt uzna ze user nie istnieje i doda drugiego o tym samym loginie local oResult = mysql_query(sQuery); if (oResult) then -- skad tez u Ciebie ta mania robienia falszywego warunku jako pierwszego? -- zapytanie powiodlo sie, praktycznie nie ma szans zeby nie mialo (samo zapytanie musialoby miec blad skladniowy, albo brak zabezpieczenia przed sql injection) if (not mysql_num_rows(oResult)) then -- jezeli 0/false/nil (w naszym przypadku zero) -- rejestrujemy nowe konto else -- wywalamy blad, ze konto istnieje end else -- wywolanie "nieznanego bledu" end Link to comment
Linux_Shines Posted May 7, 2013 Author Share Posted May 7, 2013 Nie wiem jakim cudem działała, ale już jest okej - przestała. Co do "skad tez u Ciebie ta mania robienia falszywego warunku jako pierwszego?" - tak jakoś, zawsze zaczynam od negacji, potem sprawdzam resztę. Ale, ale, teraz mam błąd, że "Ta nazwa użytkownika jest już zajęta". Nie wiem, co jest grane, bo to jest porąbane - mówiąc szczerze. W bazie nie jestem zarejestrowany, dodatkowo podstawiłem kod wedle zaleceń z Twojego "pseudo-pseudokodu" (przy okazji, musiałem zamienić "local oResult = mysql_query(sQuery);" na "local oResult = mysql_query(handler, sQuery);", bo inaczej w konsoli miałem błąd "ERROR: script.lua:59: bad argument #1 to 'mysql_query' (mysqlHandler expected, got string)") - dalej nic, no może poza zamieszczaniem w konsoli SELECT * FROM `konta` WHERE `Pseudonim` = 'Shiny' LIMIT 1 i niczego innego więcej. Poniżej sprawca zamieszania, zrobiony wedle zaleceń: function registerHandler(player, username, password) local sQuery = "SELECT * FROM `" ..tablename.. "` WHERE `" ..nick.. "` = '"..mysql_escape_string(handler, user).."' LIMIT 1"; -- LIMIT spowoduje, ze zapytanie bedzie delikatnie szybsze w przypadku kiedy znajdziemy odpowiednik (nie trzeba bedzie przeszukiwac reszty wierszow). NIE SPRAWDZAJ TU PODANEGO HASLA! bo jak bedzie bledne, to skrypt uzna ze user nie istnieje i doda drugiego o tym samym loginie outputDebugString(sQuery) local oResult = mysql_query(handler, sQuery); if(oResult) then -- skad tez u Ciebie ta mania robienia falszywego warunku jako pierwszego? -- zapytanie powiodlo sie, praktycznie nie ma szans zeby nie mialo (samo zapytanie musialoby miec blad skladniowy, albo brak zabezpieczenia przed sql injection) if(not mysql_num_rows(oResult)) then -- jezeli 0/false/nil (w naszym przypadku zero) -- rejestrujemy nowe konto mysql_query(handler, "INSERT INTO " ..tablename.. " (`" ..nick.. "`, `" ..pass.. "`) VALUES ('" ..username.. "', '" ..sha256(password).. "')") outputDebugString(handler) -- to się nie wykonuje, bo w konsoli brak czegokolwiek triggerClientEvent(player, "hideLoginWindow", getRootElement()) outputChatBox("Pomyślnie logujesz się na swoje konto.", player, 255, 255, 255) outputChatBox("Jeżeli chcesz zmienić swoje hasło, użyj /changepw", player) mysql_free_result(oResult) else -- wywalamy blad, ze konto istnieje triggerClientEvent(player, "registerTaken", getRootElement()) end else -- wywolanie "nieznanego bledu" triggerClientEvent (player, "unknownError", getRootElement()) end end Link to comment
dzek (varez) Posted May 7, 2013 Share Posted May 7, 2013 W sumie to przerób to. Zrób: `SELECT COUNT(*) AS cnt FROM ....` potem zamiast `if (not mysql_num_rows ...` daj local row = mysql_fetch_assoc(result) if (row['cnt']==0) then -- row['cnt'] to odwolanie do elementu tablicy, nie pamietam czy tak to sie w lua robilo Link to comment
Linux_Shines Posted May 8, 2013 Author Share Posted May 8, 2013 No to zrobiłem tak jak twierdzisz, że powinno być i... dalej mam ten sam błąd ("Ta nazwa użytkownika jest już zajęta"). Podam kod, bo może robię coś źle, ale staram się zrobić wszystko tak, jak mi piszesz: function registerHandler(player, username, password) local sQuery = "SELECT COUNT(*) AS cnt FROM `" ..tablename.. "` WHERE `" ..nick.. "` = '"..mysql_escape_string(handler, user).."' LIMIT 1"; -- LIMIT spowoduje, ze zapytanie bedzie delikatnie szybsze w przypadku kiedy znajdziemy odpowiednik (nie trzeba bedzie przeszukiwac reszty wierszow). NIE SPRAWDZAJ TU PODANEGO HASLA! bo jak bedzie bledne, to skrypt uzna ze user nie istnieje i doda drugiego o tym samym loginie local oResult = mysql_query(handler, sQuery); if(oResult) then local row = mysql_fetch_assoc(oResult) if(row['cnt'] == 0) then mysql_query(handler, "INSERT INTO " ..tablename.. " (`" ..nick.. "`, `" ..pass.. "`) VALUES ('" ..username.. "', '" ..sha256(password).. "')") outputDebugString(handler) triggerClientEvent(player, "hideLoginWindow", getRootElement()) outputChatBox("Pomyślnie logujesz się na swoje konto.", player, 255, 255, 255) outputChatBox("Jeżeli chcesz zmienić swoje hasło, użyj /changepw", player) mysql_free_result(handler) else outputDebugString("Ta nazwa użytkownika jest już zajęta. Rezultat: ") outputDebugString(oResult) triggerClientEvent(player, "registerTaken", getRootElement()) end else outputDebugString("Nieznany błąd. Rezultat: ") outputDebugString(oResult) triggerClientEvent(player, "unknownError", getRootElement()) end end Zapomniałbym - serwer drukuje różne wyniki rezultatów przy próbie zarejestrowania i zalogowania: [09:58:19] INFO: Ta nazwa użytkownika jest już zajęta. Rezultat: [09:58:19] INFO: MySQL result (#18) [09:58:34] INFO: Ta nazwa użytkownika jest już zajęta. Rezultat: [09:58:34] INFO: MySQL result (#20) [09:58:34] INFO: Ta nazwa użytkownika jest już zajęta. Rezultat: [09:58:34] INFO: MySQL result (#21) [09:58:35] INFO: Ta nazwa użytkownika jest już zajęta. Rezultat: [09:58:35] INFO: MySQL result (#25) [09:58:35] INFO: Ta nazwa użytkownika jest już zajęta. Rezultat: [09:58:35] INFO: MySQL result (#26) Dodam też, że po kilku minutach (zazwyczaj 5) widzę napis "connection trouble", serwer się zawiesza i dopiero gdy wyjdę z serwera drukuje takie coś: [10:04:56] INFO: Nieznany błąd. Rezultat: [10:04:56] INFO: nil [10:04:56] INFO: Nieznany błąd. Rezultat: [10:04:56] INFO: nil [10:04:56] QUIT: Shiny left the game [Quit] Link to comment
dzek (varez) Posted May 8, 2013 Share Posted May 8, 2013 po `local row = mysql_fetch_assoc(oResult)` dostaw: outputDebugString('Ilosc wierwszy: '..row['cnt']) Możesz też już wyrzucić moje komentarze z kodu `mysql_free_result()` wywołuj poza if-em z row['cnt'] (bo inaczej czyścisz wynik tylko dla określonego warunku, w innym przypadku śmiecie zostają w pamięci). do `mysql_free_result()` podajesz wynik z zapytania, a nie handler połączenia! (czyli oResult) Co do tego wieszania się - przeanalizujemy potem. Gdzieś się coś zapętla zdaje się. Aha, i na razie testuj jedną rzecz - rejestrację. Logowanie potem. Link to comment
Linux_Shines Posted May 26, 2013 Author Share Posted May 26, 2013 Czy mógłbym poprosić o zamknięcie tego tematu, bo zacząłem korzystać z wbudowanego systemu plików MTA, które są proste i działają pewnie? Link to comment
dzek (varez) Posted May 26, 2013 Share Posted May 26, 2013 Teoretycznie nie ma celu zamykanie topiku, ale proszę bardzo Link to comment
Recommended Posts