code-disaster / steamworks4j

A thin Java wrapper to access the Steamworks API
https://code-disaster.github.io/steamworks4j/
MIT License
468 stars 64 forks source link

SteamNetworking.isP2PPacketAvailable generates error in native code #108

Open andy98725 opened 2 years ago

andy98725 commented 2 years ago

In one use case, the mentioned function consistently errors out.

Here's my relevant code. Let me know if there's an alternative way I should be using the method.

private Thread startListener() {
    Thread listen = new Thread(new Runnable() {
        @Override
        public void run() {
            SteamNetworking net = steam.net.get();
            SteamID sender = new SteamID();
            int msgSize;

            try {
                while (!Thread.interrupted()) {
                    try {
                        while ((msgSize = net.isP2PPacketAvailable(0)) > 0) {
                            if (msgSize > recBuffer.capacity())
                            recBuffer = ByteBuffer.allocateDirect(msgSize);

                            synchronized (recBuffer) {
                                    recBuffer.clear();
                                    net.readP2PPacket(sender, recBuffer, 0);
                                    byte[] bytes = new byte[msgSize];
                                    recBuffer.get(bytes);
                                    recieveMessage(FileUtils.bytesToObj(bytes), sender);
                            }
                        }
                    } catch (Exception e) {
                        Game.getLogger().errorLog(e, "Steam Game Listener");
                    }
                    Thread.sleep((long) (1000.0 / Game.FRAME_RATE));
                }
            } catch (InterruptedException e) {
            }
        }
    }, "Steam Game Listener");
    listen.setDaemon(true);
    listen.start();
    return listen;
}

Here's the error log, since I'm on Windows: hs_err_pid18664.log

code-disaster commented 2 years ago

I don't know why it would crash inside the isP2PPacketAvailable() function, but I agree that the Java API could do a better job here. I believe there's also a bug with readP2PPacket() - it should check the return value and limit() recBuffer accordingly afterwards. (The same bug exists in SteamNetworkingTest)

code-disaster commented 2 years ago

Also, not sure what your steam.net.get() does, and how many of those listeners you create, but you may run into trouble here. Try to not share that SteamNetworking instance, but just create a local one.

andy98725 commented 2 years ago

Ah, that line just lazy-loads the interface. There's only the one interface and it's disposed of properly, so no issues there.

I found the presence of the error strange due to the simplicity of the C method. I have no idea what could cause it. Doesn't help that the windows error reporting for the native code is borderline unreadable to me.