• Welcome to TechPowerUp Forums, Guest! Please check out our forum guidelines for info related to our community.

Steam API XML parse into css?

Solaris17

Super Dainty Moderator
Staff member
Joined
Aug 16, 2005
Messages
25,776 (3.79/day)
Location
Alabama
System Name Rocinante
Processor I9 14900KS
Motherboard EVGA z690 Dark KINGPIN (modded BIOS)
Cooling EK-AIO Elite 360 D-RGB
Memory 64GB Gskill Trident Z5 DDR5 6000 @6400
Video Card(s) MSI SUPRIM Liquid X 4090
Storage 1x 500GB 980 Pro | 1x 1TB 980 Pro | 1x 8TB Corsair MP400
Display(s) Odyssey OLED G9 G95SC
Case Lian Li o11 Evo Dynamic White
Audio Device(s) Moondrop S8's on Schiit Hel 2e
Power Supply Bequiet! Power Pro 12 1500w
Mouse Lamzu Atlantis mini (White)
Keyboard Monsgeek M3 Lavender, Akko Crystal Blues
VR HMD Quest 3
Software Windows 11
Benchmark Scores I dont have time for that.
Hi guys more of a proof of concept im curious about I was looking at hosting a csgo server (irrelevant fun project) which got put on hold when I got interested in the API server status you can run which is this

api.steampowered.com/ISteamApps/GetServersAtAddress/v0001?addr=71.180.229.246&format=xml

The issue is this pulls raw xml with no CSS styling and I was simply wondering if it was possible to make a php file that could call that link maybe and parse it into preset css?

This is more proof of concept than anything but im curious how you could parse the xml tags and style them so that if it were embeded into a website it would be presentable data.

the server IP is my own
 
Joined
Aug 10, 2007
Messages
4,267 (0.70/day)
Location
Sanford, FL, USA
Processor Intel i5-6600
Motherboard ASRock H170M-ITX
Cooling Cooler Master Geminii S524
Memory G.Skill DDR4-2133 16GB (8GB x 2)
Video Card(s) Gigabyte R9-380X 4GB
Storage Samsung 950 EVO 250GB (mSATA)
Display(s) LG 29UM69G-B 2560x1080 IPS
Case Lian Li PC-Q25
Audio Device(s) Realtek ALC892
Power Supply Seasonic SS-460FL2
Mouse Logitech G700s
Keyboard Logitech G110
Software Windows 10 Pro
I see that the API also has a JSON output option.
PHP:
$url = 'http://api.steampowered.com/ISteamApps/GetServersAtAddress/v0001?addr=71.180.229.246';

$server = json_decode(file_get_contents($url), true)['response']['servers'][0];

print_r($server);

/* (
    [addr] => 71.180.229.246:27015
    [gmsindex] => 65534
    [appid] => 730
    [gamedir] => csgo
    [region] => -1
    [secure] => 1
    [lan] =>
    [gameport] => 27015
    [specport] => 0
) */

Not that XML would have been a problem.
PHP:
$url = 'http://api.steampowered.com/ISteamApps/GetServersAtAddress/v0001?addr=71.180.229.246&format=xml';

$xml = simplexml_load_string(file_get_contents($url));

echo $xml->servers->server->addr;
//etc...

It could get certainly get more elaborate than that. An AJAX call after the page is loaded could prevent hang-ups if Steam is down or slow.

-edit-

I shouldn't go straight for the ['servers'][0] since I realized now that the server may not be up and the response should be checked first :) (it's late, could help ya more tomorrow)
 
Last edited:

FordGT90Concept

"I go fast!1!11!1!"
Joined
Oct 13, 2008
Messages
26,259 (4.65/day)
Location
IA, USA
System Name BY-2021
Processor AMD Ryzen 7 5800X (65w eco profile)
Motherboard MSI B550 Gaming Plus
Cooling Scythe Mugen (rev 5)
Memory 2 x Kingston HyperX DDR4-3200 32 GiB
Video Card(s) AMD Radeon RX 7900 XT
Storage Samsung 980 Pro, Seagate Exos X20 TB 7200 RPM
Display(s) Nixeus NX-EDG274K (3840x2160@144 DP) + Samsung SyncMaster 906BW (1440x900@60 HDMI-DVI)
Case Coolermaster HAF 932 w/ USB 3.0 5.25" bay + USB 3.2 (A+C) 3.5" bay
Audio Device(s) Realtek ALC1150, Micca OriGen+
Power Supply Enermax Platimax 850w
Mouse Nixeus REVEL-X
Keyboard Tesoro Excalibur
Software Windows 10 Home 64-bit
Benchmark Scores Faster than the tortoise; slower than the hare.
JSON is probably the better way to go simply because it will use less bandwidth.

No matter which you use, make sure to check ['response']['success'] == true before attempting to access the ['servers'] set. Servers is a list so enumerate through it looking for ['gamedir'] == "csgo"

You'll want to echo the data into HTML with the necessary class and id tags for CSS to work off of.
 

Aquinus

Resident Wat-man
Joined
Jan 28, 2012
Messages
13,147 (2.96/day)
Location
Concord, NH, USA
System Name Apollo
Processor Intel Core i9 9880H
Motherboard Some proprietary Apple thing.
Memory 64GB DDR4-2667
Video Card(s) AMD Radeon Pro 5600M, 8GB HBM2
Storage 1TB Apple NVMe, 4TB External
Display(s) Laptop @ 3072x1920 + 2x LG 5k Ultrafine TB3 displays
Case MacBook Pro (16", 2019)
Audio Device(s) AirPods Pro, Sennheiser HD 380s w/ FIIO Alpen 2, or Logitech 2.1 Speakers
Power Supply 96w Power Adapter
Mouse Logitech MX Master 3
Keyboard Logitech G915, GL Clicky
Software MacOS 12.1
Theoretically, a library like Enlive for Clojure could transform the XML into an appropriate HTML document, but honestly you should just process the response of the API call and not transform (in the sense of transformations) it into something pretty looking. The prettiness (HTML sent to an end user) and the XML response (coming into the server from Steam's API) are two very different things, try to keep them that way. It would be more wise to have an HTML template that uses the data from said response.

Note: If you wrote an API to turn it into JSON, you could do most of it client side in a language like JavaScript or a derivative.
 

FordGT90Concept

"I go fast!1!11!1!"
Joined
Oct 13, 2008
Messages
26,259 (4.65/day)
Location
IA, USA
System Name BY-2021
Processor AMD Ryzen 7 5800X (65w eco profile)
Motherboard MSI B550 Gaming Plus
Cooling Scythe Mugen (rev 5)
Memory 2 x Kingston HyperX DDR4-3200 32 GiB
Video Card(s) AMD Radeon RX 7900 XT
Storage Samsung 980 Pro, Seagate Exos X20 TB 7200 RPM
Display(s) Nixeus NX-EDG274K (3840x2160@144 DP) + Samsung SyncMaster 906BW (1440x900@60 HDMI-DVI)
Case Coolermaster HAF 932 w/ USB 3.0 5.25" bay + USB 3.2 (A+C) 3.5" bay
Audio Device(s) Realtek ALC1150, Micca OriGen+
Power Supply Enermax Platimax 850w
Mouse Nixeus REVEL-X
Keyboard Tesoro Excalibur
Software Windows 10 Home 64-bit
Benchmark Scores Faster than the tortoise; slower than the hare.
Just remove the &format=xml and it returns JSON.
 

Aquinus

Resident Wat-man
Joined
Jan 28, 2012
Messages
13,147 (2.96/day)
Location
Concord, NH, USA
System Name Apollo
Processor Intel Core i9 9880H
Motherboard Some proprietary Apple thing.
Memory 64GB DDR4-2667
Video Card(s) AMD Radeon Pro 5600M, 8GB HBM2
Storage 1TB Apple NVMe, 4TB External
Display(s) Laptop @ 3072x1920 + 2x LG 5k Ultrafine TB3 displays
Case MacBook Pro (16", 2019)
Audio Device(s) AirPods Pro, Sennheiser HD 380s w/ FIIO Alpen 2, or Logitech 2.1 Speakers
Power Supply 96w Power Adapter
Mouse Logitech MX Master 3
Keyboard Logitech G915, GL Clicky
Software MacOS 12.1
Just remove the &format=xml and it returns JSON.
Quick way of saying you don't need a sliver of server-side code to handle this. You can do this with JS and HTML alone.
 

Solaris17

Super Dainty Moderator
Staff member
Joined
Aug 16, 2005
Messages
25,776 (3.79/day)
Location
Alabama
System Name Rocinante
Processor I9 14900KS
Motherboard EVGA z690 Dark KINGPIN (modded BIOS)
Cooling EK-AIO Elite 360 D-RGB
Memory 64GB Gskill Trident Z5 DDR5 6000 @6400
Video Card(s) MSI SUPRIM Liquid X 4090
Storage 1x 500GB 980 Pro | 1x 1TB 980 Pro | 1x 8TB Corsair MP400
Display(s) Odyssey OLED G9 G95SC
Case Lian Li o11 Evo Dynamic White
Audio Device(s) Moondrop S8's on Schiit Hel 2e
Power Supply Bequiet! Power Pro 12 1500w
Mouse Lamzu Atlantis mini (White)
Keyboard Monsgeek M3 Lavender, Akko Crystal Blues
VR HMD Quest 3
Software Windows 11
Benchmark Scores I dont have time for that.
I see that the API also has a JSON output option.
PHP:
$url = 'http://api.steampowered.com/ISteamApps/GetServersAtAddress/v0001?addr=71.180.229.246';

$server = json_decode(file_get_contents($url), true)['response']['servers'][0];

print_r($server);

/* (
    [addr] => 71.180.229.246:27015
    [gmsindex] => 65534
    [appid] => 730
    [gamedir] => csgo
    [region] => -1
    [secure] => 1
    [lan] =>
    [gameport] => 27015
    [specport] => 0
) */

Not that XML would have been a problem.
PHP:
$url = 'http://api.steampowered.com/ISteamApps/GetServersAtAddress/v0001?addr=71.180.229.246&format=xml';

$xml = simplexml_load_string(file_get_contents($url));

echo $xml->servers->server->addr;
//etc...

It could get certainly get more elaborate than that. An AJAX call after the page is loaded could prevent hang-ups if Steam is down or slow.

-edit-

I shouldn't go straight for the ['servers'][0] since I realized now that the server may not be up and the response should be checked first :) (it's late, could help ya more tomorrow)

if you didnt want to start with servers[0] what would you start with? Can you modify the json output as separate objects like you can with XML I'm not familiar with it but it appears you can but this way it just displays the full array string from $url correct?

infact looking at it it seems to me like it would be logical to break the json up via

Code:
$server = json_decode(file_get_contents($url), true)['response']['servers'][0];

into something like

Code:
$server = json_decode(file_get_contents($url), true)['response']['addr'][0];

going by these catagories

Code:
<response>
<success>true</success>
<servers>
<server>
<addr>71.180.229.246:27015</addr>
<gmsindex>65534</gmsindex>
<appid>730</appid>
<gamedir>csgo</gamedir>
<region>-1</region>
<secure>true</secure>
<lan>false</lan>
<gameport>27015</gameport>
<specport>0</specport>
</server>
</servers>
</response>

but using addr does not seem to work. does it not because it is nested inside of 'server'?
 
Last edited:

Aquinus

Resident Wat-man
Joined
Jan 28, 2012
Messages
13,147 (2.96/day)
Location
Concord, NH, USA
System Name Apollo
Processor Intel Core i9 9880H
Motherboard Some proprietary Apple thing.
Memory 64GB DDR4-2667
Video Card(s) AMD Radeon Pro 5600M, 8GB HBM2
Storage 1TB Apple NVMe, 4TB External
Display(s) Laptop @ 3072x1920 + 2x LG 5k Ultrafine TB3 displays
Case MacBook Pro (16", 2019)
Audio Device(s) AirPods Pro, Sennheiser HD 380s w/ FIIO Alpen 2, or Logitech 2.1 Speakers
Power Supply 96w Power Adapter
Mouse Logitech MX Master 3
Keyboard Logitech G915, GL Clicky
Software MacOS 12.1
if you didnt want to start with servers[0] what would you start with? Can you modify the json output as separate objects like you can with XML I'm not familiar with it but it appears you can but this way it just displays the full array string from $url correct?

infact looking at it it seems to me like it would be logical to break the json up via

Code:
$server = json_decode(file_get_contents($url), true)['response']['servers'][0];

into something like

Code:
$server = json_decode(file_get_contents($url), true)['response']['addr'][0];

going by these catagories

Code:
<response>
<success>true</success>
<servers>
<server>
<addr>71.180.229.246:27015</addr>
<gmsindex>65534</gmsindex>
<appid>730</appid>
<gamedir>csgo</gamedir>
<region>-1</region>
<secure>true</secure>
<lan>false</lan>
<gameport>27015</gameport>
<specport>0</specport>
</server>
</servers>
</response>

but using addr does not seem to work. does it not because it is nested inside of 'server'?

Both XML and JSON represent the data the same. You would still need to take the first <server> tag from <servers>. The code for XML there is misleading because you still need to do something similar with the XML. I should also add that JSON parsers for many languages tend to be vastly faster than XML parsers.

Is there a particular way you want this done or do you have something specific in mind? I ask this because HTML/JS is the best way to eliminate the middleman (server) for checking status and requires zero server-side code which would make the page incredibly responsive and lean on bandwidth for the server. JSON can make this incredibly easy and efficient.
 

Solaris17

Super Dainty Moderator
Staff member
Joined
Aug 16, 2005
Messages
25,776 (3.79/day)
Location
Alabama
System Name Rocinante
Processor I9 14900KS
Motherboard EVGA z690 Dark KINGPIN (modded BIOS)
Cooling EK-AIO Elite 360 D-RGB
Memory 64GB Gskill Trident Z5 DDR5 6000 @6400
Video Card(s) MSI SUPRIM Liquid X 4090
Storage 1x 500GB 980 Pro | 1x 1TB 980 Pro | 1x 8TB Corsair MP400
Display(s) Odyssey OLED G9 G95SC
Case Lian Li o11 Evo Dynamic White
Audio Device(s) Moondrop S8's on Schiit Hel 2e
Power Supply Bequiet! Power Pro 12 1500w
Mouse Lamzu Atlantis mini (White)
Keyboard Monsgeek M3 Lavender, Akko Crystal Blues
VR HMD Quest 3
Software Windows 11
Benchmark Scores I dont have time for that.
Both XML and JSON represent the data the same. You would still need to take the first <server> tag from <servers>. The code for XML there is misleading because you still need to do something similar with the XML. I should also add that JSON parsers for many languages tend to be vastly faster than XML parsers.

Is there a particular way you want this done or do you have something specific in mind? I ask this because HTML/JS is the best way to eliminate the middleman (server) for checking status and requires zero server-side code which would make the page incredibly responsive and lean on bandwidth for the server. JSON can make this incredibly easy and efficient.

I simply wanted to parse the data I received via the API into easy to read brackets like

Online:

Server:

Port:

Secure:

So that I could embed it in a webpage that was my whole purpose I just couldn't figure out how to make it "Pretty" The data is functional but it isnt what a normal user would want to see and seeing as I know close to nothing with pulling this data and making it readable I wanted to learn on the way I am at anyone's mercy when it comes to this. The best I can provide is common sense and a logical thought process.
 

FordGT90Concept

"I go fast!1!11!1!"
Joined
Oct 13, 2008
Messages
26,259 (4.65/day)
Location
IA, USA
System Name BY-2021
Processor AMD Ryzen 7 5800X (65w eco profile)
Motherboard MSI B550 Gaming Plus
Cooling Scythe Mugen (rev 5)
Memory 2 x Kingston HyperX DDR4-3200 32 GiB
Video Card(s) AMD Radeon RX 7900 XT
Storage Samsung 980 Pro, Seagate Exos X20 TB 7200 RPM
Display(s) Nixeus NX-EDG274K (3840x2160@144 DP) + Samsung SyncMaster 906BW (1440x900@60 HDMI-DVI)
Case Coolermaster HAF 932 w/ USB 3.0 5.25" bay + USB 3.2 (A+C) 3.5" bay
Audio Device(s) Realtek ALC1150, Micca OriGen+
Power Supply Enermax Platimax 850w
Mouse Nixeus REVEL-X
Keyboard Tesoro Excalibur
Software Windows 10 Home 64-bit
Benchmark Scores Faster than the tortoise; slower than the hare.
Tweaking Jizzler's code...
PHP:
$ip = 'SNIP';
$appid = 730; // Counter-Strike: Global Offensive

$url = 'http://api.steampowered.com/ISteamApps/GetServersAtAddress/v0001?addr=' . $ip;

$response = json_decode(file_get_contents($url), true)['response'];

if ($response['success']) // Make sure Valve was able to query the server.
{
  echo $ip . " Online<br/>Servers:<ul>";
  for ($i=0; $i < count($response['servers']); $i++) // Check each server in the response.
  {
    if ($response['servers'][$i]['appid'] == $appid) // Make sure the host matches requested.
    {
      echo "<li>" . explode(':', $response['servers'][$i]['addr'])[1]; // Get the port number.
      if ($response['servers'][$i]['secure'])
      {
        echo " Secured";
      }
     echo "</li>";
    }
  }
  echo "</ul>";
}
else
{
  echo $ip . " Offline"; // Nothing to see here; move along.
}
Code is untested. Edit the echo lines to make it pretty. Put a DIV or SPAN around it, put it in table, whatever.

It should look like:
SNIP Online
  • 27015 Secured
In theory, anyway. If you had two more CSGO servers running on the same IP, one was secured and one wasn't, it should look like this:
SNIP Online
  • 27015 Secured
  • 27016
  • 27017 Secured
 
Last edited:

Solaris17

Super Dainty Moderator
Staff member
Joined
Aug 16, 2005
Messages
25,776 (3.79/day)
Location
Alabama
System Name Rocinante
Processor I9 14900KS
Motherboard EVGA z690 Dark KINGPIN (modded BIOS)
Cooling EK-AIO Elite 360 D-RGB
Memory 64GB Gskill Trident Z5 DDR5 6000 @6400
Video Card(s) MSI SUPRIM Liquid X 4090
Storage 1x 500GB 980 Pro | 1x 1TB 980 Pro | 1x 8TB Corsair MP400
Display(s) Odyssey OLED G9 G95SC
Case Lian Li o11 Evo Dynamic White
Audio Device(s) Moondrop S8's on Schiit Hel 2e
Power Supply Bequiet! Power Pro 12 1500w
Mouse Lamzu Atlantis mini (White)
Keyboard Monsgeek M3 Lavender, Akko Crystal Blues
VR HMD Quest 3
Software Windows 11
Benchmark Scores I dont have time for that.
Tweaking Jizzler's code...
PHP:
$ip = '71.180.229.246';
$url = 'http://api.steampowered.com/ISteamApps/GetServersAtAddress/v0001?addr=' . $ip;

$response = json_decode(file_get_contents($url), true)['response'];

if ($response['success']) // Make sure Valve was able to query the server.
{
  echo $ip . " Online<br/>Servers:<ul>";
  for ($i=0; $i < count($response['servers']); $i++) // Check each server in the response.
  {
    if ($response['servers'][$i]['appid'] == 730) // Make sure the host is Counter-Strike: Global Offensive.
    {
      echo "<li>" . explode(':', $response['servers'][$i]['addr'])[1]
      if ($response['servers'][$i]['secure'])
      {
        echo " Secured";
      }
     echo "</li>";
    }
  }
  echo "</ul>";
}
else
{
  echo $ip . " Offline"; // Nothing to see here; move along.
}
Code is untested. Edit the echo lines to make it pretty. Put a DIV or SPAN around it, put it in table, whatever.

Thanks ford :toast: I do have an issue with this version when calling the IP it appears to break it I get the 71.18 echos to the page but nothing else so I imagine its a problem with the first 2 lines?

Code:
$ip = '71.180.229.246';
$url = 'http://api.steampowered.com/ISteamApps/GetServersAtAddress/v0001?addr=' + $ip;

but I am unsure if it is a context issue or further down?

nevermind I broke it with a line break that stopped the ?> at the end of the document.
 

FordGT90Concept

"I go fast!1!11!1!"
Joined
Oct 13, 2008
Messages
26,259 (4.65/day)
Location
IA, USA
System Name BY-2021
Processor AMD Ryzen 7 5800X (65w eco profile)
Motherboard MSI B550 Gaming Plus
Cooling Scythe Mugen (rev 5)
Memory 2 x Kingston HyperX DDR4-3200 32 GiB
Video Card(s) AMD Radeon RX 7900 XT
Storage Samsung 980 Pro, Seagate Exos X20 TB 7200 RPM
Display(s) Nixeus NX-EDG274K (3840x2160@144 DP) + Samsung SyncMaster 906BW (1440x900@60 HDMI-DVI)
Case Coolermaster HAF 932 w/ USB 3.0 5.25" bay + USB 3.2 (A+C) 3.5" bay
Audio Device(s) Realtek ALC1150, Micca OriGen+
Power Supply Enermax Platimax 850w
Mouse Nixeus REVEL-X
Keyboard Tesoro Excalibur
Software Windows 10 Home 64-bit
Benchmark Scores Faster than the tortoise; slower than the hare.
I made a lot of changes. I was using the wrong character (+) to concatenate strings. I haven't wrote PHP in forever.
 

Solaris17

Super Dainty Moderator
Staff member
Joined
Aug 16, 2005
Messages
25,776 (3.79/day)
Location
Alabama
System Name Rocinante
Processor I9 14900KS
Motherboard EVGA z690 Dark KINGPIN (modded BIOS)
Cooling EK-AIO Elite 360 D-RGB
Memory 64GB Gskill Trident Z5 DDR5 6000 @6400
Video Card(s) MSI SUPRIM Liquid X 4090
Storage 1x 500GB 980 Pro | 1x 1TB 980 Pro | 1x 8TB Corsair MP400
Display(s) Odyssey OLED G9 G95SC
Case Lian Li o11 Evo Dynamic White
Audio Device(s) Moondrop S8's on Schiit Hel 2e
Power Supply Bequiet! Power Pro 12 1500w
Mouse Lamzu Atlantis mini (White)
Keyboard Monsgeek M3 Lavender, Akko Crystal Blues
VR HMD Quest 3
Software Windows 11
Benchmark Scores I dont have time for that.
So basically for JSON in general php has a built in decode flag and you simply make each section a variable?
 

FordGT90Concept

"I go fast!1!11!1!"
Joined
Oct 13, 2008
Messages
26,259 (4.65/day)
Location
IA, USA
System Name BY-2021
Processor AMD Ryzen 7 5800X (65w eco profile)
Motherboard MSI B550 Gaming Plus
Cooling Scythe Mugen (rev 5)
Memory 2 x Kingston HyperX DDR4-3200 32 GiB
Video Card(s) AMD Radeon RX 7900 XT
Storage Samsung 980 Pro, Seagate Exos X20 TB 7200 RPM
Display(s) Nixeus NX-EDG274K (3840x2160@144 DP) + Samsung SyncMaster 906BW (1440x900@60 HDMI-DVI)
Case Coolermaster HAF 932 w/ USB 3.0 5.25" bay + USB 3.2 (A+C) 3.5" bay
Audio Device(s) Realtek ALC1150, Micca OriGen+
Power Supply Enermax Platimax 850w
Mouse Nixeus REVEL-X
Keyboard Tesoro Excalibur
Software Windows 10 Home 64-bit
Benchmark Scores Faster than the tortoise; slower than the hare.
json_decode processes the entire file into a mixed array. Do:
PHP:
print_r(json_decode(file_get_contents($url), true));
To see the whole array. We're just jumping to the parts we care about.

simplexml_load_string loads it into a class describing the entire XML so you have to step through the children using -> . Arrays are easy to work with because you can copy part of it and focus on it easily.
 

Solaris17

Super Dainty Moderator
Staff member
Joined
Aug 16, 2005
Messages
25,776 (3.79/day)
Location
Alabama
System Name Rocinante
Processor I9 14900KS
Motherboard EVGA z690 Dark KINGPIN (modded BIOS)
Cooling EK-AIO Elite 360 D-RGB
Memory 64GB Gskill Trident Z5 DDR5 6000 @6400
Video Card(s) MSI SUPRIM Liquid X 4090
Storage 1x 500GB 980 Pro | 1x 1TB 980 Pro | 1x 8TB Corsair MP400
Display(s) Odyssey OLED G9 G95SC
Case Lian Li o11 Evo Dynamic White
Audio Device(s) Moondrop S8's on Schiit Hel 2e
Power Supply Bequiet! Power Pro 12 1500w
Mouse Lamzu Atlantis mini (White)
Keyboard Monsgeek M3 Lavender, Akko Crystal Blues
VR HMD Quest 3
Software Windows 11
Benchmark Scores I dont have time for that.
json_decode processes the entire file into a mixed array. Do:
PHP:
print_r(json_decode(file_get_contents($url), true));
To see the whole array. We're just jumping to the parts we care about.

simplexml_load_string loads it into a class describing the entire XML so you have to step through the children using -> . Arrays are easy to work with because you can copy part of it and focus on it easily.

So was that why Jizzlers example included
Code:
echo $xml->servers->server->addr;
? Am I correct in reading it linear? you MUST do servers->server and not just 'server'?
 

FordGT90Concept

"I go fast!1!11!1!"
Joined
Oct 13, 2008
Messages
26,259 (4.65/day)
Location
IA, USA
System Name BY-2021
Processor AMD Ryzen 7 5800X (65w eco profile)
Motherboard MSI B550 Gaming Plus
Cooling Scythe Mugen (rev 5)
Memory 2 x Kingston HyperX DDR4-3200 32 GiB
Video Card(s) AMD Radeon RX 7900 XT
Storage Samsung 980 Pro, Seagate Exos X20 TB 7200 RPM
Display(s) Nixeus NX-EDG274K (3840x2160@144 DP) + Samsung SyncMaster 906BW (1440x900@60 HDMI-DVI)
Case Coolermaster HAF 932 w/ USB 3.0 5.25" bay + USB 3.2 (A+C) 3.5" bay
Audio Device(s) Realtek ALC1150, Micca OriGen+
Power Supply Enermax Platimax 850w
Mouse Nixeus REVEL-X
Keyboard Tesoro Excalibur
Software Windows 10 Home 64-bit
Benchmark Scores Faster than the tortoise; slower than the hare.
Yes, because look at the hierarchy of the XML:
Code:
<response>
	<success>true</success>
	<servers>
		<server>
			<addr>SNIP:27015</addr>
			<gmsindex>65534</gmsindex>
			<appid>730</appid>
			<gamedir>csgo</gamedir>
			<region>-1</region>
			<secure>true</secure>
			<lan>false</lan>
			<gameport>27015</gameport>
			<specport>0</specport>
		</server>
	</servers>
</response>
The reason why you can ignore response is because the root element is implicit and required. $xml effectively refers to response because it always refers to the root element which is response in this case. You can access success via $xml->success.

There can be more than one server in servers. I suspect Jizzler's XML code would break (or only reach #0) if that were the case).
 
Last edited:

Solaris17

Super Dainty Moderator
Staff member
Joined
Aug 16, 2005
Messages
25,776 (3.79/day)
Location
Alabama
System Name Rocinante
Processor I9 14900KS
Motherboard EVGA z690 Dark KINGPIN (modded BIOS)
Cooling EK-AIO Elite 360 D-RGB
Memory 64GB Gskill Trident Z5 DDR5 6000 @6400
Video Card(s) MSI SUPRIM Liquid X 4090
Storage 1x 500GB 980 Pro | 1x 1TB 980 Pro | 1x 8TB Corsair MP400
Display(s) Odyssey OLED G9 G95SC
Case Lian Li o11 Evo Dynamic White
Audio Device(s) Moondrop S8's on Schiit Hel 2e
Power Supply Bequiet! Power Pro 12 1500w
Mouse Lamzu Atlantis mini (White)
Keyboard Monsgeek M3 Lavender, Akko Crystal Blues
VR HMD Quest 3
Software Windows 11
Benchmark Scores I dont have time for that.
I really appreciate the explanation thank you. For those that want to know I did modify the code a bit to make it a little more precise. For example if something is running on the IP valve will still query success and thus the CS server will read as online. However if you query the port it will switch to offline the second the server goes down..or rather when valves API catches up to see if its down.

Code:
$ip = '71.180.229.246';
$appid = 730; // Counter-Strike: Global Offensive

$url = 'http://api.steampowered.com/ISteamApps/GetServersAtAddress/v0001?addr=' . $ip;

$response = json_decode(file_get_contents($url), true)['gameport'];

if ($response['your-port-here']) // Make sure Valve was able to query the server.
{
  echo $ip . " Online<br/>Servers:<ul>";
  for ($i=0; $i < count($response['servers']); $i++) // Check each server in the response.
  {
    if ($response['servers'][$i]['appid'] == $appid) // Make sure the host matches requested.
    {
      echo "<li>" . explode(':', $response['servers'][$i]['addr'])[1]; // Get the port number.
      if ($response['servers'][$i]['secure'])
      {
        echo " Secured";
      }
     echo "</li>";
    }
  }
  echo "</ul>";
}
else
{
  echo $ip . " Offline"; // Nothing to see here; move along.
}

EDIT:: nvm this did not work.
 
Last edited:

FordGT90Concept

"I go fast!1!11!1!"
Joined
Oct 13, 2008
Messages
26,259 (4.65/day)
Location
IA, USA
System Name BY-2021
Processor AMD Ryzen 7 5800X (65w eco profile)
Motherboard MSI B550 Gaming Plus
Cooling Scythe Mugen (rev 5)
Memory 2 x Kingston HyperX DDR4-3200 32 GiB
Video Card(s) AMD Radeon RX 7900 XT
Storage Samsung 980 Pro, Seagate Exos X20 TB 7200 RPM
Display(s) Nixeus NX-EDG274K (3840x2160@144 DP) + Samsung SyncMaster 906BW (1440x900@60 HDMI-DVI)
Case Coolermaster HAF 932 w/ USB 3.0 5.25" bay + USB 3.2 (A+C) 3.5" bay
Audio Device(s) Realtek ALC1150, Micca OriGen+
Power Supply Enermax Platimax 850w
Mouse Nixeus REVEL-X
Keyboard Tesoro Excalibur
Software Windows 10 Home 64-bit
Benchmark Scores Faster than the tortoise; slower than the hare.
Success is based on whether or not api.steampowered.com could invoke a response from 71.180.229.246 at all. That's why it can be successful but not have any servers available. If I were you, I wouldn't show anything on success and "71.180.229.246 unreachable" on fail. The mere presence of an instance under servers says that specific server is online. If it is offline, it simply won't be in the list. If you want to simulate your typical offline/online message, you have to check for the specific instance of a server. If exists, online; if doesn't exist, offline.

I would probably use the gameport field for that. Also using gameport, you could get rid of the explode bit (silly me).
 

Solaris17

Super Dainty Moderator
Staff member
Joined
Aug 16, 2005
Messages
25,776 (3.79/day)
Location
Alabama
System Name Rocinante
Processor I9 14900KS
Motherboard EVGA z690 Dark KINGPIN (modded BIOS)
Cooling EK-AIO Elite 360 D-RGB
Memory 64GB Gskill Trident Z5 DDR5 6000 @6400
Video Card(s) MSI SUPRIM Liquid X 4090
Storage 1x 500GB 980 Pro | 1x 1TB 980 Pro | 1x 8TB Corsair MP400
Display(s) Odyssey OLED G9 G95SC
Case Lian Li o11 Evo Dynamic White
Audio Device(s) Moondrop S8's on Schiit Hel 2e
Power Supply Bequiet! Power Pro 12 1500w
Mouse Lamzu Atlantis mini (White)
Keyboard Monsgeek M3 Lavender, Akko Crystal Blues
VR HMD Quest 3
Software Windows 11
Benchmark Scores I dont have time for that.
Success is based on whether or not api.steampowered.com could invoke a response from 71.180.229.246 at all. That's why it can be successful but not have any servers available. If I were you, I wouldn't show anything on success and "71.180.229.246 unreachable" on fail. The mere presence of an instance under servers says that specific server is online. If it is offline, it simply won't be in the list. If you want to simulate your typical offline/online message, you have to check for the specific instance of a server. If exists, online; if doesn't exist, offline.

Thats what I was looking into. More for education the steam API for example will show success when it can query the IP itself however it will not generate some subsets in this example gameport is not created if the game is not found but the IP is reachable. In my case I attempted to modify it to ask for the gameport group and fail or ask for gameports response IE the port number or fail since this would be even more accurate because even if the IP is infact unreachable gameport would not be polled and the response would still be fail.

at least that was my logic behind it.
 

FordGT90Concept

"I go fast!1!11!1!"
Joined
Oct 13, 2008
Messages
26,259 (4.65/day)
Location
IA, USA
System Name BY-2021
Processor AMD Ryzen 7 5800X (65w eco profile)
Motherboard MSI B550 Gaming Plus
Cooling Scythe Mugen (rev 5)
Memory 2 x Kingston HyperX DDR4-3200 32 GiB
Video Card(s) AMD Radeon RX 7900 XT
Storage Samsung 980 Pro, Seagate Exos X20 TB 7200 RPM
Display(s) Nixeus NX-EDG274K (3840x2160@144 DP) + Samsung SyncMaster 906BW (1440x900@60 HDMI-DVI)
Case Coolermaster HAF 932 w/ USB 3.0 5.25" bay + USB 3.2 (A+C) 3.5" bay
Audio Device(s) Realtek ALC1150, Micca OriGen+
Power Supply Enermax Platimax 850w
Mouse Nixeus REVEL-X
Keyboard Tesoro Excalibur
Software Windows 10 Home 64-bit
Benchmark Scores Faster than the tortoise; slower than the hare.
I'm pretty sure api.steampowered.com is accessing Steam on the computer hosting. Success is based on whether or not the API was able to connect. If it can't connect, there will be no instances of server under servers.

In your example above, I believe it would always fail because $response will never contain your port number, always success and servers.
 

Solaris17

Super Dainty Moderator
Staff member
Joined
Aug 16, 2005
Messages
25,776 (3.79/day)
Location
Alabama
System Name Rocinante
Processor I9 14900KS
Motherboard EVGA z690 Dark KINGPIN (modded BIOS)
Cooling EK-AIO Elite 360 D-RGB
Memory 64GB Gskill Trident Z5 DDR5 6000 @6400
Video Card(s) MSI SUPRIM Liquid X 4090
Storage 1x 500GB 980 Pro | 1x 1TB 980 Pro | 1x 8TB Corsair MP400
Display(s) Odyssey OLED G9 G95SC
Case Lian Li o11 Evo Dynamic White
Audio Device(s) Moondrop S8's on Schiit Hel 2e
Power Supply Bequiet! Power Pro 12 1500w
Mouse Lamzu Atlantis mini (White)
Keyboard Monsgeek M3 Lavender, Akko Crystal Blues
VR HMD Quest 3
Software Windows 11
Benchmark Scores I dont have time for that.

Solaris17

Super Dainty Moderator
Staff member
Joined
Aug 16, 2005
Messages
25,776 (3.79/day)
Location
Alabama
System Name Rocinante
Processor I9 14900KS
Motherboard EVGA z690 Dark KINGPIN (modded BIOS)
Cooling EK-AIO Elite 360 D-RGB
Memory 64GB Gskill Trident Z5 DDR5 6000 @6400
Video Card(s) MSI SUPRIM Liquid X 4090
Storage 1x 500GB 980 Pro | 1x 1TB 980 Pro | 1x 8TB Corsair MP400
Display(s) Odyssey OLED G9 G95SC
Case Lian Li o11 Evo Dynamic White
Audio Device(s) Moondrop S8's on Schiit Hel 2e
Power Supply Bequiet! Power Pro 12 1500w
Mouse Lamzu Atlantis mini (White)
Keyboard Monsgeek M3 Lavender, Akko Crystal Blues
VR HMD Quest 3
Software Windows 11
Benchmark Scores I dont have time for that.
I did manage to make the correct adjustment it seems like this time I used the variable "servers" since the steam API does not create the opening <servers> and only the closing </servers> if you poll "servers" it does not require much modification

Code:
$ip = 'your-IP';
$appid = 730; // Counter-Strike: Global Offensive

$url = 'http://api.steampowered.com/ISteamApps/GetServersAtAddress/v0001?addr=' . $ip;

$response = json_decode(file_get_contents($url), true)['reponse'];

if ($response['servers']) // Make sure Valve was able to query the server.
{
  echo $ip . " Online<br/>Servers:<ul>";
  for ($i=0; $i < count($response['servers']); $i++) // Check each server in the response.
  {
    if ($response['servers'][$i]['appid'] == $appid) // Make sure the host matches requested.
    {
      echo "<li>" . explode(':', $response['servers'][$i]['addr'])[1]; // Get the port number.
      if ($response['servers'][$i]['secure'])
      {
        echo " Secured";
      }
     echo "</li>";
    }
  }
  echo "</ul>";
}
else
{
  echo $ip . " Offline"; // Nothing to see here; move along.
}
 

FordGT90Concept

"I go fast!1!11!1!"
Joined
Oct 13, 2008
Messages
26,259 (4.65/day)
Location
IA, USA
System Name BY-2021
Processor AMD Ryzen 7 5800X (65w eco profile)
Motherboard MSI B550 Gaming Plus
Cooling Scythe Mugen (rev 5)
Memory 2 x Kingston HyperX DDR4-3200 32 GiB
Video Card(s) AMD Radeon RX 7900 XT
Storage Samsung 980 Pro, Seagate Exos X20 TB 7200 RPM
Display(s) Nixeus NX-EDG274K (3840x2160@144 DP) + Samsung SyncMaster 906BW (1440x900@60 HDMI-DVI)
Case Coolermaster HAF 932 w/ USB 3.0 5.25" bay + USB 3.2 (A+C) 3.5" bay
Audio Device(s) Realtek ALC1150, Micca OriGen+
Power Supply Enermax Platimax 850w
Mouse Nixeus REVEL-X
Keyboard Tesoro Excalibur
Software Windows 10 Home 64-bit
Benchmark Scores Faster than the tortoise; slower than the hare.
Here's what I came up with:
PHP:
$ip = 'SNIP';
$servers = array(
		array(27015, 730) // port 27015 should have Counter-Strike: Global Offensive
	);
/* Example of many servers:

$servers = array(
		array(27015, 730), // port 27015 should have Counter-Strike: Global Offensive
		array(7777, 104900), // port 7777 should have ORION: Prelude
		array(26015, 91700) // port 26015 should have E.Y.E: Divine Cybermancy
	);

*/

$url = 'http://api.steampowered.com/ISteamApps/GetServersAtAddress/v0001?addr=' . $ip;

$response = json_decode(file_get_contents($url), true)['response'];

function IndexOfServer($serverarray, $portappid) // Finds the gameport + appid in the response and returns the index.
{
	for ($i=0; $i < count($serverarray); $i++) // Check each server in the response.  If there are no servers, it will fall through to return -1.
	{
		if (($serverarray[$i]['gameport'] == $portappid[0]) && ($serverarray[$i]['appid'] == $portappid[1]))
		{
			return $i; // I found it!
		}
	}
	return -1; // I couldn't find it.
}

if ($response['success']) // Make sure Valve was able to query the server.
{
	echo '<ul>'; // Start unordered list
	for ($s=0; $s < count($servers); $s++) // Loop through our list of expected servers.
	{
		$i = IndexOfServer($response['servers'], $servers[$s]);
		$secured = ''; // Placeholder for our secured message, if it is secured.
		echo '<li class="';
		if ($i == -1)
		{
			echo 'offline'; // This server that was expected to be found was not so we must assume it is offline.
		}
		else
		{
			echo 'online';
			if ($response['servers'][$i]['secure'])
			{
				$secured = ' Secured'; // Would recommend replacing this with an <img /> of a padlock.
			}
		}
		echo '">' . $servers[$s][0] . $secured . '</li>';
	}
	echo "</ul>"; // End unordered list
}
else
{
  echo $ip . ' unreachable'; // Nothing to see here; move along.
}
Use the offline and online classes to decorate the text to show status. For example, make offline red and online green.
 
Last edited:

Solaris17

Super Dainty Moderator
Staff member
Joined
Aug 16, 2005
Messages
25,776 (3.79/day)
Location
Alabama
System Name Rocinante
Processor I9 14900KS
Motherboard EVGA z690 Dark KINGPIN (modded BIOS)
Cooling EK-AIO Elite 360 D-RGB
Memory 64GB Gskill Trident Z5 DDR5 6000 @6400
Video Card(s) MSI SUPRIM Liquid X 4090
Storage 1x 500GB 980 Pro | 1x 1TB 980 Pro | 1x 8TB Corsair MP400
Display(s) Odyssey OLED G9 G95SC
Case Lian Li o11 Evo Dynamic White
Audio Device(s) Moondrop S8's on Schiit Hel 2e
Power Supply Bequiet! Power Pro 12 1500w
Mouse Lamzu Atlantis mini (White)
Keyboard Monsgeek M3 Lavender, Akko Crystal Blues
VR HMD Quest 3
Software Windows 11
Benchmark Scores I dont have time for that.
Here's what I came up with:
PHP:
$ip = '71.180.229.246';
$servers = array(
        array(27015, 730) // port 27015 should have Counter-Strike: Global Offensive;
    );

$url = 'http://api.steampowered.com/ISteamApps/GetServersAtAddress/v0001?addr=' . $ip;

$response = json_decode(file_get_contents($url), true)['response'];

function IndexOfServer($portappid) // Finds the gameport + appid in the response and returns the index.
{
    for ($i=0; $i < count($response['servers']); $i++) // Check each server in the response.
    {
        if (($response['servers'][$i]['gameport'] == $portappid[0]) && ($response['servers'][$i]['appid'] == $portappid[1]))
        {
            return $i; // I found it!
        }
    }
    return -1; // I couldn't find it.
}

if ($response['success']) // Make sure Valve was able to query the server.
{
    echo '<ul>'; // Start unordered list
    for ($s=0; $s < count($servers); $s++) // Loop through our list of expected servers.
    {
        $i = IndexOfServer($servers[$s]);
        $secured = ''; // Placeholder for our secured message, if it is secured.
        echo '<li class="';
        if ($i == -1)
        {
            echo 'offline'; // This server that was expected to be found was not so we must assume it is offline.
        }
        else
        {
            echo 'online';
            if ($response['servers'][$i]['secure'])
            {
                $secured = ' Secured'; // Would recommend replacing this with an <img /> of a padlock.
            }
        }
        echo '">' . $servers[$s][0] . $secured . '</li>';
    }
    echo "</ul>"; // End unordered list
}
else
{
  echo $ip . ' unreachable'; // Nothing to see here; move along.
}
Use the offline and online classes to decorate the text to show status. For example, make offline red and online green.

This one only echos the server port in <li> form

edit:

Code:
 echo '<li class="';
        if ($i == -1)
? no closing > detected on notepad++?
 

FordGT90Concept

"I go fast!1!11!1!"
Joined
Oct 13, 2008
Messages
26,259 (4.65/day)
Location
IA, USA
System Name BY-2021
Processor AMD Ryzen 7 5800X (65w eco profile)
Motherboard MSI B550 Gaming Plus
Cooling Scythe Mugen (rev 5)
Memory 2 x Kingston HyperX DDR4-3200 32 GiB
Video Card(s) AMD Radeon RX 7900 XT
Storage Samsung 980 Pro, Seagate Exos X20 TB 7200 RPM
Display(s) Nixeus NX-EDG274K (3840x2160@144 DP) + Samsung SyncMaster 906BW (1440x900@60 HDMI-DVI)
Case Coolermaster HAF 932 w/ USB 3.0 5.25" bay + USB 3.2 (A+C) 3.5" bay
Audio Device(s) Realtek ALC1150, Micca OriGen+
Power Supply Enermax Platimax 850w
Mouse Nixeus REVEL-X
Keyboard Tesoro Excalibur
Software Windows 10 Home 64-bit
Benchmark Scores Faster than the tortoise; slower than the hare.
Can you copy and paste the source it dumped?
 
Top