Jump to content

Connecting to IPS Community Suite


Recommended Posts

<?php 
// PHP 
  
include 'mta_sdk.php';  // Correct path if you use a different one 
$servername = "********";  // Change these details 
$username = "********";  // Change these details 
$password = "*********";  // Change these details 
$dbname = "********";  // Change these details 
$table = "core_members"; 
$accountColumn = "name";  // change to "email" if you prefer logging in through email 
$conn = mysqli_connect($servername, $username, $password, $dbname); 
if (!$conn) { 
    mta::doReturn(false, "Connection failed: " . mysqli_connect_error()); // Account not found 
    #die("Connection failed: " . mysqli_connect_error()); 
} 
$input = mta::getInput(); 
if (isset($input[0]) && isset($input[1]) && isset($input[2]) && $input[0] == "verifyPasswords" ) { 
    $sql = "SELECT `members_pass_salt`, `members_pass_hash`, `members_id` FROM `".$table."` WHERE `".$accountColumn."`='".strtolower($input[1])."' LIMIT 1"; 
    $result = mysqli_query($conn, $sql); 
    if (mysqli_num_rows($result) > 0) { 
        $row = mysqli_fetch_assoc($result); 
        if (crypt($input[2], '$2a$13$' . $row['members_pass_salt']) == $row['members_pass_hash']) { 
            mta::doReturn(true, 0, $row, $input[3], $input[4]);  // Password correct 
        } else { 
            mta::doReturn(false, 1, false, false, $input[4]);  // Passwords don't match 
        } 
    } else { 
          mta::doReturn(false, 2, false, false, $input[4]); // Account not found 
    } 
} 
// Author: MrTasty 
?>

MTA SERVER SIDE SCRIPT - ABOVE IS PHP SCRIPT

function UserLogin(userName,Password,Checksave)
 if not (userName == "") then
        if not (Password == "") then
  callRemote("[LINK]", function(response,extra,data,Checksave,player)
    if response == true then

     triggerClientEvent(player,"loginHide",getRootElement())
     triggerClientEvent(player,"showNotification",player, "Successfully logged in!", "success")
     triggerClientEvent(player, "triggerLobby", player)
     UserData("success", data["member_id"], data["name"], player, userName, Password, Checksave);
     
    elseif extra == 1 then
     triggerClientEvent(player,"showNotification",player, "Password doesn't match!", "error")
    elseif extra == 2 then
     triggerClientEvent(player,"showNotification",player, "Account doesn't exist!", "error")
    end
            end ,"verifyPasswords", userName, Password, Checksave, source)
  else
  triggerClientEvent(source,"showNotification",source, "Please enter your password!", "error")
  end
 else
 triggerClientEvent(source,"showNotification",source, "Please enter your username!", "error")
 end 
end
addEvent("UserWantToLogin",true)
addEventHandler("UserWantToLogin",getRootElement(),UserLogin)

So whenever I try to login, it says account doesnt exist, I dont understand what I'm doing wrong? Any help?
 

@MrTasty

  • Like 1
Link to comment

Place the following file in the root of your IPS installation, where "init.php" is located.

'You should move to internally verifying the accounts.

<?php
include 'mta_sdk.php';

$_SERVER['SCRIPT_FILENAME']	= __FILE__;
$path	= '';
require_once $path . 'init.php';
\IPS\Session\Front::i();

$input = mta::getInput();
$username		= $input[0]['user'];
$password		= $input[0]['pass'];

$member = \IPS\Member::load($username, 'name');
if( !$member->member_id ) {
	mta::doReturn(
		array(
			'status' => 'FAILED',
			'msg' => 'ACCOUNT_NOT_FOUND',
		)
	);
	exit;
}

$salt = $member->members_pass_salt;
$hash = crypt($password, '$2a$13$' . $salt);

if (\IPS\Login::compareHashes($member->members_pass_hash, $hash) === TRUE) {
	mta::doReturn(
		array(
			"status" => "SUCCESS",
			"connect_status" => ( $member->members_bitoptions['validating'] ) ? 'VALIDATING' : 'SUCCESS',
			"email" => $member->email,
			"name" => $member->name,
			"connect_id" => $member->member_id,
		)
	);
}
else
{
	mta::doReturn(
		array(
			'status' => 'FAILED',
			'msg' => 'ACCOUNT_INVALID_PASSWORD',
		)
	);
}
?>

The following is a sample Lua code based on your previous code.

function UserLogin(userName,Password,Checksave)
	if not (userName == "") then
		if not (Password == "") then
			fetchRemote("[LINK]", 
				function(response,errno,player)
					if type(response) == "table" then
						if response.status == "SUCCESS" then
							triggerClientEvent(player,"loginHide",getRootElement())
							triggerClientEvent(player,"showNotification",player, "Successfully logged in!", "success")
							triggerClientEvent(player, "triggerLobby", player)
							UserData("success", data["member_id"], data["name"], player, userName, Password, Checksave)
						else
							if response.msg == "ACCOUNT_NOT_FOUND" then
								triggerClientEvent(player,"showNotification",player, "Account doesn't exist!", "error")
							elseif response.msg == "ACCOUNT_INVALID_PASSWORD" then
								triggerClientEvent(player,"showNotification",player, "Password doesn't match!", "error")
							end
						end
					elseif response == "ERROR" then
						triggerClientEvent(player,"showNotification",player, "Internal error. Please try again later. (Code "..errno..")", "error")
					end
				end
			, toJSON({user=userName, pass=Password}), false, source)
		else
			triggerClientEvent(source,"showNotification",source, "Please enter your password!", "error")
		end
	else
		triggerClientEvent(source,"showNotification",source, "Please enter your username!", "error")
	end 
end
addEvent("UserWantToLogin",true)
addEventHandler("UserWantToLogin",getRootElement(),UserLogin)

None of this is tested but I skimmed through this and I think it should work.

Edited by MrTasty
Link to comment
function UserLogin(userName,Password,Checksave)
	if not (userName == "") then
		if not (Password == "") then
			fetchRemote("http://forums.link.com/login.php", 
				function(response,errno,player)
					if type(response) == "table" then
						if response.status == "SUCCESS" then
						    triggerClientEvent(player,"loginHide",getRootElement())
					  	    triggerClientEvent(player,"showNotification",player, "Successfully logged in!", "success")
							UserData("success", data["member_id"], data["name"], player, userName, Password, Checksave)
							outputDebugString("True")
						else
							if response.msg == "ACCOUNT_NOT_FOUND" then
						     triggerClientEvent(player,"showNotification",player, "Account doesn't exist!", "error")
						outputDebugString("False")
							elseif response.msg == "ACCOUNT_INVALID_PASSWORD" then
							triggerClientEvent(player,"showNotification",player, "Password doesn't match!", "error")
							end
						end
					elseif response == "ERROR" then
						triggerClientEvent(player,"showNotification",player, "Internal error. Please try again later. (Code "..errno..")", "error")
					end
				end
			, toJSON({user=userName, pass=Password}), false, source)
		else
			triggerClientEvent(source,"showNotification",source, "Please enter your password!", "error")
		end
	else
		triggerClientEvent(source,"showNotification",source, "Please enter your username!", "error")
	end 
end
addEvent("UserWantToLogin",true)
addEventHandler("UserWantToLogin",getRootElement(),UserLogin)

function UserData(Status,UserID,uName,player,userName,Password,Checksave)
 if Status == "success" then
  if not getAccount (UserID) then
   acc = addAccount(tostring(UserID),tostring(Password))
  end
  if not getAccount(UserID,Password) then
   setAccountPassword(getAccount(UserID),Password)
  end
  local acc = getAccount ( UserID,Password)
  if(not isGuestAccount(acc)) then
   logOut(player);
  end
   logIn (player, acc, Password)
  
  setElementData(player,"getForumID",UserID)
  setElementData(player,"getForumName",uName)
 end   
end

LUA Script ^

 

<?php
include 'mta_sdk.php';

$_SERVER['SCRIPT_FILENAME']	= __FILE__;
$path	= '';
require_once $path . 'init.php';
\IPS\Session\Front::i();

$input = mta::getInput();
$username		= $input[0]['user'];
$password		= $input[0]['pass'];

$member = \IPS\Member::load($username, 'name');
if( !$member->member_id ) {
	mta::doReturn(
		array(
			'status' => 'FAILED',
			'msg' => 'ACCOUNT_NOT_FOUND',
		)
	);
	exit;
}

$salt = $member->members_pass_salt;
$hash = crypt($password, '$2a$13$' . $salt);

if (\IPS\Login::compareHashes($member->members_pass_hash, $hash) === TRUE) {
	mta::doReturn(
		array(
			"status" => "SUCCESS",
			"connect_status" => ( $member->members_bitoptions['validating'] ) ? 'VALIDATING' : 'SUCCESS',
			"email" => $member->email,
			"name" => $member->name,
			"connect_id" => $member->member_id,
		)
	);
}
else
{
	mta::doReturn(
		array(
			'status' => 'FAILED',
			'msg' => 'ACCOUNT_INVALID_PASSWORD',
		)
	);
}
?>

PHP ^

 

---

There's no output in the debug, and nothing happens, any ideas?

@MrTasty

Edited by raysmta
Link to comment
function UserLogin(userName,Password,Checksave)
  if not (userName == "") then
    if not (Password == "") then
      fetchRemote("http://forums.link.com/login.php", 
        function(response,errno,player)
          local response = fromJSON(response)
          if type(response) == "table" then
            if response.status == "SUCCESS" then
              triggerClientEvent(player,"loginHide",getRootElement())
              triggerClientEvent(player,"showNotification",player, "Successfully logged in!", "success")
              UserData("success", data["member_id"], data["name"], player, userName, Password, Checksave)
            else
              if response.msg == "ACCOUNT_NOT_FOUND" then
                triggerClientEvent(player,"showNotification",player, "Account doesn't exist!", "error")
              elseif response.msg == "ACCOUNT_INVALID_PASSWORD" then
                triggerClientEvent(player,"showNotification",player, "Password doesn't match!", "error")
              else
                outputDebugString("UNRECOGNISED RESPONSE @ "..getPlayerName(player)"'s login attempt.")
              end
            end
          elseif response == "ERROR" then
            triggerClientEvent(player,"showNotification",player, "Internal error. Please try again later. (Code "..errno..")", "error")
            outputDebugString("INTERNAL ERROR "..errno.." @ "..getPlayerName(player)"'s login attempt.")
          else
            outputDebugString("PARSING ERROR @ "..getPlayerName(player)"'s login attempt.") -- maybe the response was sent in a way other than a table, but its not an error either
          end
        end
        , toJSON({user=userName, pass=Password}), false, source)
    else
      triggerClientEvent(source,"showNotification",source, "Please enter your password!", "error")
    end
  else
    triggerClientEvent(source,"showNotification",source, "Please enter your username!", "error")
  end 
end
addEvent("UserWantToLogin",true)
addEventHandler("UserWantToLogin",getRootElement(),UserLogin)

function UserData(Status,UserID,uName,player,userName,Password,Checksave)
  if Status == "success" then
    if not getAccount (UserID) then
      acc = addAccount(tostring(UserID),tostring(Password))
    end
    if not getAccount(UserID,Password) then
      setAccountPassword(getAccount(UserID),Password)
    end
    local acc = getAccount ( UserID,Password)
    if(not isGuestAccount(acc)) then
      logOut(player);
    end
    logIn (player, acc, Password)

    setElementData(player,"getForumID",UserID)
    setElementData(player,"getForumName",uName)
  end   
end

 

Edited by MrTasty
  • Like 1
Link to comment

The code above should work. The problem was I didn't convert the JSON back to Lua (the SDK sends arrays as JSON).

(too much time passed for me to edit and append this message to the post above -.-)

 

Also, you may wish to check response.connect_status when deciding whether to grant permission to log in. This value will be either "SUCCESS" or "VALIDATING", so you may block logins from accounts which haven't confirmed their email yet.

Edited by MrTasty
  • Like 2
Link to comment
  • 1 month later...

When i add this code it outputs: outputDebugString("PARSING ERROR @ "..getPlayerName(player)"'s login attempt.")

 

Any idea how to fix this?

 

function CPlayer:OnPlayerRequestLogin(data)
  if not (data[1] == "") then
    if not (data[2] == "") then
      fetchRemote("http://forums.link.com/login.php", 
        function(response,errno,player)
          local response = fromJSON(response)
          if type(response) == "table" then
            if response.status == "SUCCESS" then
				DB:Query(function(res) 
					if #res > 0 then -- login normal
						Core:Notificate(player, "You successfully logged in. Welcome back" ..data[1].."!", "success")
						self:InitiateLogin(0x118100F1)
					elseif #res == 0 then -- login new player
						self.accountName = data[1]
						self.uid = response.connect_id
							local date = getRealTime()
							--id,name,pw,alias,date,lastseen,playtime,countrycode,lang,team,teamlvl,permlvl,warns,sanction.mutetime
							DB:Exec("INSERT INTO `Accounts` VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", self.uid, data[1], hash("sha256", data[2]), self.name, ("%s-%s-%s"):format(date.year+1900, date.month+1, date.monthday),("%s-%s-%s %s:%s:%s"):format(date.year+1900, date.month+1, date.monthday, date.hour, date.minute, date.second), 0, self:GetCountry(), "", 0, 1, 0, 0, 0)
							--id,money,exp,mapsdm,mapsdd,mapshunter,pointsdm,pointsdd,pointshunter
							DB:Exec("INSERT INTO `Players` VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)", self.uid, 0, 0, 0, 0, 0, 0, 0, 0)
							--id,chat,chat,chat,chat,carhide,carfade,drawhud,mapmusic
							DB:Exec("INSERT INTO `Settings` VALUES (?,1,1,1,1,0,1,1,1)", self.uid)
							--id,moneyspend,mapsbought,mapswon,pvpwon,spinwon,eventswon,timesjoined,dmdeaths,dmmaps,dmfinished,dmwins,dmtoptimes,ddkils,dddeaths,ddmaps,ddwins,ddwinstreak,hunterkills,hunterdeaths,hunterrockets,huntermaps,hunterwins,hunterwinstreak
							DB:Exec("INSERT INTO `PlayerStats` VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", self.uid, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
							
							self:InitiateLogin(0x118100F1)
							Core:Notificate(player, "You successfully logged in. Welcome, "..data[1].." to vigour gaming!", "success")
					end
				end, "SELECT `ID` from `Accounts` WHERE `Accountname` = ?", data[1])			
            else
              if response.msg == "ACCOUNT_NOT_FOUND" then
				Core:Notificate(player, "Account not found!", "error")
				Core:Notificate(player, "Register yourself if you don't have an account", "info")
				triggerClientEvent(player, "URAL:Response", player, 404)
              elseif response.msg == "ACCOUNT_INVALID_PASSWORD" then
				Core:Notificate(player, "Wrong account password!", "error")
				triggerClientEvent(player, "URAL:Response", player, 401)
              else
                outputDebugString("UNRECOGNISED RESPONSE @ "..getPlayerName(player)"'s login attempt.")
              end
            end
          elseif response == "ERROR" then
			Core:Notificate(player, "Internal error. Please try again later. (Code "..errno..")", "error")
            outputDebugString("INTERNAL ERROR "..errno.." @ "..getPlayerName(player)"'s login attempt.")
          else
            outputDebugString("PARSING ERROR @ "..getPlayerName(player)"'s login attempt.") -- maybe the response was sent in a way other than a table, but its not an error either
          end
        end, toJSON({user=data[1], pass=data[2]}), false, source)
    else
		Core:Notificate(self.obj, "Enter your password!", "error")
		triggerClientEvent(self.obj, "URAL:Response", self.obj, 401)
    end
  else
	Core:Notificate(self.obj, "Enter your username!", "error")
	triggerClientEvent(self.obj, "URAL:Response", self.obj, 401)
  end
end

 

Edited by Ruzy
Link to comment

Change lines 4-5 and line 42 to

function(response_,errno,player) -- line 4
  local response = fromJSON(response_) -- line 5
  -- ...
  elseif response_ == "ERROR" then --line 42
  -- ...
end

This should result in the code correctly informing you of the HTTP error code, and thus no valid response was given (i.e. 500 error)

If it still comes up as a parsing error, that means the website's response is incorrectly formatted.

Edited by MrTasty
Link to comment

It's still comes up as parsing error. mta_sdk.php is installed too and this is the login.php code:

 

<?php
include 'mta_sdk.php';

$_SERVER['SCRIPT_FILENAME']	= __FILE__;
$path	= '';
require_once $path . 'init.php';
\IPS\Session\Front::i();

$input = mta::getInput();
$username		= $input[0]['user'];
$password		= $input[0]['pass'];

$member = \IPS\Member::load($username, 'name');
if( !$member->member_id ) {
	mta::doReturn(
		array(
			'status' => 'FAILED',
			'msg' => 'ACCOUNT_NOT_FOUND',
		)
	);
	exit;
}

$salt = $member->members_pass_salt;
$hash = crypt($password, '$2a$13$' . $salt);

if (\IPS\Login::compareHashes($member->members_pass_hash, $hash) === TRUE) {
	mta::doReturn(
		array(
			"status" => "SUCCESS",
			"connect_status" => ( $member->members_bitoptions['validating'] ) ? 'VALIDATING' : 'SUCCESS',
			"email" => $member->email,
			"name" => $member->name,
			"connect_id" => $member->member_id,
		)
	);
}
else
{
	mta::doReturn(
		array(
			'status' => 'FAILED',
			'msg' => 'ACCOUNT_INVALID_PASSWORD',
		)
	);
}
?>

 

Link to comment
fetchRemote("http://forums.link.com/login.php", -- of course use your own URL here
  function(response_,errno,player)
    outputDebugString(tostring(response_))
  end
, toJSON({user="any username", pass="and any password"}), false)

Try running this, preferably with runcode through the HTTP interface (usually at http://<your server ip>:22003/runcode/ unless you changed the HTTP port) and check for the response - it should be a JSON string.

Edited by MrTasty
Link to comment
[2017-07-23 06:36:21] INFO: <br />
<b>Deprecated</b>:  Automatically populating $HTTP_RAW_POST_DATA is deprecated and will be removed in a future version. To avoid this warning set 'always_populate_raw_post_data' to '-1' in php.ini and use the php://input stream instead. in <b>Unknown</b> on line <b>0</b><br />
<br />
<b>Warning</b>:  Cannot modify header information - headers already sent in <b>Unknown</b> on line <b>0</b><br />
[{"status":"SUCCESS","connect_status":"SUCCESS","email":"****@gmail.com","name":"Ruzy","connect_id":1}]

 

Edited by Ruzy
Link to comment

Aha. Parsing error - the response from the site, although it contains the JSON code, it is not the JSON code on its own. You should do something about those error messages so that the only response from the server is, is the JSON string (what you see on line 5)

The first error can be corrected by changing php.ini as instructed, the other error is a result of the first error being written up before the forum code was initialised (which includes setting headers, I guess) and that causes an error - setting headers when something was already outputted (the previous error).

Edited by MrTasty
  • Like 1
Link to comment
  • 6 months later...

BUMP

It is unable to get the datas, e.g. data["member_id"], data["name"], it worked when I used callRemote, but fails to work now since it is not getting the data through the arguments, any ideas how I can fix this?

function UserLogin(userName,Password,Checksave)
  if not (userName == "") then
    if not (Password == "") then
      fetchRemote("http://forums.link.com/login.php", 
        function(response,errno,player)
          local response = fromJSON(response)
          if type(response) == "table" then
            if response.status == "SUCCESS" then
              triggerClientEvent(player,"loginHide",getRootElement())
              triggerClientEvent(player,"showNotification",player, "Successfully logged in!", "success")
              UserData("success", data["member_id"], data["name"], player, userName, Password, Checksave)
            else
              if response.msg == "ACCOUNT_NOT_FOUND" then
                triggerClientEvent(player,"showNotification",player, "Account doesn't exist!", "error")
              elseif response.msg == "ACCOUNT_INVALID_PASSWORD" then
                triggerClientEvent(player,"showNotification",player, "Password doesn't match!", "error")
              else
                outputDebugString("UNRECOGNISED RESPONSE @ "..getPlayerName(player)"'s login attempt.")
              end
            end
          elseif response == "ERROR" then
            triggerClientEvent(player,"showNotification",player, "Internal error. Please try again later. (Code "..errno..")", "error")
            outputDebugString("INTERNAL ERROR "..errno.." @ "..getPlayerName(player)"'s login attempt.")
          else
            outputDebugString("PARSING ERROR @ "..getPlayerName(player)"'s login attempt.") -- maybe the response was sent in a way other than a table, but its not an error either
          end
        end
        , toJSON({user=userName, pass=Password}), false, source)
    else
      triggerClientEvent(source,"showNotification",source, "Please enter your password!", "error")
    end
  else
    triggerClientEvent(source,"showNotification",source, "Please enter your username!", "error")
  end 
end
addEvent("UserWantToLogin",true)
addEventHandler("UserWantToLogin",getRootElement(),UserLogin)

function UserData(Status,UserID,uName,player,userName,Password,Checksave)
  if Status == "success" then
    if not getAccount (UserID) then
      acc = addAccount(tostring(UserID),tostring(Password))
    end
    if not getAccount(UserID,Password) then
      setAccountPassword(getAccount(UserID),Password)
    end
    local acc = getAccount ( UserID,Password)
    if(not isGuestAccount(acc)) then
      logOut(player);
    end
    logIn (player, acc, Password)

    setElementData(player,"getForumID",UserID)
    setElementData(player,"getForumName",uName)
  end   
end

 

Edited by ℓιgнт
Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

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