Как тестировать приложения Steamworks P2P только с одной учетной записью Steam?

В настоящее время я пишу многопользовательскую игру, используя API Steamworks. Однако недавно я столкнулся с некоторыми проблемами, то есть я не могу отправлять пакеты от одного клиента к другому. API правильно инициализирован и все такое, но когда я ищу доступные пакеты, возвращаемый размер пакета всегда равен 0. Я думаю, это потому, что у меня есть только одна учетная запись Steam, поэтому Steamworks использует один и тот же идентификатор Steam для обоих клиентов, которые вызывает проблемы.

Итак, мой вопрос: как можно протестировать такие приложения, которые должны использовать разные идентификаторы Steam? Если у вас есть другие идеи, почему пакеты не отправляются, пожалуйста, дайте мне знать. Весь сетевой код содержится в одном классе 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.


person scewps    schedule 25.12.2017    source источник


Ответы (1)


Я создал второй аккаунт Steam только по этой причине. Добавил учетную запись разработчика в серверную часть Steamworks и использовал бета-ключ для активации игры.

Тестировать все еще сложно, так как обе стороны должны запускать свой собственный клиент Steam, по крайней мере, насколько я знаю. Я только что использовал две машины (один ПК, один MacBook), и мне приходилось постоянно напоминать себе синхронизировать каждое изменение кода.

person Daniel Ludwig    schedule 24.01.2018