我目前正在使用 Steamworks API 编写多人游戏。不过,我最近遇到了一些问题,那就是我似乎无法将数据包从一个客户端发送到另一个客户端。API 已正确初始化,但当我查找可用数据包时,返回的数据包大小始终为 0。我认为这是因为我只有一个 Steam 帐户,因此 Steamworks 对两个客户端使用相同的 Steam ID导致问题。
所以我的问题是:如何测试这些必须使用不同 Steam ID 的应用程序?如果您有任何其他想法为什么数据包没有发送,请告诉我。所有的网络代码都包含在一个名为 NetworkManager 的类中,我将在此处发布(注意,我丢弃了为简单起见未使用的回调方法。connectToLobby() 在启动时调用一次,pollPackets() 每帧调用一次) :
public class NetworkManager implements SteamMatchmakingCallback, SteamNetworkingCallback, SteamUserCallback, SteamUtilsCallback, SteamAPIWarningMessageHook {
private static final String LOBBY_MATCHING_KEY = "[key:sandbox-lobby]";
private static final String LOBBY_MATCHING_VALUE = "[true]";
private static final int DEFAULT_CHANNEL = 1;
private SteamMatchmaking matchmaking;
private SteamNetworking networking;
private SteamUser user;
private SteamUtils utils;
private Gson serializer;
private SteamID host;
private World world;
public NetworkManager(World world) {
this.world = world;
matchmaking = new SteamMatchmaking(this);
networking = new SteamNetworking(this, API.Client);
user = new SteamUser(this);
utils = new SteamUtils(this);
serializer = new Gson();
utils.setWarningMessageHook(this);
}
@Override
public void onSteamShutdown() {
// TODO Auto-generated method stub
}
@Override
public void onWarningMessage(int severity, String message) {
System.out.println(message);
}
public void connectToLobby() {
System.out.println(user.getSteamID().getAccountID());
matchmaking.addRequestLobbyListStringFilter(LOBBY_MATCHING_KEY, LOBBY_MATCHING_VALUE, LobbyComparison.Equal);
matchmaking.requestLobbyList();
}
public void pollPackets() {
int packetSize;
while ((packetSize = networking.isP2PPacketAvailable(DEFAULT_CHANNEL)) > 0) {
System.out.println("Packet was received!");
// A packet is available, so get it's contents
ByteBuffer buffer = ByteBuffer.allocateDirect(packetSize);
try {
while (networking.readP2PPacket(host, buffer, DEFAULT_CHANNEL) > 0) {
}
} catch (SteamException e) {
e.printStackTrace();
}
byte[] bytes = new byte[buffer.position()];
buffer.get(bytes);
String json = new String(bytes);
buffer = null;
bytes = null;
Packet packet = serializer.fromJson(json, Packet.class);
world.onPacketReceive(packet);
}
}
public void sendPacket(SteamID destination, Packet packet) {
byte[] bytes = serializer.toJson(packet).getBytes();
ByteBuffer buffer = ByteBuffer.allocateDirect(bytes.length);
buffer.clear();
buffer.put(bytes);
buffer.flip();
try {
System.out.println(buffer.position());
System.out.println(buffer.limit());
if (networking.sendP2PPacket(destination, buffer, P2PSend.UnreliableNoDelay, DEFAULT_CHANNEL)) {
System.err.println("Failed to send packet!");
} else {
System.out.println("Sent packet to " + destination.getAccountID() + " from " + user.getSteamID().getAccountID());
}
} catch (SteamException e) {
e.printStackTrace();
}
bytes = null;
buffer = null;
}
@Override
public void onLobbyMatchList(int lobbiesMatching) {
if (lobbiesMatching == 0) {
// No open lobbies found, so create one
matchmaking.createLobby(LobbyType.Public, 2);
} else {
// Open lobby found, so join it
SteamID firstLobby = matchmaking.getLobbyByIndex(0);
matchmaking.joinLobby(firstLobby);
}
}
@Override
public void onLobbyCreated(SteamResult result, SteamID steamIDLobby) {
if (result == SteamResult.OK) {
matchmaking.setLobbyJoinable(steamIDLobby, false);
if (!matchmaking.setLobbyData(steamIDLobby, LOBBY_MATCHING_KEY, LOBBY_MATCHING_VALUE)) {
System.err.println("Failed to set lobby matching data!");
return;
}
matchmaking.setLobbyJoinable(steamIDLobby, true);
host = null;
System.out.println("Lobby creation successful!");
} else {
System.err.println("Lobby creation failed: " + result);
}
}
@Override
public void onLobbyEnter(SteamID steamIDLobby, int chatPermissions, boolean blocked, ChatRoomEnterResponse response) {
host = steamIDLobby;
System.out.println("Lobby join response: " + response);
sendPacket(steamIDLobby, new JoinPacket());
}
@Override
public void onP2PSessionRequest(SteamID steamIDRemote) {
System.out.println("Session request");
// Accept any user that tries to send you messages
networking.acceptP2PSessionWithUser(steamIDRemote);
}
@Override
public void onP2PSessionConnectFail(SteamID steamIDRemote, P2PSessionError sessionError) {
System.err.println("Session connect failed!");
System.err.println(sessionError);
}
}
数据包类:
public class Packet {
public static final int PACKET_LOGIN = 0x0001;
private final int type;
protected final Map<String, String> data;
public Packet(int type) {
this.type = type;
data = new HashMap<String, String>();
}
public int getType() {
return type;
}
}
我非常感谢任何提示为什么没有收到数据包,或者我将如何使用两个不同的 Steam ID 运行两个客户端。