AlliedModders

AlliedModders (https://forums.alliedmods.net/index.php)
-   Snippets and Tutorials (https://forums.alliedmods.net/forumdisplay.php?f=112)
-   -   [SNIPPET] Discord / Steam link & tracker (https://forums.alliedmods.net/showthread.php?t=329861)

Mitchell 01-10-2021 14:03

[SNIPPET] Discord / Steam link & tracker
 
Most other scripts that interact with discord that attempt to store players steamids in a database require interaction of the user to be in a server typing in chat or typing in the discord server etc.
This snippet uses a php page and a discord application (which can be a bot also) that reads the connections list of the user for the steam64. It requires the user to have their steam connected to their discord account.

This script is possibly old and may need minor edits

Learn how to create a discord bot account: https://discordpy.readthedocs.io/en/latest/discord.html

Database used in snippet:
Code:

CREATE TABLE IF NOT EXISTS `discord_connections` (
  `userid` varchar(64) NOT NULL,
  `type` varchar(32) NOT NULL,
  `id` varchar(64) NOT NULL,
  `name` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_mysql500_ci DEFAULT NULL,
  `added` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `updated` datetime DEFAULT NULL
);

php files:

Config file:
PHP Code:

<?php
//Database to store player's connections:
$DBHOST "localhost";
$DBPORT 3306;
$DBNAME "---";
$DBUSERNAME "---";
$DBPASSWORD "---";

//This should automatically point to the link.php script when included. If for some reason your Discord Application's redirect URI is different then override this.
$CURRENT_PAGE "https://$_SERVER[HTTP_HOST]$_SERVER[PHP_SELF]";
//$CURRENT_PAGE = "https://some.site/link.php" //uncomment this to override the redirect uri to this.

//Discord App Stuff:
$DISCORDAPP_CLIENT_ID "-----";
$DISCORDAPP_CLIENT_SECRET "-----";
$DISCORDAPP_REDIRECT_URI urlencode($CURRENT_PAGE);

//Probably don't need to edit this.
$DISCORDAPP_API_ENDPOINT "https://discordapp.com/api";
?>

Link page (the page users will open)
PHP Code:

<?php
//Create unique state session, to prevent people from just calling this page indirectly without going through the process first.
session_start();
include 
'discord_config.php';
if(!isset(
$_GET['code']) || !isset($_SESSION["discord_state"])) {
    
//Code or session does not exist, we need to refetch.
    
$characters '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
    
$charactersLength strlen($characters);
    
$randomString '';
    for (
$i 0$i 24$i++) {
        
$randomString .= $characters[rand(0$charactersLength 1)];
    }
    
$_SESSION["discord_state"] = $randomString;
    
header("Location: https://discordapp.com/api/oauth2/authorize?client_id=".$DISCORDAPP_CLIENT_ID."&redirect_uri=".$DISCORDAPP_REDIRECT_URI."&response_type=code&scope=identify%20connections&state=".$randomString);
    die();
    
//Redirect them out to the authorize link.
}
//echo "Code: " . $_GET['code'] . "<br/>";
//echo "Session: " . $_SESSION["discord_state"] . "<br/>";
unset($_SESSION['discord_state']);
//Check if the state string matches the session on.
if(!isset($_GET["state"])) {
    
//State doesn't exist, not sure how, possibly changed the url?
    
echo "State parameter does not exist!";
    die();
}
//echo "State: " . $_GET["state"] . "<br/>";
//echo "Redirect URI: " . $DISCORDAPP_REDIRECT_URI . "<br/>";

//So now we need to convert the code into an OAuth2 session.
$fields = array(
    
'client_id' => urlencode($DISCORDAPP_CLIENT_ID),
    
'client_secret' => urlencode($DISCORDAPP_CLIENT_SECRET),
    
'grant_type' => urlencode('authorization_code'),
    
'code' => urlencode($_GET['code']),
    
'redirect_uri' => $DISCORDAPP_REDIRECT_URI,
    
'scope' => urlencode('identify connections')
);
//url-ify the data for the POST
foreach($fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; }
rtrim($fields_string'&');

$ch curl_init();
curl_setopt($ch,CURLOPT_URL$DISCORDAPP_API_ENDPOINT '/oauth2/token');
curl_setopt($ch,CURLOPT_POSTcount($fields));
curl_setopt($ch,CURLOPT_POSTFIELDS$fields_string);
curl_setopt($ch,CURLOPT_RETURNTRANSFERTRUE);
$result curl_exec($ch);
$responseCode curl_getinfo($chCURLINFO_HTTP_CODE);
$errorcURL curl_error($ch);
$errorNum curl_errno($ch);
curl_close($ch);
if(
$errorNum || $responseCode != "200") {
    print 
"cURL1 - Result: " $result "<br/>";
    print 
"cURL1 - Response: " $responseCode "<br/>";
    print 
"cURL1 - cURL Error: " $errorcURL "<br/>";
    die();
}
unset(
$ch);
//Parse oAuth response to object.
$data json_decode($resultTRUE);
//Check if "error" exists and then die.
if(isset($data['error'])) {
    
//There was an error!
    
echo "cURL1 - Error Type: " $data['error'] . "<br/>";
    echo 
"cURL1 - Error Message: " $data['error_description'] . "<br/>";
    die();
}
$AUTH_HEADER 'authorization: Bearer ' $data['access_token'];
//print $AUTH_HEADER . '<br/>';

//Get the client's connection list: (Done before the client's userid due to requiring steam in the connections before proceeding)
$ch curl_init();
curl_setopt_array($ch, array(
  
CURLOPT_URL => $DISCORDAPP_API_ENDPOINT "/users/@me/connections",
  
CURLOPT_RETURNTRANSFER => true,
  
CURLOPT_ENCODING => "",
  
CURLOPT_MAXREDIRS => 10,
  
CURLOPT_TIMEOUT => 30,
  
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  
CURLOPT_CUSTOMREQUEST => "GET",
  
CURLOPT_HTTPHEADER => array(
    
$AUTH_HEADER,
    
"cache-control: no-cache"
  
),
));
$result curl_exec($ch);
$responseCode curl_getinfo($chCURLINFO_HTTP_CODE);
$errorcURL curl_error($ch);
$errorNum curl_errno($ch);
curl_close($ch);
if(
$errorNum || $responseCode != "200") {
    print 
"cURL2 - Result: " $result "<br/>";
    print 
"cURL2 - Response: " $responseCode "<br/>";
    print 
"cURL2 - cURL Error: " $errorcURL "<br/>";
    die();
}
//Parse oAuth response to object.
$data json_decode($resultTRUE);
//Check if "error" exists and then die.
if(isset($data['error'])) {
    
//There was an error!
    
echo "cURL2 - Error Type: " $data['error'] . "<br/>";
    echo 
"cURL2 - Error Message: " $data['error_description'] . "<br/>";
    echo 
"cURL2 - Result: " $result "<br/>";
    die();
}
//echo $result . "<br/>";

$hasSteamConnection FALSE;
$steam64 "-1";
$steamName "<unknown>";
foreach(
$data as $item) { //foreach element in $arr
    
if(isset($item['type']) && $item['type'] == "steam") {
        
$hasSteamConnection TRUE;
        
$steam64 $item['id'];
        
$steamName $item['name'];
    }
}

if(!
$hasSteamConnection) {
    echo 
"You haven't connected steam to your discord account, please do so first. <br/>";
    die();
}

//Get the current User's ID and name stuff:
$ch curl_init();
curl_setopt_array($ch, array(
  
CURLOPT_URL => $DISCORDAPP_API_ENDPOINT "/users/@me",
  
CURLOPT_RETURNTRANSFER => true,
  
CURLOPT_ENCODING => "",
  
CURLOPT_MAXREDIRS => 10,
  
CURLOPT_TIMEOUT => 30,
  
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  
CURLOPT_CUSTOMREQUEST => "GET",
  
CURLOPT_HTTPHEADER => array(
    
$AUTH_HEADER,
    
"cache-control: no-cache"
  
),
));
$result curl_exec($ch);
$responseCode curl_getinfo($chCURLINFO_HTTP_CODE);
$errorcURL curl_error($ch);
$errorNum curl_errno($ch);
curl_close($ch);
if(
$errorNum || $responseCode != "200") {
    print 
"cURL3 - Result: " $result "<br/>";
    print 
"cURL3 - Response: " $responseCode "<br/>";
    print 
"cURL3 - cURL Error: " $errorcURL "<br/>";
    die();
}
//Parse oAuth response to object.
$data json_decode($resultTRUE);
//Check if "error" exists and then die.
if(isset($data['error']) || !isset($data['id'])) {
    
//There was an error!
    
echo "cURL3 - Error Type: " $data['error'] . "<br/>";
    echo 
"cURL3 - Error Message: " $data['error_description'] . "<br/>";
    echo 
"cURL3 - Result: " $result "<br/>";
    die();
}
//echo $result . "<br/>";

$discordUser $data['username'];
$discordId $data['id'];

//Last but not least is saving within the database!

$conn = new mysqli($DBHOST$DBUSERNAME$DBPASSWORD$DBNAME$DBPORT);
// Check connection
if ($conn->connect_error) {
    die(
"Connection failed: " $conn->connect_error);
}
$sanitizedName $conn->escape_string($steamName);
//Insert or if it exist update the values and change the update time.
$sql "INSERT INTO `discord_connections` (userid,type,id,name) VALUES ('".$discordId."','steam','".$steam64."','".$sanitizedName."') ON DUPLICATE KEY UPDATE id='".$steam64."', name='".$sanitizedName."', updated=CURRENT_TIMESTAMP;";
$dbresult $conn->query($sql);
$conn->close();
if(!
$dbresult) {
    echo 
"Error while saving your steamId and Discord UserId! <br/>";
    die();
}

echo 
"<h1>Saved Discord/Steam connection. Thanks ".$discordUser."!</h1>";
echo 
"Steam Name: " $steamName "<br/>";
echo 
"Steam ID64: " $steam64 "<br/>";
echo 
"Discord Username: " $discordUser "<br/>";
echo 
"Discord UserId: " $discordId "<br/>";
echo 
"<br/>You may now exit this page safely.<br/>";
?>

Most of this was just a proof of concept so it's going to look choppy which is why it's a snippet not a plugin. There was also an idea to redirect to the steam openid login page to get the user's steamid if it doesn't exist as a connection.
Mostly what you would want to change is the entry into the database, depending on your needs you may want to convert to a different type of steamid.

ShiNxz 01-11-2021 22:04

Re: [SNIPPET] Discord / Steam link & tracker
 
Not sure if its usefull (as it was for me), but if someone using DSM (https://forums.alliedmods.net/showthread.php?t=317478)
and want the script to edit the dsm table too so the command listener will work when someone link his discord -> steam.

I'm not a php/sql programmer so it might look wierd/dumb.

Add the following lines (in link.php) after the first connection lines.
PHP Code:

function toSteamID($id) {
    if (
is_numeric($id) && strlen($id) >= 16) {
        
$z bcdiv(bcsub($id'76561197960265728'), '2');
    } elseif (
is_numeric($id)) {
        
$z bcdiv($id'2'); // Actually new User ID format
    
} else {
        return 
$id// We have no idea what this is, so just return it.
    
}
    
$y bcmod($id'2');
    return 
'STEAM_1:' $y ':' floor($z);
}
$steamID toSteamID($steam64);
$conn2 = new mysqli($DBHOST2$DBUSERNAME2$DBPASSWORD2$DBNAME2$DBPORT2);
// Check connection
if ($conn2->connect_error) {
    die(
"Connection failed: " $conn2->connect_error);
}
$sanitizedName $conn2->escape_string($steamName);
//Update dsm
$sql2 "UPDATE `dsm` SET userid='".$discordId."', member='1' WHERE steamid= '".$steamID."'";
$dbresult2 $conn2->query($sql2);
$conn2->close();
if(!
$dbresult2) {
    echo 
"Error while saving your steamId and Discord UserId! <br/>";
    die();



Also add new db information in 'discord_config.php' with the dsm table information.
PHP Code:

// DSM
$DBHOST2 "-";
$DBPORT2 3306;
$DBNAME2 "dsm";
$DBUSERNAME2 "-";
$DBPASSWORD2 "-"

Currently it works fine for me, ik its not the best way to do that, but rewriting the php file / plugin isn't easier.


All times are GMT -4. The time now is 00:39.

Powered by vBulletin®
Copyright ©2000 - 2021, vBulletin Solutions, Inc.