diff --git a/core/src/io/anuke/mindustry/net/Net.java b/core/src/io/anuke/mindustry/net/Net.java index 19f459ea60..160fd3343d 100644 --- a/core/src/io/anuke/mindustry/net/Net.java +++ b/core/src/io/anuke/mindustry/net/Net.java @@ -178,9 +178,9 @@ public class Net{ */ public static void send(Object object, SendMode mode){ if(server){ - if(serverProvider != null) serverProvider.send(object, mode); + if(serverProvider != null) serverProvider.sendServer(object, mode); }else{ - if(clientProvider != null) clientProvider.send(object, mode); + if(clientProvider != null) clientProvider.sendClient(object, mode); } } @@ -188,21 +188,21 @@ public class Net{ * Send an object to a certain client. Server-side only */ public static void sendTo(int id, Object object, SendMode mode){ - serverProvider.sendTo(id, object, mode); + serverProvider.sendServerTo(id, object, mode); } /** * Send an object to everyone EXCEPT certain client. Server-side only */ public static void sendExcept(int id, Object object, SendMode mode){ - serverProvider.sendExcept(id, object, mode); + serverProvider.sendServerExcept(id, object, mode); } /** * Send a stream to a specific client. Server-side only. */ public static void sendStream(int id, Streamable stream){ - serverProvider.sendStream(id, stream); + serverProvider.sendServerStream(id, stream); } /** @@ -343,7 +343,7 @@ public class Net{ void connect(String ip, int port, Runnable success) throws IOException; /** Send an object to the server. */ - void send(Object object, SendMode mode); + void sendClient(Object object, SendMode mode); /** Update the ping. Should be done every second or so. */ void updatePing(); @@ -368,7 +368,9 @@ public class Net{ void pingHost(String address, int port, Consumer valid, Consumer failed); /** Close all connections. */ - void dispose(); + default void dispose(){ + disconnect(); + } } /** Server implementation. */ @@ -377,7 +379,7 @@ public class Net{ void host(int port) throws IOException; /** Sends a large stream of data to a specific client. */ - default void sendStream(int id, Streamable stream){ + default void sendServerStream(int id, Streamable stream){ NetConnection connection = getByID(id); if(connection == null) return; try{ @@ -402,13 +404,13 @@ public class Net{ } } - default void send(Object object, SendMode mode){ + default void sendServer(Object object, SendMode mode){ for(NetConnection con : getConnections()){ con.send(object, mode); } } - default void sendTo(int id, Object object, SendMode mode){ + default void sendServerTo(int id, Object object, SendMode mode){ NetConnection conn = getByID(id); if(conn == null){ Log.err("Failed to find connection with ID {0}.", id); @@ -417,7 +419,7 @@ public class Net{ conn.send(object, mode); } - default void sendExcept(int id, Object object, SendMode mode){ + default void sendServerExcept(int id, Object object, SendMode mode){ for(NetConnection con : getConnections()){ if(con.id != id){ con.send(object, mode); diff --git a/desktop/build.gradle b/desktop/build.gradle index 94ad0e0d95..0f8aaacae4 100644 --- a/desktop/build.gradle +++ b/desktop/build.gradle @@ -53,7 +53,7 @@ task steamtest(dependsOn: dist){ if(System.properties["os.name"].contains("Mac")){ into "/Users/anuke/Library/Application Support/Steam/steamapps/common/Mindustry/Contents/Resources" }else{ - into "/home/anuke/.steam/steam/steamapps/common/Mindustry" + into "/home/anuke/.steam/steam/steamapps/common/Mindustry/jre" } rename("Mindustry.jar", "desktop.jar") } diff --git a/desktop/src/io/anuke/mindustry/desktop/DesktopLauncher.java b/desktop/src/io/anuke/mindustry/desktop/DesktopLauncher.java index b17526babe..e4a08eb89c 100644 --- a/desktop/src/io/anuke/mindustry/desktop/DesktopLauncher.java +++ b/desktop/src/io/anuke/mindustry/desktop/DesktopLauncher.java @@ -15,8 +15,9 @@ public class DesktopLauncher{ Platform.instance = new DesktopPlatform(arg); if(SteamAPI.isSteamRunning()){ - Net.setClientProvider(new ArcNetClient()); - Net.setServerProvider(new SteamServerImpl(new ArcNetServer())); + SteamNetImpl net = new SteamNetImpl(); + Net.setClientProvider(net); + Net.setServerProvider(net); }else{ Net.setClientProvider(new ArcNetClient()); Net.setServerProvider(new ArcNetServer()); diff --git a/desktop/src/io/anuke/mindustry/desktop/steam/SteamClientImpl.java b/desktop/src/io/anuke/mindustry/desktop/steam/SteamClientImpl.java deleted file mode 100644 index 7d870f6e00..0000000000 --- a/desktop/src/io/anuke/mindustry/desktop/steam/SteamClientImpl.java +++ /dev/null @@ -1,217 +0,0 @@ -package io.anuke.mindustry.desktop.steam; - -import com.codedisaster.steamworks.*; -import com.codedisaster.steamworks.SteamMatchmaking.*; -import com.codedisaster.steamworks.SteamNetworking.*; -import io.anuke.arc.*; -import io.anuke.arc.function.*; -import io.anuke.arc.util.*; -import io.anuke.arc.util.async.*; -import io.anuke.arc.util.pooling.*; -import io.anuke.mindustry.net.Net; -import io.anuke.mindustry.net.*; -import io.anuke.mindustry.net.Net.*; -import io.anuke.mindustry.net.Packets.*; -import net.jpountz.lz4.*; - -import java.io.*; -import java.nio.*; - -import static io.anuke.mindustry.Vars.ui; - -public class SteamClientImpl implements SteamNetworkingCallback, SteamMatchmakingCallback, ClientProvider{ - final SteamNetworking snet = new SteamNetworking(this); - final SteamMatchmaking smat = new SteamMatchmaking(this); - - final PacketSerializer serializer = new PacketSerializer(); - final ByteBuffer writeBuffer = ByteBuffer.allocateDirect(1024 * 4); - final ByteBuffer readBuffer = ByteBuffer.allocateDirect(1024 * 4); - final LZ4FastDecompressor decompressor = LZ4Factory.fastestInstance().fastDecompressor(); - - SteamID currentLobby, currentServer; - - public SteamClientImpl(){ - //snet = new SteamNetworking(this); - //smat = new SteamMatchmaking(this); - - //Log.info("Calling createLobby"); - //SteamAPICall call = smat.createLobby(LobbyType.FriendsOnly, 16); - - /* - new Thread(() -> { - int length; - SteamID from = new SteamID(); - while((length = snet.isP2PPacketAvailable(0)) != 0){ - try{ - buffer.position(0); - snet.readP2PPacket(from, buffer, 0); - }catch(SteamException e){ - e.printStackTrace(); - } - } - }){{ - setDaemon(true); - }}.start();*/ - - //start recieving packets - Threads.daemon(() -> { - int length; - SteamID from = new SteamID(); - while(true){ - while((length = snet.isP2PPacketAvailable(0)) != 0){ - try{ - readBuffer.position(0); - snet.readP2PPacket(from, readBuffer, 0); - int fromID = from.getAccountID(); - //TODO make sure ID is host ID - Object output = serializer.read(readBuffer); - - if(fromID == currentServer.getAccountID()){ - Core.app.post(() -> Net.handleClientReceived(output)); - } - }catch(SteamException e){ - e.printStackTrace(); - } - } - - Threads.sleep(1000 / 10); - } - }); - } - - @Override - public void connect(String ip, int port, Runnable success) throws IOException{ - //no - } - - @Override - public void send(Object object, SendMode mode){ - if(currentServer == null) return; - - try{ - writeBuffer.limit(writeBuffer.capacity()); - writeBuffer.position(0); - serializer.write(writeBuffer, object); - writeBuffer.flip(); - - snet.sendP2PPacket(currentServer, writeBuffer, mode == SendMode.tcp ? P2PSend.Reliable : P2PSend.UnreliableNoDelay, 0); - }catch(Exception e){ - Net.showError(e); - } - Pools.free(object); - } - - @Override - public void updatePing(){ - - } - - @Override - public int getPing(){ - return 0; - } - - @Override - public void disconnect(){ - if(currentLobby != null){ - smat.leaveLobby(currentLobby); - snet.closeP2PSessionWithUser(currentServer); - currentServer = null; - currentLobby = null; - } - } - - @Override - public byte[] decompressSnapshot(byte[] input, int size){ - return decompressor.decompress(input, size); - } - - @Override - public void discover(Consumer callback, Runnable done){ - - } - - @Override - public void pingHost(String address, int port, Consumer valid, Consumer failed){ - - } - - @Override - public void dispose(){ - disconnect(); - } - - @Override - public void onP2PSessionConnectFail(SteamID steamIDRemote, P2PSessionError sessionError){ - Log.info("{0} has disconnected: {1}", steamIDRemote.getAccountID(), sessionError); - } - - @Override - public void onP2PSessionRequest(SteamID steamIDRemote){ - snet.acceptP2PSessionWithUser(steamIDRemote); - } - - @Override - public void onFavoritesListChanged(int ip, int queryPort, int connPort, int appID, int flags, boolean add, int accountID){ - - } - - @Override - public void onLobbyInvite(SteamID steamIDUser, SteamID steamIDLobby, long gameID){ - Log.info("lobby invite {0} {1} {2}", steamIDLobby.getAccountID(), steamIDUser.getAccountID(), gameID); - ui.showConfirm("Someone has invited you to a game.", "But do you accept?", () -> { - smat.joinLobby(steamIDLobby); - }); - } - - @Override - public void onLobbyEnter(SteamID steamIDLobby, int chatPermissions, boolean blocked, ChatRoomEnterResponse response){ - currentLobby = steamIDLobby; - currentServer = smat.getLobbyOwner(steamIDLobby); - - Connect con = new Connect(); - con.addressTCP = "steam:" + currentServer.getAccountID(); - - Net.handleClientReceived(con); - Log.info("enter lobby {0} {1}", steamIDLobby.getAccountID(), response); - } - - @Override - public void onLobbyDataUpdate(SteamID steamIDLobby, SteamID steamIDMember, boolean success){ - - } - - @Override - public void onLobbyChatUpdate(SteamID steamIDLobby, SteamID steamIDUserChanged, SteamID steamIDMakingChange, ChatMemberStateChange stateChange){ - - } - - @Override - public void onLobbyChatMessage(SteamID steamIDLobby, SteamID steamIDUser, ChatEntryType entryType, int chatID){ - - } - - @Override - public void onLobbyGameCreated(SteamID steamIDLobby, SteamID steamIDGameServer, int ip, short port){ - - } - - @Override - public void onLobbyMatchList(int lobbiesMatching){ - - } - - @Override - public void onLobbyKicked(SteamID steamIDLobby, SteamID steamIDAdmin, boolean kickedDueToDisconnect){ - - } - - @Override - public void onLobbyCreated(SteamResult result, SteamID steamIDLobby){ - } - - @Override - public void onFavoritesListAccountsUpdated(SteamResult result){ - - } -} diff --git a/desktop/src/io/anuke/mindustry/desktop/steam/SteamFriendsImpl.java b/desktop/src/io/anuke/mindustry/desktop/steam/SteamFriendsImpl.java deleted file mode 100644 index 1497508ebf..0000000000 --- a/desktop/src/io/anuke/mindustry/desktop/steam/SteamFriendsImpl.java +++ /dev/null @@ -1,52 +0,0 @@ -package io.anuke.mindustry.desktop.steam; - -import com.codedisaster.steamworks.*; -import com.codedisaster.steamworks.SteamFriends.*; - -public class SteamFriendsImpl implements SteamFriendsCallback{ - public final SteamFriends friends; - - public SteamFriendsImpl(){ - friends = new SteamFriends(this); - } - - @Override - public void onSetPersonaNameResponse(boolean b, boolean b1, SteamResult steamResult){ - - } - - @Override - public void onPersonaStateChange(SteamID steamID, PersonaChange personaChange){ - - } - - @Override - public void onGameOverlayActivated(boolean b){ - - } - - @Override - public void onGameLobbyJoinRequested(SteamID steamID, SteamID steamID1){ - - } - - @Override - public void onAvatarImageLoaded(SteamID steamID, int i, int i1, int i2){ - - } - - @Override - public void onFriendRichPresenceUpdate(SteamID steamID, int i){ - - } - - @Override - public void onGameRichPresenceJoinRequested(SteamID steamID, String s){ - - } - - @Override - public void onGameServerChangeRequested(String s, String s1){ - - } -} diff --git a/desktop/src/io/anuke/mindustry/desktop/steam/SteamNetImpl.java b/desktop/src/io/anuke/mindustry/desktop/steam/SteamNetImpl.java new file mode 100644 index 0000000000..21adf5423d --- /dev/null +++ b/desktop/src/io/anuke/mindustry/desktop/steam/SteamNetImpl.java @@ -0,0 +1,372 @@ +package io.anuke.mindustry.desktop.steam; + +import com.codedisaster.steamworks.*; +import com.codedisaster.steamworks.SteamFriends.*; +import com.codedisaster.steamworks.SteamMatchmaking.*; +import com.codedisaster.steamworks.SteamNetworking.*; +import io.anuke.arc.*; +import io.anuke.arc.collection.*; +import io.anuke.arc.function.*; +import io.anuke.arc.util.*; +import io.anuke.arc.util.async.*; +import io.anuke.arc.util.pooling.*; +import io.anuke.mindustry.net.Net; +import io.anuke.mindustry.net.*; +import io.anuke.mindustry.net.Net.*; +import io.anuke.mindustry.net.Packets.*; +import net.jpountz.lz4.*; + +import java.io.*; +import java.nio.*; +import java.util.concurrent.*; + +import static io.anuke.mindustry.Vars.ui; + +public class SteamNetImpl implements SteamNetworkingCallback, SteamMatchmakingCallback, SteamFriendsCallback, ClientProvider, ServerProvider{ + final SteamNetworking snet = new SteamNetworking(this); + final SteamMatchmaking smat = new SteamMatchmaking(this); + final SteamFriends friends = new SteamFriends(this); + + final PacketSerializer serializer = new PacketSerializer(); + final ByteBuffer writeBuffer = ByteBuffer.allocateDirect(1024 * 4); + final ByteBuffer readBuffer = ByteBuffer.allocateDirect(1024 * 4); + final LZ4FastDecompressor decompressor = LZ4Factory.fastestInstance().fastDecompressor(); + final LZ4Compressor compressor = LZ4Factory.fastestInstance().fastCompressor(); + + final CopyOnWriteArrayList connections = new CopyOnWriteArrayList<>(); + final IntMap steamConnections = new IntMap<>(); //maps steam ID -> valid net connection + + SteamID currentLobby, currentServer; + + public SteamNetImpl(){ + + //start recieving packets + Threads.daemon(() -> { + int length; + SteamID from = new SteamID(); + while(true){ + while((length = snet.isP2PPacketAvailable(0)) != 0){ + try{ + readBuffer.position(0); + snet.readP2PPacket(from, readBuffer, 0); + int fromID = from.getAccountID(); + Object output = serializer.read(readBuffer); + + Core.app.post(() -> { + if(Net.server()){ + SteamConnection con = steamConnections.get(fromID); + if(con != null){ + Net.handleServerReceived(con.id, output); + }else{ + Log.err("Unknown user with ID: {0}", fromID); + } + }else if(fromID == currentServer.getAccountID()){ + Core.app.post(() -> Net.handleClientReceived(output)); + } + }); + }catch(SteamException e){ + e.printStackTrace(); + } + } + + Threads.sleep(1000 / 10); + } + }); + } + + @Override + public void connect(String ip, int port, Runnable success) throws IOException{ + //no + } + + @Override + public void sendClient(Object object, SendMode mode){ + if(currentServer == null) return; + + try{ + writeBuffer.limit(writeBuffer.capacity()); + writeBuffer.position(0); + serializer.write(writeBuffer, object); + writeBuffer.flip(); + + snet.sendP2PPacket(currentServer, writeBuffer, mode == SendMode.tcp ? P2PSend.Reliable : P2PSend.UnreliableNoDelay, 0); + }catch(Exception e){ + Net.showError(e); + } + Pools.free(object); + } + + @Override + public void updatePing(){ + //no + } + + @Override + public int getPing(){ + //absolutely not + return 0; + } + + @Override + public void disconnect(){ + if(currentLobby != null){ + smat.leaveLobby(currentLobby); + snet.closeP2PSessionWithUser(currentServer); + currentServer = null; + currentLobby = null; + } + } + + @Override + public byte[] decompressSnapshot(byte[] input, int size){ + return decompressor.decompress(input, size); + } + + @Override + public void discover(Consumer callback, Runnable done){ + //no + } + + @Override + public void pingHost(String address, int port, Consumer valid, Consumer failed){ + //no + } + + @Override + public void host(int port) throws IOException{ + //TODO adjust max players + smat.createLobby(LobbyType.values()[Core.settings.getInt("lobbytype", 1)], 32); + } + + @Override + public void close(){ + if(currentLobby != null){ + smat.leaveLobby(currentLobby); + for(SteamConnection con : steamConnections.values()){ + con.close(); + } + currentLobby = null; + } + + steamConnections.clear(); + } + + @Override + public byte[] compressSnapshot(byte[] input){ + return compressor.compress(input); + } + + @Override + public Iterable getConnections(){ + return connections; + } + + @Override + public NetConnection getByID(int id){ + for(int i = 0; i < connections.size(); i++){ + SteamConnection con = connections.get(i); + if(con.id == id){ + return con; + } + } + + return null; + } + + @Override + public void onFavoritesListChanged(int i, int i1, int i2, int i3, int i4, boolean b, int i5){ + + } + + @Override + public void onLobbyInvite(SteamID steamIDUser, SteamID steamIDLobby, long gameID){ + Log.info("lobby invite {0} {1} {2}", steamIDLobby.getAccountID(), steamIDUser.getAccountID(), gameID); + + //ignore invites when hosting. + if(Net.server()) return; + + ui.showConfirm("Someone has invited you to a game.", "But do you accept?", () -> { + smat.joinLobby(steamIDLobby); + }); + } + + @Override + public void onLobbyEnter(SteamID steamIDLobby, int chatPermissions, boolean blocked, ChatRoomEnterResponse response){ + currentLobby = steamIDLobby; + currentServer = smat.getLobbyOwner(steamIDLobby); + + Connect con = new Connect(); + con.addressTCP = "steam:" + currentServer.getAccountID(); + + Net.handleClientReceived(con); + Log.info("enter lobby {0} {1}", steamIDLobby.getAccountID(), response); + } + + @Override + public void onLobbyDataUpdate(SteamID steamID, SteamID steamID1, boolean b){ + + } + + @Override + public void onLobbyChatUpdate(SteamID steamID, SteamID steamID1, SteamID steamID2, ChatMemberStateChange chatMemberStateChange){ + + } + + @Override + public void onLobbyChatMessage(SteamID steamID, SteamID steamID1, ChatEntryType chatEntryType, int i){ + + } + + @Override + public void onLobbyGameCreated(SteamID steamID, SteamID steamID1, int i, short i1){ + + } + + @Override + public void onLobbyMatchList(int i){ + + } + + @Override + public void onLobbyKicked(SteamID steamID, SteamID steamID1, boolean b){ + + } + + @Override + public void onLobbyCreated(SteamResult result, SteamID steamID){ + if(!Net.server()){ + Log.info("Lobby created on server: {0}, ignoring.", steamID); + return; + } + + Log.info("callback run ON SERVER"); + Log.info("Lobby create callback"); + Log.info("Lobby {1} created? {0}", result, steamID.getAccountID()); + if(result == SteamResult.OK){ + currentLobby = steamID; + friends.activateGameOverlayInviteDialog(currentLobby); + Log.info("Activating overlay dialog"); + } + } + + @Override + public void onFavoritesListAccountsUpdated(SteamResult steamResult){ + + } + + @Override + public void onP2PSessionConnectFail(SteamID steamIDRemote, P2PSessionError sessionError){ + if(Net.server()){ + Log.info("{0} has disconnected: {1}", steamIDRemote.getAccountID(), sessionError); + + if(Net.server()){ + int id = steamIDRemote.getAccountID(); + + if(steamConnections.containsKey(id)){ + Net.handleServerReceived(id, new Disconnect()); + steamConnections.remove(id); + } + } + }else if(steamIDRemote == currentServer){ + Log.info("Disconnected! {1}: {0}", steamIDRemote.getAccountID(), sessionError); + Net.handleClientReceived(new Disconnect()); + } + } + + @Override + public void onP2PSessionRequest(SteamID steamIDRemote){ + Log.info("Connection request: {0}", steamIDRemote.getAccountID()); + if(Net.client()){ + if(steamIDRemote == currentServer){ + snet.acceptP2PSessionWithUser(steamIDRemote); + } + }else if(Net.server()){ + //accept users on request + snet.acceptP2PSessionWithUser(steamIDRemote); + if(!steamConnections.containsKey(steamIDRemote.getAccountID())){ + SteamConnection con = new SteamConnection(steamIDRemote); + Connect c = new Connect(); + c.id = con.id; + c.addressTCP = "steam:" + steamIDRemote.getAccountID(); + + Log.debug("&bRecieved connection: {0}", c.addressTCP); + + connections.add(con); + Core.app.post(() -> Net.handleServerReceived(c.id, c)); + } + } + } + + @Override + public void onSetPersonaNameResponse(boolean b, boolean b1, SteamResult steamResult){ + + } + + @Override + public void onPersonaStateChange(SteamID steamID, PersonaChange personaChange){ + + } + + @Override + public void onGameOverlayActivated(boolean b){ + + } + + @Override + public void onGameLobbyJoinRequested(SteamID steamID, SteamID steamID1){ + + } + + @Override + public void onAvatarImageLoaded(SteamID steamID, int i, int i1, int i2){ + + } + + @Override + public void onFriendRichPresenceUpdate(SteamID steamID, int i){ + + } + + @Override + public void onGameRichPresenceJoinRequested(SteamID steamID, String s){ + + } + + @Override + public void onGameServerChangeRequested(String s, String s1){ + + } + + public class SteamConnection extends NetConnection{ + final SteamID sid; + + public SteamConnection(SteamID sid){ + super(sid.getAccountID() + ""); + this.sid = sid; + } + + @Override + public void send(Object object, SendMode mode){ + try{ + writeBuffer.limit(writeBuffer.capacity()); + writeBuffer.position(0); + serializer.write(writeBuffer, object); + writeBuffer.flip(); + + snet.sendP2PPacket(sid, writeBuffer, mode == SendMode.tcp ? P2PSend.Reliable : P2PSend.UnreliableNoDelay, 0); + }catch(Exception e){ + Log.err(e); + Log.info("Error sending packet. Disconnecting invalid client!"); + close(); + + SteamConnection k = steamConnections.get(sid.getAccountID()); + if(k != null) steamConnections.remove(sid.getAccountID()); + } + } + + @Override + public void close(){ + snet.closeP2PSessionWithUser(sid); + } + } +} diff --git a/desktop/src/io/anuke/mindustry/desktop/steam/SteamServerImpl.java b/desktop/src/io/anuke/mindustry/desktop/steam/SteamServerImpl.java deleted file mode 100644 index bedecebad7..0000000000 --- a/desktop/src/io/anuke/mindustry/desktop/steam/SteamServerImpl.java +++ /dev/null @@ -1,241 +0,0 @@ -package io.anuke.mindustry.desktop.steam; - -import com.codedisaster.steamworks.*; -import com.codedisaster.steamworks.SteamMatchmaking.*; -import com.codedisaster.steamworks.SteamNetworking.*; -import io.anuke.arc.*; -import io.anuke.arc.collection.*; -import io.anuke.arc.util.*; -import io.anuke.arc.util.async.*; -import io.anuke.mindustry.net.Net; -import io.anuke.mindustry.net.Net.*; -import io.anuke.mindustry.net.*; -import io.anuke.mindustry.net.Packets.*; -import net.jpountz.lz4.*; - -import java.io.*; -import java.nio.*; -import java.util.concurrent.*; - -public class SteamServerImpl implements ServerProvider, SteamNetworkingCallback, SteamMatchmakingCallback{ - private final static int maxLobbyPlayers = 32; - - final LZ4Compressor compressor = LZ4Factory.fastestInstance().fastCompressor(); - final PacketSerializer serializer = new PacketSerializer(); - final ByteBuffer writeBuffer = ByteBuffer.allocateDirect(1024 * 4); - final ByteBuffer readBuffer = ByteBuffer.allocateDirect(1024 * 4); - final SteamNetworking snet = new SteamNetworking(this); - final SteamMatchmaking smat = new SteamMatchmaking(this); - final SteamFriendsImpl friends = new SteamFriendsImpl(); - final CopyOnWriteArrayList connections = new CopyOnWriteArrayList<>(); - //private final ServerProvider server; - - //maps steam ID -> valid net connection - IntMap steamConnections = new IntMap<>(); - SteamID currentLobby; - - public SteamServerImpl(ServerProvider server){ - //this.server = server; - - //start recieving packets - Threads.daemon(() -> { - int length; - SteamID from = new SteamID(); - while(true){ - while((length = snet.isP2PPacketAvailable(0)) != 0){ - try{ - readBuffer.position(0); - snet.readP2PPacket(from, readBuffer, 0); - int fromID = from.getAccountID(); - Object output = serializer.read(readBuffer); - - Core.app.post(() -> { - SteamConnection con = steamConnections.get(fromID); - if(con != null){ - Net.handleServerReceived(con.id, output); - }else{ - Log.err("Unknown user with ID: {0}", fromID); - } - }); - }catch(SteamException e){ - e.printStackTrace(); - } - } - - Threads.sleep(1000 / 10); - } - }); - } - - //server overrides - - @Override - public void host(int port) throws IOException{ - //server.host(port); - smat.createLobby(LobbyType.values()[Core.settings.getInt("lobbytype", 1)], maxLobbyPlayers); - } - - @Override - public void close(){ - // server.close(); - if(currentLobby != null){ - smat.leaveLobby(currentLobby); - for(SteamConnection con : steamConnections.values()){ - con.close(); - } - currentLobby = null; - } - - steamConnections.clear(); - } - - @Override - public byte[] compressSnapshot(byte[] input){ - return compressor.compress(input); - } - - @Override - public Iterable getConnections(){ - return connections; - } - - @Override - public NetConnection getByID(int id){ - for(int i = 0; i < connections.size(); i++){ - SteamConnection con = connections.get(i); - if(con.id == id){ - return con; - } - } - - return null; - } - - //steam lobby overrides - - @Override - public void onFavoritesListChanged(int ip, int queryPort, int connPort, int appID, int flags, boolean add, int accountID){ - - } - - @Override - public void onLobbyInvite(SteamID steamIDUser, SteamID steamIDLobby, long gameID){ - - } - - @Override - public void onLobbyEnter(SteamID steamIDLobby, int chatPermissions, boolean blocked, ChatRoomEnterResponse response){ - - } - - @Override - public void onLobbyDataUpdate(SteamID steamIDLobby, SteamID steamIDMember, boolean success){ - - } - - @Override - public void onLobbyChatUpdate(SteamID steamIDLobby, SteamID steamIDUserChanged, SteamID steamIDMakingChange, ChatMemberStateChange stateChange){ - - } - - @Override - public void onLobbyChatMessage(SteamID steamIDLobby, SteamID steamIDUser, ChatEntryType entryType, int chatID){ - - } - - @Override - public void onLobbyGameCreated(SteamID steamIDLobby, SteamID steamIDGameServer, int ip, short port){ - - } - - @Override - public void onLobbyMatchList(int lobbiesMatching){ - - } - - @Override - public void onLobbyKicked(SteamID steamIDLobby, SteamID steamIDAdmin, boolean kickedDueToDisconnect){ - - } - - @Override - public void onLobbyCreated(SteamResult result, SteamID steamIDLobby){ - Log.info("Lobby create callback"); - Log.info("Lobby {1} created? {0}", result, steamIDLobby.getAccountID()); - if(result == SteamResult.OK){ - currentLobby = steamIDLobby; - friends.friends.activateGameOverlayInviteDialog(currentLobby); - } - } - - @Override - public void onFavoritesListAccountsUpdated(SteamResult result){ - - } - - //steam p2p network overrides - - @Override - public void onP2PSessionConnectFail(SteamID steamIDRemote, P2PSessionError sessionError){ - Log.info("{0} has disconnected: {1}", steamIDRemote.getAccountID(), sessionError); - - if(Net.server()){ - int id = steamIDRemote.getAccountID(); - - if(steamConnections.containsKey(id)){ - Net.handleServerReceived(id, new Disconnect()); - steamConnections.remove(id); - } - } - } - - @Override - public void onP2PSessionRequest(SteamID steamIDRemote){ - //accept users on request - snet.acceptP2PSessionWithUser(steamIDRemote); - if(!steamConnections.containsKey(steamIDRemote.getAccountID())){ - SteamConnection con = new SteamConnection(steamIDRemote); - Connect c = new Connect(); - c.id = con.id; - c.addressTCP = "steam:" + steamIDRemote.getAccountID(); - - Log.debug("&bRecieved connection: {0}", c.addressTCP); - - connections.add(con); - Core.app.post(() -> Net.handleServerReceived(c.id, c)); - } - } - - public class SteamConnection extends NetConnection{ - final SteamID sid; - - public SteamConnection(SteamID sid){ - super(sid.getAccountID() + ""); - this.sid = sid; - } - - @Override - public void send(Object object, SendMode mode){ - try{ - writeBuffer.limit(writeBuffer.capacity()); - writeBuffer.position(0); - serializer.write(writeBuffer, object); - writeBuffer.flip(); - - snet.sendP2PPacket(sid, writeBuffer, mode == SendMode.tcp ? P2PSend.Reliable : P2PSend.UnreliableNoDelay, 0); - }catch(Exception e){ - Log.err(e); - Log.info("Error sending packet. Disconnecting invalid client!"); - close(); - - SteamConnection k = steamConnections.get(sid.getAccountID()); - if(k != null) steamConnections.remove(sid.getAccountID()); - } - } - - @Override - public void close(){ - snet.closeP2PSessionWithUser(sid); - } - } -} diff --git a/net/src/io/anuke/mindustry/net/ArcNetClient.java b/net/src/io/anuke/mindustry/net/ArcNetClient.java index 618aea5eb4..af4ca06894 100644 --- a/net/src/io/anuke/mindustry/net/ArcNetClient.java +++ b/net/src/io/anuke/mindustry/net/ArcNetClient.java @@ -114,7 +114,7 @@ public class ArcNetClient implements ClientProvider{ } @Override - public void send(Object object, SendMode mode){ + public void sendClient(Object object, SendMode mode){ try{ client.sendTCP(object); //sending things can cause an under/overflow, catch it and disconnect instead of crashing