diff --git a/Facepunch.Steamworks/Interop/steam_api_interop.cs b/Facepunch.Steamworks/Interop/steam_api_interop.cs index cf49dbe..7174128 100644 --- a/Facepunch.Steamworks/Interop/steam_api_interop.cs +++ b/Facepunch.Steamworks/Interop/steam_api_interop.cs @@ -1290,9 +1290,9 @@ namespace Valve.Interop [DllImportAttribute( "FacepunchSteamworksApi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamGameServer_GetPublicIP" )] internal static extern uint SteamAPI_ISteamGameServer_GetPublicIP( IntPtr instancePtr ); [DllImportAttribute( "FacepunchSteamworksApi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamGameServer_HandleIncomingPacket" )] - internal static extern bool SteamAPI_ISteamGameServer_HandleIncomingPacket( IntPtr instancePtr, IntPtr pData, int cbData, uint srcIP, char srcPort ); + internal static extern bool SteamAPI_ISteamGameServer_HandleIncomingPacket( IntPtr instancePtr, IntPtr pData, int cbData, uint srcIP, ushort srcPort ); [DllImportAttribute( "FacepunchSteamworksApi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamGameServer_GetNextOutgoingPacket" )] - internal static extern int SteamAPI_ISteamGameServer_GetNextOutgoingPacket( IntPtr instancePtr, IntPtr pOut, int cbMaxOut, ref uint pNetAdr, ref char pPort ); + internal static extern int SteamAPI_ISteamGameServer_GetNextOutgoingPacket( IntPtr instancePtr, IntPtr pOut, int cbMaxOut, ref uint pNetAdr, ref ushort pPort ); [DllImportAttribute( "FacepunchSteamworksApi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamGameServer_EnableHeartbeats" )] internal static extern void SteamAPI_ISteamGameServer_EnableHeartbeats( IntPtr instancePtr, bool bActive ); [DllImportAttribute( "FacepunchSteamworksApi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamGameServer_SetHeartbeatInterval" )] @@ -2355,8 +2355,8 @@ namespace Valve.Steamworks internal abstract void GetGameplayStats(); internal abstract ulong GetServerReputation(); internal abstract uint GetPublicIP(); - internal abstract bool HandleIncomingPacket( IntPtr pData, int cbData, uint srcIP, char srcPort ); - internal abstract int GetNextOutgoingPacket( IntPtr pOut, int cbMaxOut, ref uint pNetAdr, ref char pPort ); + internal abstract bool HandleIncomingPacket( IntPtr pData, int cbData, uint srcIP, ushort srcPort ); + internal abstract int GetNextOutgoingPacket( IntPtr pOut, int cbMaxOut, ref uint pNetAdr, ref ushort pPort ); internal abstract void EnableHeartbeats( bool bActive ); internal abstract void SetHeartbeatInterval( int iHeartbeatInterval ); internal abstract void ForceHeartbeat(); @@ -6685,13 +6685,13 @@ namespace Valve.Steamworks uint result = NativeEntrypoints.SteamAPI_ISteamGameServer_GetPublicIP(m_pSteamGameServer); return result; } - internal override bool HandleIncomingPacket( IntPtr pData, int cbData, uint srcIP, char srcPort ) + internal override bool HandleIncomingPacket( IntPtr pData, int cbData, uint srcIP, ushort srcPort ) { CheckIfUsable(); bool result = NativeEntrypoints.SteamAPI_ISteamGameServer_HandleIncomingPacket(m_pSteamGameServer,pData,cbData,srcIP,srcPort); return result; } - internal override int GetNextOutgoingPacket( IntPtr pOut, int cbMaxOut, ref uint pNetAdr, ref char pPort ) + internal override int GetNextOutgoingPacket( IntPtr pOut, int cbMaxOut, ref uint pNetAdr, ref ushort pPort ) { CheckIfUsable(); pNetAdr = 0; diff --git a/Facepunch.Steamworks/Server/Query.cs b/Facepunch.Steamworks/Server/Query.cs new file mode 100644 index 0000000..b795220 --- /dev/null +++ b/Facepunch.Steamworks/Server/Query.cs @@ -0,0 +1,82 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; + +namespace Facepunch.Steamworks +{ + public partial class Server + { + ServerQuery _query; + + public ServerQuery Query + { + get + { + if ( _query == null ) + _query = new ServerQuery( this ); + + return _query; + } + } + } + + public class ServerQuery + { + internal Server server; + internal static byte[] buffer = new byte[16*1024]; + + internal ServerQuery( Server s ) + { + server = s; + } + + public struct Packet + { + public uint Address { get; internal set; } + public byte[] Data { get; internal set; } + public ushort Port { get; internal set; } + public int Size { get; internal set; } + } + + /// + /// If true, Steam wants to send a packet. You should respond by sending + /// this packet in an unconnected way to the returned Address and Port + /// + /// + /// + public unsafe bool GetOutgoingPacket( out Packet packet ) + { + packet = new Packet(); + + fixed ( byte* ptr = buffer ) + { + uint addr = 0; + ushort port = 0; + + var size = server.native.gameServer.GetNextOutgoingPacket( (IntPtr)ptr, buffer.Length, ref addr, ref port ); + if ( size == 0 ) + return false; + + packet.Size = size; + packet.Data = buffer; + packet.Address = addr; + packet.Port = port; + return true; + } + } + + /// + /// We have received a server query on our game port. Pass it to Steam to handle. + /// + public unsafe void Handle( byte[] data, int size, uint address, ushort port ) + { + fixed ( byte* ptr = data ) + { + server.native.gameServer.HandleIncomingPacket( (IntPtr)ptr, size, address, port ); + } + } + + } +}