Esempio n. 1
0
        /// <summary>
        /// A result is a reply to a specific command
        /// </summary>
        private static void ProcessResult(CallbackMsg_t msg)
        {
            var result = msg.Data.ToType <SteamAPICallCompleted_t>();

            //
            // Do we have an entry added via OnCallComplete
            //
            if (!ResultCallbacks.TryGetValue(result.AsyncCall, out var callbackInfo))
            {
                //
                // This can happen if the callback result was immediately available
                // so we just returned that without actually going through the callback
                // dance. It's okay for this to fail.
                //

                //
                // But still let everyone know that this happened..
                //
                OnDebugCallback?.Invoke((CallbackType)result.Callback, $"[no callback waiting/required]", false);
                return;
            }

            // Remove it before we do anything, incase the continuation throws exceptions
            ResultCallbacks.Remove(result.AsyncCall);

            // At this point whatever async routine called this
            // continues running.
            callbackInfo.continuation();
        }
Esempio n. 2
0
        /// <summary>
        /// A callback is a general global message
        /// </summary>
        private static void ProcessCallback(CallbackMsg_t msg, bool isServer)
        {
            OnDebugCallback?.Invoke(msg.Type, CallbackToString(msg.Type, msg.Data, msg.DataSize), isServer);

            // Is this a special callback telling us that the call result is ready?
            if (msg.Type == CallbackType.SteamAPICallCompleted)
            {
                ProcessResult(msg);
                return;
            }

            if (Callbacks.TryGetValue(msg.Type, out var list))
            {
                actionsToCall.Clear();

                foreach (var item in list)
                {
                    if (item.server != isServer)
                    {
                        continue;
                    }

                    actionsToCall.Add(item.action);
                }

                foreach (var action in actionsToCall)
                {
                    action(msg.Data);
                }

                actionsToCall.Clear();
            }
        }
        internal static void RunFrame(bool isGameServer)
        {
            if (!IsInitialized)
            {
                throw new InvalidOperationException("Callback dispatcher is not initialized.");
            }

            HSteamPipe hSteamPipe = (HSteamPipe)(isGameServer ? NativeMethods.SteamGameServer_GetHSteamPipe() : NativeMethods.SteamAPI_GetHSteamPipe());

            NativeMethods.SteamAPI_ManualDispatch_RunFrame(hSteamPipe);
            var callbacksRegistry = isGameServer ? m_registeredGameServerCallbacks : m_registeredCallbacks;

            while (NativeMethods.SteamAPI_ManualDispatch_GetNextCallback(hSteamPipe, m_pCallbackMsg))
            {
                CallbackMsg_t callbackMsg = (CallbackMsg_t)Marshal.PtrToStructure(m_pCallbackMsg, typeof(CallbackMsg_t));
                try {
                    // Check for dispatching API call results
                    if (callbackMsg.m_iCallback == SteamAPICallCompleted_t.k_iCallback)
                    {
                        SteamAPICallCompleted_t callCompletedCb = (SteamAPICallCompleted_t)Marshal.PtrToStructure(callbackMsg.m_pubParam, typeof(SteamAPICallCompleted_t));
                        IntPtr pTmpCallResult = Marshal.AllocHGlobal((int)callCompletedCb.m_cubParam);
                        bool   bFailed;
                        if (NativeMethods.SteamAPI_ManualDispatch_GetAPICallResult(hSteamPipe, callCompletedCb.m_hAsyncCall, pTmpCallResult, (int)callCompletedCb.m_cubParam, callCompletedCb.m_iCallback, out bFailed))
                        {
                            lock (m_sync) {
                                if (m_registeredCallResults.TryGetValue((ulong)callCompletedCb.m_hAsyncCall, out var callResults))
                                {
                                    m_registeredCallResults.Remove((ulong)callCompletedCb.m_hAsyncCall);
                                    foreach (var cr in callResults)
                                    {
                                        cr.OnRunCallResult(pTmpCallResult, bFailed, (ulong)callCompletedCb.m_hAsyncCall);
                                        cr.SetUnregistered();
                                    }
                                }
                            }
                        }
                        Marshal.FreeHGlobal(pTmpCallResult);
                    }
                    else
                    {
                        if (callbacksRegistry.TryGetValue(callbackMsg.m_iCallback, out var callbacks))
                        {
                            List <Callback> callbacksCopy;
                            lock (m_sync) {
                                callbacksCopy = new List <Callback>(callbacks);
                            }
                            foreach (var callback in callbacksCopy)
                            {
                                callback.OnRunCallback(callbackMsg.m_pubParam);
                            }
                        }
                    }
                } catch (Exception e) {
                    ExceptionHandler(e);
                } finally {
                    NativeMethods.SteamAPI_ManualDispatch_FreeLastCallback(hSteamPipe);
                }
            }
        }
Esempio n. 4
0
        /// <summary>
        /// A callback is a general global message
        /// </summary>
        private static void ProcessCallback(CallbackMsg_t msg)
        {
            // Is this a special callback telling us that the call result is ready?
            if (msg.Type == CallbackType.SteamAPICallCompleted)
            {
                ProcessResult(msg);
                return;
            }

            if (Callbacks.TryGetValue(msg.Type, out var list))
            {
                foreach (var item in list)
                {
                    item.action(msg.Data);
                }
            }
        }
Esempio n. 5
0
        /// <summary>
        /// Calls RunFrame and processes events from this Steam Pipe
        /// </summary>
        public static void Frame(HSteamPipe pipe)
        {
            SteamAPI_ManualDispatch_RunFrame(pipe);

            CallbackMsg_t msg = default;

            while (SteamAPI_ManualDispatch_GetNextCallback(pipe, ref msg))
            {
                try
                {
                    ProcessCallback(msg);
                }
                finally
                {
                    SteamAPI_ManualDispatch_FreeLastCallback(pipe);
                }
            }
        }
Esempio n. 6
0
        /// <summary>
        /// A result is a reply to a specific command
        /// </summary>
        private static void ProcessResult(CallbackMsg_t msg)
        {
            var result = msg.Data.ToType <SteamAPICallCompleted_t>();

            //
            // Do we have an entry added via OnCallComplete
            //
            if (!ResultCallbacks.TryGetValue(result.AsyncCall, out var callbackInfo))
            {
                // Do we care? Should we throw errors?
                return;
            }

            // Remove it before we do anything, incase the continuation throws exceptions
            ResultCallbacks.Remove(result.AsyncCall);

            // At this point whatever async routine called this
            // continues running.
            callbackInfo.continuation();
        }
Esempio n. 7
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;
            }
        }
Esempio n. 8
0
 internal static extern bool SteamAPI_ManualDispatch_GetNextCallback(HSteamPipe pipe, [In, Out] ref CallbackMsg_t msg);
Esempio n. 9
0
        internal static void RunFrame(bool isGameServer)
        {
            if (!IsInitialized)
            {
                throw new InvalidOperationException("Callback dispatcher is not initialized.");
            }
            HSteamPipe hSteamPipe = (HSteamPipe)(isGameServer ? NativeMethods.SteamGameServer_GetHSteamPipe() : NativeMethods.SteamAPI_GetHSteamPipe());

            NativeMethods.SteamAPI_ManualDispatch_RunFrame(hSteamPipe);
            Dictionary <int, List <Callback> > dictionary = (isGameServer ? m_registeredGameServerCallbacks : m_registeredCallbacks);

            while (NativeMethods.SteamAPI_ManualDispatch_GetNextCallback(hSteamPipe, m_pCallbackMsg))
            {
                CallbackMsg_t callbackMsg_t = (CallbackMsg_t)Marshal.PtrToStructure(m_pCallbackMsg, typeof(CallbackMsg_t));
                try
                {
                    if (callbackMsg_t.m_iCallback == 703)
                    {
                        SteamAPICallCompleted_t steamAPICallCompleted_t = (SteamAPICallCompleted_t)Marshal.PtrToStructure(callbackMsg_t.m_pubParam, typeof(SteamAPICallCompleted_t));
                        IntPtr intPtr = Marshal.AllocHGlobal((int)steamAPICallCompleted_t.m_cubParam);
                        if (NativeMethods.SteamAPI_ManualDispatch_GetAPICallResult(hSteamPipe, steamAPICallCompleted_t.m_hAsyncCall, intPtr, (int)steamAPICallCompleted_t.m_cubParam, steamAPICallCompleted_t.m_iCallback, out var pbFailed))
                        {
                            lock (m_sync)
                            {
                                if (m_registeredCallResults.TryGetValue((ulong)steamAPICallCompleted_t.m_hAsyncCall, out var value))
                                {
                                    m_registeredCallResults.Remove((ulong)steamAPICallCompleted_t.m_hAsyncCall);
                                    foreach (CallResult item in value)
                                    {
                                        item.OnRunCallResult(intPtr, pbFailed, (ulong)steamAPICallCompleted_t.m_hAsyncCall);
                                        item.SetUnregistered();
                                    }
                                }
                            }
                        }
                        Marshal.FreeHGlobal(intPtr);
                    }
                    else
                    {
                        if (!dictionary.TryGetValue(callbackMsg_t.m_iCallback, out var value2))
                        {
                            continue;
                        }
                        List <Callback> list;
                        lock (m_sync)
                        {
                            list = new List <Callback>(value2);
                        }
                        foreach (Callback item2 in list)
                        {
                            item2.OnRunCallback(callbackMsg_t.m_pubParam);
                        }
                        continue;
                    }
                }
                catch (Exception e)
                {
                    ExceptionHandler(e);
                }
                finally
                {
                    NativeMethods.SteamAPI_ManualDispatch_FreeLastCallback(hSteamPipe);
                }
            }
        }