public static IntPtr Get(int size, int referenceCount)
        {
            const int maxSize = 16 * 1024 * 1024;

            if (size < 0 || size > maxSize)
            {
                throw new ArgumentOutOfRangeException(nameof(size));
            }
            if (referenceCount <= 0)
            {
                throw new ArgumentOutOfRangeException(nameof(referenceCount));
            }

            AllocateBuffer(size, out var ptr, out var actualSize);
            var counter = AllocateReferenceCounter(ptr, actualSize, referenceCount);

#if DEBUG
            SteamNetworkingUtils.LogDebugMessage(NetDebugOutput.Verbose,
                                                 $"{nameof( BufferManager )} allocated {ptr.ToInt64():X8} (size={size}, actualSize={actualSize}) with {referenceCount} references");
#endif

            lock ( ReferenceCounters )
            {
                ReferenceCounters.Add(ptr, counter);
            }

            return(ptr);
        }
예제 #2
0
        public static void Shutdown()
        {
            Event.DisposeAllClient();

            initialized = false;

            ShutdownInterfaces();
            SteamApps.Shutdown();
            SteamUtils.Shutdown();
            SteamParental.Shutdown();
            SteamMusic.Shutdown();
            SteamVideo.Shutdown();
            SteamUser.Shutdown();
            SteamFriends.Shutdown();
            SteamScreenshots.Shutdown();
            SteamUserStats.Shutdown();
            SteamInventory.Shutdown();
            SteamNetworking.Shutdown();
            SteamMatchmaking.Shutdown();
            SteamParties.Shutdown();
            SteamNetworkingUtils.Shutdown();
            SteamNetworkingSockets.Shutdown();
            ServerList.Base.Shutdown();

            SteamAPI.Shutdown();
        }
            public void Set(IntPtr ptr, int size, int referenceCount)
            {
                if (ptr == IntPtr.Zero)
                {
                    throw new ArgumentNullException(nameof(ptr));
                }
                if (size <= 0)
                {
                    throw new ArgumentOutOfRangeException(nameof(size));
                }
                if (referenceCount <= 0)
                {
                    throw new ArgumentOutOfRangeException(nameof(referenceCount));
                }

                Pointer = ptr;
                Size    = size;

                var prevCount = Interlocked.Exchange(ref _count, referenceCount);

                if (prevCount != 0)
                {
#if DEBUG
                    SteamNetworkingUtils.LogDebugMessage(NetDebugOutput.Warning, $"{nameof( BufferManager )} set reference count when current count was not 0");
#endif
                }
            }
        public async Task RelayEndtoEndFakeIP()
        {
            SteamNetworkingUtils.InitRelayNetworkAccess();
            SteamNetworkingUtils.DebugLevel     = NetDebugOutput.Warning;
            SteamNetworkingUtils.OnDebugOutput += DebugOutput;

            // For some reason giving steam a couple of seconds here
            // seems to prevent it returning null connections from ConnectNormal
            await Task.Delay(2000);

            Console.WriteLine($"----- Creating Socket Relay Socket..");
            var socket = SteamNetworkingSockets.CreateRelaySocketFakeIP <TestSocketInterface>();
            var server = socket.RunAsync();

            await Task.Delay(1000);

            Console.WriteLine($"----- Retrieving Fake IP..");
            SteamNetworkingSockets.GetFakeIP(0, out NetAddress address);

            Console.WriteLine($"----- Connecting To Socket via Fake IP ({address})");
            var connection = SteamNetworkingSockets.ConnectNormal <TestConnectionInterface>(address);
            var client     = connection.RunAsync();

            await Task.WhenAll(server, client);
        }
예제 #5
0
 public static void Shutdown()
 {
     Event.DisposeAllServer();
     SteamServer.initialized = false;
     SteamServer._internal   = null;
     SteamServer.ShutdownInterfaces();
     SteamNetworkingUtils.Shutdown();
     SteamNetworkingSockets.Shutdown();
     SteamInventory.Shutdown();
     SteamGameServer.Shutdown();
 }
            public bool Decrement()
            {
                var newCount = Interlocked.Decrement(ref _count);

                if (newCount < 0)
                {
                    SteamNetworkingUtils.LogDebugMessage(NetDebugOutput.Bug, $"Prevented double free of {nameof(BufferManager)} pointer");
                    return(false);
                }

                return(newCount == 0);
            }
        public async Task GetEstimatedPing()
        {
            await SteamNetworkingUtils.WaitForPingDataAsync();

            var garrysping = Data.PingLocation.TryParseFromString(GarrysLocation);

            Assert.IsTrue(garrysping.HasValue);

            var ping = SteamNetworkingUtils.EstimatePingTo(garrysping.Value);

            Assert.IsTrue(ping > 0);

            Console.WriteLine($"Ping returned: {ping}");
        }
        private static void FreeBuffer(IntPtr ptr, int size)
        {
            var bucketSize  = GetBucketSize(size);
            var bucketLimit = GetBucketLimit(size);

            if (bucketSize <= 0 || bucketLimit <= 0)
            {
                // not bucketed, no pooling for this size
                Marshal.FreeHGlobal(ptr);

#if DEBUG
                SteamNetworkingUtils.LogDebugMessage(NetDebugOutput.Verbose,
                                                     $"{nameof( BufferManager )} freed unpooled pointer {ptr.ToInt64():X8} (size={size})");
#endif
                return;
            }

            lock ( BufferPools )
            {
                if (!BufferPools.TryGetValue(bucketSize, out var bucketPool))
                {
                    bucketPool = new Stack <IntPtr>(bucketLimit);
                    BufferPools.Add(bucketSize, bucketPool);
                }

                if (bucketPool.Count >= bucketLimit)
                {
                    // pool overflow, get rid
                    Marshal.FreeHGlobal(ptr);

#if DEBUG
                    SteamNetworkingUtils.LogDebugMessage(NetDebugOutput.Verbose,
                                                         $"{nameof( BufferManager )} pool overflow, freed pooled pointer {ptr.ToInt64():X8} (size={size})");
#endif
                    return;
                }

                bucketPool.Push(ptr);

#if DEBUG
                SteamNetworkingUtils.LogDebugMessage(NetDebugOutput.Verbose,
                                                     $"{nameof( BufferManager )} returned pointer to pool {ptr.ToInt64():X8} (size={size})");
#endif
            }
        }
        public async Task LocalPingLocation()
        {
            await SteamNetworkingUtils.WaitForPingDataAsync();

            for (int i = 0; i < 10; i++)
            {
                var pl = SteamNetworkingUtils.LocalPingLocation;
                if (!pl.HasValue)
                {
                    await Task.Delay(1000);

                    continue;
                }

                Console.WriteLine($"{i} Seconds Until Result: {pl}");
                return;
            }

            Assert.Fail();
        }
예제 #10
0
        public async Task RelayEndtoEnd()
        {
            SteamNetworkingUtils.InitRelayNetworkAccess();

            // For some reason giving steam a couple of seconds here
            // seems to prevent it returning null connections from ConnectNormal
            await Task.Delay(2000);

            Console.WriteLine($"----- Creating Socket Relay Socket..");
            var socket = SteamNetworkingSockets.CreateRelaySocket <TestSocketInterface>(6);
            var server = socket.RunAsync();

            await Task.Delay(1000);

            Console.WriteLine($"----- Connecting To Socket via SteamId ({SteamClient.SteamId})");
            var connection = SteamNetworkingSockets.ConnectRelay <TestConnectionInterface>(SteamClient.SteamId, 6);
            var client     = connection.RunAsync();

            await Task.WhenAll(server, client);
        }
        private static void Free(NetMsg *msg)
        {
            var ptr = msg->DataPtr;

            lock ( ReferenceCounters )
            {
                if (!ReferenceCounters.TryGetValue(ptr, out var counter))
                {
                    SteamNetworkingUtils.LogDebugMessage(NetDebugOutput.Bug, $"Attempt to free pointer not tracked by {nameof(BufferManager)}: {ptr.ToInt64():X8}");
                    return;
                }

#if DEBUG
                SteamNetworkingUtils.LogDebugMessage(NetDebugOutput.Verbose, $"{nameof( BufferManager )} decrementing reference count of {ptr.ToInt64():X8}");
#endif

                if (counter.Decrement())
                {
#if DEBUG
                    SteamNetworkingUtils.LogDebugMessage(NetDebugOutput.Verbose, $"{nameof( BufferManager )} freeing {ptr.ToInt64():X8} as it is now unreferenced");

                    if (ptr != counter.Pointer)
                    {
                        SteamNetworkingUtils.LogDebugMessage(NetDebugOutput.Bug,
                                                             $"{nameof( BufferManager )} freed pointer ({ptr.ToInt64():X8}) does not match counter pointer ({counter.Pointer.ToInt64():X8})");
                    }

                    var bucketSize = GetBucketSize(counter.Size);
                    if (counter.Size != bucketSize)
                    {
                        SteamNetworkingUtils.LogDebugMessage(NetDebugOutput.Bug,
                                                             $"{nameof( BufferManager )} freed pointer size ({counter.Size}) does not match bucket size ({bucketSize})");
                    }
#endif

                    ReferenceCounters.Remove(ptr);
                    FreeBuffer(ptr, counter.Size);
                    FreeReferenceCounter(counter);
                }
            }
        }
        private static void AllocateBuffer(int minimumSize, out IntPtr ptr, out int size)
        {
            var bucketSize = GetBucketSize(minimumSize);

            if (bucketSize <= 0)
            {
                // not bucketed, no pooling for this size
                ptr  = Marshal.AllocHGlobal(minimumSize);
                size = minimumSize;

#if DEBUG
                SteamNetworkingUtils.LogDebugMessage(NetDebugOutput.Verbose,
                                                     $"{nameof( BufferManager )} allocated unpooled pointer {ptr.ToInt64():X8} (size={size})");
#endif
                return;
            }

            lock ( BufferPools )
            {
                if (!BufferPools.TryGetValue(bucketSize, out var bucketPool) || bucketPool.Count == 0)
                {
                    // nothing pooled yet, but we can pool this size
                    ptr  = Marshal.AllocHGlobal(bucketSize);
                    size = bucketSize;

#if DEBUG
                    SteamNetworkingUtils.LogDebugMessage(NetDebugOutput.Verbose,
                                                         $"{nameof( BufferManager )} allocated new poolable pointer {ptr.ToInt64():X8} (size={size})");
#endif
                    return;
                }

                ptr  = bucketPool.Pop();
                size = bucketSize;
#if DEBUG
                SteamNetworkingUtils.LogDebugMessage(NetDebugOutput.Verbose,
                                                     $"{nameof( BufferManager )} allocated pointer from pool {ptr.ToInt64():X8} (size={size})");
#endif
            }
        }
예제 #13
0
        /// <summary>
        /// Calls RunFrame and processes events from this Steam Pipe
        /// </summary>
        public static void Frame(HSteamPipe pipe)
        {
            if (runningFrame)
            {
                return;
            }

            try
            {
                runningFrame = true;

                SteamAPI_ManualDispatch_RunFrame(pipe);
                SteamNetworkingUtils.OutputDebugMessages();

                CallbackMsg_t msg = default;

                while (SteamAPI_ManualDispatch_GetNextCallback(pipe, ref msg))
                {
                    try
                    {
                        ProcessCallback(msg, pipe == ServerPipe);
                    }
                    finally
                    {
                        SteamAPI_ManualDispatch_FreeLastCallback(pipe);
                    }
                }
            }
            catch (System.Exception e)
            {
                OnException?.Invoke(e);
            }
            finally
            {
                runningFrame = false;
            }
        }