Jump to content

[Błąd/MySQL] Panel rejestracji/logowania nie chce działać


Recommended Posts

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

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

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

Dziwi mnie, szczerze dziwi, że ta rejestracja Ci działa o.O

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

Nie wiem jakim cudem działała, ale już jest okej - przestała. :lol:

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

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

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

po `local row = mysql_fetch_assoc(oResult)` dostaw:

outputDebugString('Ilosc wierwszy: '..row['cnt']) 

Możesz też już wyrzucić moje komentarze z kodu :P

`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
  • 3 weeks later...
Guest
This topic is now closed to further replies.
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...