using System; using System.Collections.Generic; using System.Runtime.InteropServices; using Decal.Interop.Core; using Decal.Interop.Net; namespace Decal.DecalNet { [ComVisible(true)] [Guid("C8C406F8-BA2E-4964-8B04-FF38394A8E0E")] [ClassInterface(ClassInterfaceType.None)] [ProgId("DecalNet.NetService")] public class NetServiceImpl : INetService, IDecalService { internal static NetServiceImpl Instance { get; private set; } private IDecalCore _decalCore; private readonly List _filters = new List(); public DecalCore Decal => (DecalCore)_decalCore; // Returns the network filter (V2 interface) if available public object Filter => _filters.Count > 0 ? _filters[0] : null; // Returns filter via IDispatch for VB compatibility public object FilterVB => Filter; public ACHooks Hooks => _decalCore?.Hooks; // IDecalService public void Initialize(DecalCore pDecal) { _decalCore = (IDecalCore)pDecal; Instance = this; // In native code: hooks recvfrom/sendto from wsock32.dll // Network hooking in C# will use the same approach via P/Invoke // or be handled by the native Inject.DLL shim } public void BeforePlugins() { // Load V1 network filters from registry } public void AfterPlugins() { // Remove V1 filters (after plugins had a chance to upgrade to V2) } public void Terminate() { // Terminate all filters foreach (var filter in _filters) { try { filter.Terminate(); } catch { } } _filters.Clear(); _decalCore = null; if (Instance == this) Instance = null; } /// /// Register a V2 network filter. /// internal void RegisterFilter(INetworkFilter2 filter) { _filters.Add(filter); filter.Initialize((NetService)(object)this); } /// /// Dispatch a server-to-client message to all filters. /// Called from the network hook when a packet is received. /// internal void DispatchServerMessage(byte[] data) { var msg = new MessageImpl(data, false); foreach (var filter in _filters) { try { filter.DispatchServer((IMessage2)msg); } catch { } } } /// /// Dispatch a client-to-server message to all filters. /// Called from the network hook when a packet is sent. /// internal void DispatchClientMessage(byte[] data) { var msg = new MessageImpl(data, true); foreach (var filter in _filters) { try { filter.DispatchClient((IMessage2)msg); } catch { } } } } }