
Java源码Steam游戏服务器信息查询Source Engine Query
查询steam游戏服务器信息API,可查询arma3,dayz等steam游戏
新建类 ServerPlayer.java
封装玩家信息
package com.destiny.kaiheila.destinybot.SteamServerQuery;
public class ServerPlayer {
public int PlayerIndex;
public String PlayerName;
public long PlayerScore;
public float PlayerDuration;
public ServerPlayer(int Index, String Name, long Score, float Duration) {
this.PlayerIndex = Index;
this.PlayerName = Name;
this.PlayerScore = Score;
this.PlayerDuration = Duration;
}
public int getIndex() {
return this.PlayerIndex;
}
public String getName() {
return this.PlayerName;
}
public long getScore() {
return this.PlayerScore;
}
public float getDuration() {
return this.PlayerDuration;
}
}
新建 SteamServerChallenge.java
steam查询头
package com.destiny.kaiheila.destinybot.SteamServerQuery;
public class SteamServerChallenge {
public static int HEADER = (byte)0x41;
}
新建 SteamServerEnvironment.java
专用服务器操作系统标识
package com.destiny.kaiheila.destinybot.SteamServerQuery;
public class SteamServerEnvironment {
public static int LINUX = 108;
public static int WINDOWS = 119;
public static int MAC = 109;
}
新建 SteamServerInfo.java
服务器信息
package com.destiny.kaiheila.destinybot.SteamServerQuery;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
public class SteamServerInfo {
private int position = 0;
public static byte HEADER = (byte)0x49;
private int ServerProtocol;
private byte[] ServerName;
private byte[] ServerMap;
private byte[] ServerFolder;
private byte[] ServerGame;
private short ServerAppID;
private int ServerPlayers;
private int ServerMaxPlayers;
private int ServerBots;
private int ServerType;
private int ServerEnvironment;
private int ServerVisibility;
private int ServerVAC;
private byte[] ServerVersion;
private int ServerEDF;
public SteamServerInfo(byte[] Buffer) {
this.ServerProtocol = Buffer[0];
this.position++;
int ServerNameLength = this.getStringLenght(this.position, Buffer);
this.ServerName = new byte[ServerNameLength];
System.arraycopy(Buffer, this.position, this.ServerName, 0, ServerNameLength);
this.position = this.position + ServerNameLength + 1;
int ServerMapLength = this.getStringLenght(this.position, Buffer);
this.ServerMap = new byte[ServerMapLength];
System.arraycopy(Buffer, this.position, this.ServerMap, 0, ServerMapLength);
this.position = this.position + ServerMapLength + 1;
int ServerFolderLength = this.getStringLenght(this.position, Buffer);
this.ServerFolder = new byte[ServerFolderLength];
System.arraycopy(Buffer, this.position, this.ServerFolder, 0, ServerFolderLength);
this.position = this.position + ServerFolderLength + 1;
int ServerGameLength = this.getStringLenght(this.position, Buffer);
this.ServerGame = new byte[ServerGameLength];
System.arraycopy(Buffer, this.position, this.ServerGame, 0, ServerGameLength);
this.position = this.position + ServerGameLength + 1;
this.ServerAppID = ByteBuffer.wrap(Buffer, this.position, this.position + 1).order(ByteOrder.LITTLE_ENDIAN).getShort();
this.position = this.position + 2;
this.ServerPlayers = Buffer[this.position];
this.position++;
this.ServerMaxPlayers = Buffer[this.position];
this.position++;
this.ServerBots = Buffer[this.position];
this.position++;
this.ServerType = Buffer[this.position];
this.position++;
this.ServerEnvironment = Buffer[this.position];
this.position++;
this.ServerVisibility = Buffer[this.position];
this.position++;
this.ServerVAC = Buffer[this.position];
this.position++;
int ServerVersionLength = getStringLenght(this.position, Buffer);
this.ServerVersion = new byte[ServerVersionLength];
System.arraycopy(Buffer, this.position, this.ServerVersion, 0, ServerVersionLength);
this.position = this.position + ServerVersionLength + 1;
this.ServerEDF = Buffer[this.position];
}
public int getProtocol() {
return this.ServerProtocol;
}
public String getName() {
return new String(this.ServerName);
}
public String getMap() {
return new String(this.ServerMap);
}
public String getFolder() {
return new String(this.ServerFolder);
}
public String getGame() {
return new String(this.ServerGame);
}
public short getAppID() {
return this.ServerAppID;
}
public int getPlayers() {
return this.ServerPlayers;
}
public int getMaxPlayers() {
return this.ServerMaxPlayers;
}
public int getBots() {
return this.ServerBots;
}
public int getType() {
return this.ServerType;
}
public int getEnvironment() {
return this.ServerEnvironment;
}
public int getVisibility() {
return this.ServerVisibility;
}
public int getVAC() {
return this.ServerVAC;
}
public String getVersion() {
return new String(this.ServerVersion);
}
public int getEDF() {
return this.ServerEDF;
}
private int getStringLenght(int start, byte[] buffer) {
for (int i = start; i < buffer.length; i++) {
if (buffer[i] == 0) {
return i - start;
}
}
return 0;
}
@Override
public String toString() {
return "Protocol : " + this.getProtocol() + "\nName : " + this.getName() + "\nMap : " + this.getMap() + "\nFolder : " + this.getFolder() + "\nGame : " + this.getGame() + "\nAppID : " + this.getAppID() + "\nPlayers : " + this.getPlayers() + "\nMax Players : " + this.getMaxPlayers() + "\nBots : " + this.getBots() + "\nServer Type : " + (char)this.getType() + " (d = DEDICATED|l = NON-DEDICATED|p = SourceTV/proxy)\nEnvironment : " + (char)this.getEnvironment() + " (l = Linux|w = Windows|m = MAC)\nVisibility : " + this.getVisibility() + " (0 = Public|1 = Private)\nVAC : " + this.getVAC() + " (0 = UNSECURED|1 = SECURED)\nVersion : " + this.getVersion() + "\nExtra Data Flag (EDF) : " + this.getEDF();
}
}
新建 SteamServerPlayer.java
服务器玩家信息
package com.destiny.kaiheila.destinybot.SteamServerQuery;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class SteamServerPlayer {
private int position = 0;
public static byte HEADER = (byte)0x44;
public int PlayersLength;
public ServerPlayer[] Players;
public SteamServerPlayer(byte[] Buffer) {
this.PlayersLength = Buffer[this.position];
this.Players = new ServerPlayer[this.getPlayersLength()];
this.position++;
for (int i = 0; i < this.getPlayersLength(); i++) {
int PlayerIndex = Buffer[this.position];
this.position++;
int PlayerNameLength = getStringLenght(this.position, Buffer);
byte[] PlayerName = new byte[PlayerNameLength];
System.arraycopy(Buffer, this.position, PlayerName, 0, PlayerNameLength);
this.position = this.position + PlayerNameLength + 1;
long PlayerScore = ((Buffer[this.position + 3] & 0xFFL) << 24) | ((Buffer[this.position + 2] & 0xFFL) << 16) | ((Buffer[this.position + 1] & 0xFFL) << 8) | ((Buffer[this.position + 0] & 0xFFL) << 0);
this.position = this.position + 4;
float PlayerDuration = ByteBuffer.wrap(new byte[] {Buffer[this.position], Buffer[this.position+1], Buffer[this.position+2], Buffer[this.position+3]}).order(ByteOrder.LITTLE_ENDIAN).getFloat();
this.position = this.position + 4;
this.Players[i] = new ServerPlayer(PlayerIndex, new String(PlayerName), PlayerScore, PlayerDuration);
}
}
public int getPlayersLength() {
return this.PlayersLength;
}
public ServerPlayer[] getPlayers() {
return this.Players;
}
private int getStringLenght(int start, byte[] buffer) {
for (int i = start; i < buffer.length; i++) {
if (buffer[i] == 0)
return i - start;
}
return 0;
}
public List<Map<String,Object>> playerList (){
List<Map<String,Object>> listMap = new ArrayList<>();
for (ServerPlayer Player : this.getPlayers()) {
Map<String,Object> map = new HashMap<>();
map.put("playerName",Player.getName() );
map.put("Score", Long.parseLong(String.valueOf(Player.getScore())));
map.put("Duration",Math.round(Player.getDuration() / 3600) + ":" + Math.round((Player.getDuration() % 3600) / 60) + ":" + Math.round((Player.getDuration() % 3600) % 60));
listMap.add(map);
}
return listMap;
}
public String toString() {
String PlayerTable = "";
for (ServerPlayer Player : this.getPlayers()) {
PlayerTable += Player.getName() + ((Player.getName().length() <= 7) ? "\t\t\t\t" : ((Player.getName().length() <= 15) ? "\t\t\t" : ((Player.getName().length() <= 23) ? "\t\t" : "\t")));
PlayerTable += new Long(Player.getScore()).intValue() + "\t\t";
PlayerTable += Math.round(Player.getDuration() / 3600) + ":" + Math.round((Player.getDuration() % 3600) / 60) + ":" + Math.round((Player.getDuration() % 3600) % 60) + "\n";
}
return "Players : " + this.getPlayersLength() + "\nPlayer Name :\t\t\tScore :\t\tDuration:\n" + PlayerTable;
}
}
新建SteamServerQuery.java
steam主服务器查询
package com.destiny.kaiheila.destinybot.SteamServerQuery;
import java.net.*;
public class SteamServerQuery {
private InetAddress ServerAddress;
private int ServerPort;
private DatagramSocket UDPClient;
public SteamServerQuery(InetAddress Address, int Port) {
try {
this.UDPClient = new DatagramSocket();
this.ServerAddress = Address;
this.ServerPort = Port;
} catch (SocketException e) {
e.printStackTrace();
}
}
public SteamServerQuery(String Address, int Port) throws UnknownHostException {
this(InetAddress.getByName(Address), Port);
}
public SteamServerQuery(String Address) throws UnknownHostException {
this(Address.split(":")[0], Integer.parseInt(Address.split(":")[1]));
}
public DatagramSocket getDatagramSocket() {
return UDPClient;
}
public SteamServerInfo getInfo() throws Exception {
byte[] InfoHeader = new byte[25];
InfoHeader[0] = (byte)0xFF;
InfoHeader[1] = (byte)0xFF;
InfoHeader[2] = (byte)0xFF;
InfoHeader[3] = (byte)0xFF;
InfoHeader[4] = (byte)0x54;
byte[] SourceString = new String("Source Engine Query").getBytes();
System.arraycopy(SourceString, 0, InfoHeader, 5, SourceString.length);
InfoHeader[5 + SourceString.length] = (byte) 0x00;
DatagramPacket SendInfoPacket = new DatagramPacket(InfoHeader, InfoHeader.length, this.ServerAddress, this.ServerPort);
this.UDPClient.setSoTimeout(3000);
this.UDPClient.send(SendInfoPacket);
byte[] ReceivedBuffer = new byte[512];
DatagramPacket ReceivedInfoPacket = new DatagramPacket(ReceivedBuffer, ReceivedBuffer.length);
UDPClient.setSoTimeout(3000);
this.UDPClient.receive(ReceivedInfoPacket);
if (ReceivedBuffer[0] == (byte)0xFF && ReceivedBuffer[1] == (byte)0xFF && ReceivedBuffer[2] == (byte)0xFF && ReceivedBuffer[3] == (byte)0xFF && ReceivedBuffer[4] == SteamServerInfo.HEADER) {
byte[] ServerInfoBuffer = new byte[ReceivedBuffer.length - 5];
System.arraycopy(ReceivedBuffer, 5, ServerInfoBuffer, 0, ServerInfoBuffer.length);
return new SteamServerInfo(ServerInfoBuffer);
}
return null;
}
public SteamServerPlayer getPlayer() throws Exception{
byte[] PlayerHeader = this.getChallenge();
PlayerHeader[4] = (byte)0x55;
DatagramPacket SendPlayerPacket = new DatagramPacket(PlayerHeader, PlayerHeader.length, this.ServerAddress, this.ServerPort);
this.UDPClient.send(SendPlayerPacket);
byte[] ReceivedPlayerBuffer = new byte[1024];
DatagramPacket ReceivedPlayerPacket = new DatagramPacket(ReceivedPlayerBuffer, ReceivedPlayerBuffer.length);
this.UDPClient.setSoTimeout(3000);
this.UDPClient.receive(ReceivedPlayerPacket);
if (ReceivedPlayerBuffer[0] == (byte)0xFF && ReceivedPlayerBuffer[1] == (byte)0xFF && ReceivedPlayerBuffer[2] == (byte)0xFF && ReceivedPlayerBuffer[3] == (byte)0xFF && ReceivedPlayerBuffer[4] == SteamServerPlayer.HEADER) {
byte[] ServerPlayerBuffer = new byte[ReceivedPlayerBuffer.length - 5];
System.arraycopy(ReceivedPlayerBuffer, 5, ServerPlayerBuffer, 0, ServerPlayerBuffer.length);
return new SteamServerPlayer(ServerPlayerBuffer);
} else {
System.err.println("ERROR Player Packet !");
return null;
}
}
public byte[] getChallenge() throws Exception {
byte[] ChallengeHeader = new byte[9];
ChallengeHeader[0] = (byte)0xFF;
ChallengeHeader[1] = (byte)0xFF;
ChallengeHeader[2] = (byte)0xFF;
ChallengeHeader[3] = (byte)0xFF;
ChallengeHeader[4] = (byte)0x55;
ChallengeHeader[5] = (byte)0xFF;
ChallengeHeader[6] = (byte)0xFF;
ChallengeHeader[7] = (byte)0xFF;
ChallengeHeader[8] = (byte)0xFF;
DatagramPacket SendChallengePacket = new DatagramPacket(ChallengeHeader, ChallengeHeader.length, this.ServerAddress, this.ServerPort);
this.UDPClient.send(SendChallengePacket);
byte[] ReceivedChallengeBuffer = new byte[9];
DatagramPacket ReceivedChallengePacket = new DatagramPacket(ReceivedChallengeBuffer, ReceivedChallengeBuffer.length);
this.UDPClient.setSoTimeout(3000);
this.UDPClient.receive(ReceivedChallengePacket);
if(ReceivedChallengeBuffer[0] == (byte)0xFF && ReceivedChallengeBuffer[1] == (byte)0xFF && ReceivedChallengeBuffer[2] == (byte)0xFF && ReceivedChallengeBuffer[3] == (byte)0xFF && ReceivedChallengeBuffer[4] == SteamServerChallenge.HEADER) {
return ReceivedChallengeBuffer;
} else {
System.err.println("ERROR Challenge Packet !");
return new byte[9];
}
}
}
使用方法:
//参数 IP:查询端口
SteamServerQuery ServerQuery = new SteamServerQuery("0.0.0.0:2303");
//从服务器获取服务器信息
SteamServerInfo ServerInfo = ServerQuery.getInfo();
//从服务器获取玩家信息
SteamServerPlayer player = ServerQuery.getPlayer();
ServerInfo.....
player....
文件:文件下载
- 感谢你赐予我前进的力量
赞赏者名单
因为你们的支持让我意识到写文章的价值🙏
本文是原创文章,采用 CC BY-NC-ND 4.0 协议,完整转载请注明来自 七龙
评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果