Exemplo n.º 1
0
        public static void RegisterAllPacketNestedTypesInAssembly(Assembly assembly, NetPacketProcessor packetProcessor)
        {
            System.Collections.Generic.IEnumerable <Type> nestedTypes = AssembliesUtils.GetTypesWithAttributeInAssembly <RegisterNestedTypeAttribute>(assembly);
            foreach (Type type in nestedTypes)
            {
                Log.Info($"Registering Nested Type: {type.Name}");
                if (type.IsClass)
                {
                    MethodInfo registerMethod = packetProcessor.GetType().GetMethods()
                                                .Where(m => m.Name == nameof(NetPacketProcessor.RegisterNestedType))
                                                .FirstOrDefault(m => m.GetParameters().Length == 1 && m.GetParameters()[0].ParameterType.Name.Equals(typeof(Func <>).Name))
                                                .MakeGenericMethod(type);

                    MethodInfo delegateMethod = packetProcessor.GetType().GetMethod(nameof(NetPacketProcessor.CreateNestedClassInstance)).MakeGenericMethod(type);
                    Type       funcType       = typeof(Func <>).MakeGenericType(type);
                    Delegate   callback       = Delegate.CreateDelegate(funcType, packetProcessor, delegateMethod);
                    registerMethod.Invoke(packetProcessor, new object[] { callback });
                }
                else if (type.IsValueType)
                {
                    MethodInfo method  = typeof(NetPacketProcessor).GetMethod(nameof(NetPacketProcessor.RegisterNestedType), Type.EmptyTypes);
                    MethodInfo generic = method.MakeGenericMethod(type);
                    generic.Invoke(packetProcessor, null);
                }
                else
                {
                    Log.Error($"Could not register nested type: {type.Name}. Must be a class or struct.");
                }
            }
        }
Exemplo n.º 2
0
        public static void RegisterAllPacketNestedTypes(NetPacketProcessor packetProcessor)
        {
            var nestedTypes = AssembliesUtils.GetTypesWithAttribute <RegisterNestedTypeAttribute>();

            foreach (Type type in nestedTypes)
            {
                Console.WriteLine($"Registering Nested Type: {type.Name}");
                if (type.IsClass)
                {
                    // TODO: Find a better way to get the "NetPacketProcessor.RegisterNestedType" that as the Func<T> param instead of by index.
                    MethodInfo registerMethod = packetProcessor.GetType()
                                                .GetMethods()
                                                .Where(m => m.Name == nameof(NetPacketProcessor.RegisterNestedType))
                                                .ToArray()[2]
                                                .MakeGenericMethod(type);

                    MethodInfo delegateMethod = packetProcessor.GetType().GetMethod(nameof(NetPacketProcessor.CreateNestedClassInstance)).MakeGenericMethod(type);
                    var        funcType       = typeof(Func <>).MakeGenericType(type);
                    var        callback       = Delegate.CreateDelegate(funcType, packetProcessor, delegateMethod);
                    registerMethod.Invoke(packetProcessor, new object[] { callback });
                }
                else if (type.IsValueType)
                {
                    MethodInfo method  = typeof(NetPacketProcessor).GetMethod(nameof(NetPacketProcessor.RegisterNestedType), Type.EmptyTypes);
                    MethodInfo generic = method.MakeGenericMethod(type);
                    generic.Invoke(packetProcessor, null);
                }
                else
                {
                    Log.Error($"Could not register nested type: {type.Name}. Must be a class or struct.");
                }
            }
        }
Exemplo n.º 3
0
        public override void Start()
        {
            foreach (Assembly assembly in AssembliesUtils.GetNebulaAssemblies())
            {
                PacketUtils.RegisterAllPacketNestedTypesInAssembly(assembly, PacketProcessor);
            }
            PacketUtils.RegisterAllPacketProcessorsInCallingAssembly(PacketProcessor, false);

            foreach (Assembly assembly in NebulaModAPI.TargetAssemblies)
            {
                PacketUtils.RegisterAllPacketNestedTypesInAssembly(assembly, PacketProcessor);
                PacketUtils.RegisterAllPacketProcessorsInAssembly(assembly, PacketProcessor, false);
            }
#if DEBUG
            PacketProcessor.SimulateLatency = true;
#endif

            clientSocket            = new WebSocket($"ws://{serverEndpoint}/socket");
            clientSocket.OnOpen    += ClientSocket_OnOpen;
            clientSocket.OnClose   += ClientSocket_OnClose;
            clientSocket.OnMessage += ClientSocket_OnMessage;

            clientSocket.Connect();

            ((LocalPlayer)Multiplayer.Session.LocalPlayer).IsHost = false;

            if (Config.Options.RememberLastIP)
            {
                // We've successfully connected, set connection as last ip, cutting out "ws://" and "/socket"
                Config.Options.LastIP = serverEndpoint.ToString();
                Config.SaveOptions();
            }

            NebulaModAPI.OnMultiplayerGameStarted?.Invoke();
        }
Exemplo n.º 4
0
        public override void Start()
        {
            if (loadSaveFile)
            {
                SaveManager.LoadServerData();
            }

            foreach (Assembly assembly in AssembliesUtils.GetNebulaAssemblies())
            {
                PacketUtils.RegisterAllPacketNestedTypesInAssembly(assembly, PacketProcessor);
            }
            PacketUtils.RegisterAllPacketProcessorsInCallingAssembly(PacketProcessor, true);

            foreach (Assembly assembly in NebulaModAPI.TargetAssemblies)
            {
                PacketUtils.RegisterAllPacketNestedTypesInAssembly(assembly, PacketProcessor);
                PacketUtils.RegisterAllPacketProcessorsInAssembly(assembly, PacketProcessor, true);
            }
#if DEBUG
            PacketProcessor.SimulateLatency = true;
#endif

            socket = new WebSocketServer(System.Net.IPAddress.IPv6Any, port);
            DisableNagleAlgorithm(socket);
            WebSocketService.PacketProcessor = PacketProcessor;
            WebSocketService.PlayerManager   = PlayerManager;
            socket.AddWebSocketService <WebSocketService>("/socket", wse => new WebSocketService());
            try
            {
                socket.KeepClean = Config.Options.CleanupInactiveSessions;
                socket.Start();
            }catch (System.InvalidOperationException e)
            {
                InGamePopup.ShowError("Error", "An error occurred while hosting the game: " + e.Message, "Close");
                Stop();
                return;
            }

            ((LocalPlayer)Multiplayer.Session.LocalPlayer).IsHost = true;

            ((LocalPlayer)Multiplayer.Session.LocalPlayer).SetPlayerData(new PlayerData(
                                                                             PlayerManager.GetNextAvailablePlayerId(),
                                                                             GameMain.localPlanet?.id ?? -1,
                                                                             Config.Options.GetMechaColors(),
                                                                             !string.IsNullOrWhiteSpace(Config.Options.Nickname) ? Config.Options.Nickname : GameMain.data.account.userName), loadSaveFile);

            NebulaModAPI.OnMultiplayerGameStarted?.Invoke();
        }
Exemplo n.º 5
0
        public override void Start()
        {
            if (loadSaveFile)
            {
                SaveManager.LoadServerData();
            }

            foreach (Assembly assembly in AssembliesUtils.GetNebulaAssemblies())
            {
                PacketUtils.RegisterAllPacketNestedTypesInAssembly(assembly, PacketProcessor);
            }
            PacketUtils.RegisterAllPacketProcessorsInCallingAssembly(PacketProcessor, true);

            foreach (Assembly assembly in NebulaModAPI.TargetAssemblies)
            {
                PacketUtils.RegisterAllPacketNestedTypesInAssembly(assembly, PacketProcessor);
                PacketUtils.RegisterAllPacketProcessorsInAssembly(assembly, PacketProcessor, true);
            }
#if DEBUG
            PacketProcessor.SimulateLatency = true;
#endif

            if (Config.Options.EnableUPnpOrPmpSupport)
            {
                Task.Run(async() => {
                    var discoverer = new NatDiscoverer();
                    try
                    {
                        var device = await discoverer.DiscoverDeviceAsync();
                        await device.CreatePortMapAsync(new Mapping(Protocol.Tcp, port, port, "DSP nebula"));
                        NebulaModel.Logger.Log.Info($"Successfully created UPnp or Pmp port mapping for {port}");
                    }
                    catch (NatDeviceNotFoundException)
                    {
                        NebulaModel.Logger.Log.WarnInform("No UPnp or Pmp compatible/enabled NAT device found");
                    }
                    catch (MappingException)
                    {
                        NebulaModel.Logger.Log.WarnInform("Could not create UPnp or Pmp port mapping");
                    }
                });
            }

            ngrokManager = new Ngrok.NgrokManager(port);

            socket                       = new WebSocketServer(System.Net.IPAddress.IPv6Any, port);
            socket.Log.Level             = LogLevel.Debug;
            socket.AllowForwardedRequest = true; // This is required to make the websocket play nice with tunneling services like ngrok

            if (!string.IsNullOrWhiteSpace(Config.Options.ServerPassword))
            {
                socket.AuthenticationSchemes = AuthenticationSchemes.Basic;
                socket.UserCredentialsFinder = id => {
                    var name = id.Name;

                    // Return user name, password, and roles.
                    return(name == "nebula-player"
                           ? new NetworkCredential(name, Config.Options.ServerPassword)
                           : null); // If the user credentials are not found.
                };
            }

            DisableNagleAlgorithm(socket);
            WebSocketService.PacketProcessor = PacketProcessor;
            WebSocketService.PlayerManager   = PlayerManager;
            socket.AddWebSocketService <WebSocketService>("/socket", wse => new WebSocketService());
            try
            {
                socket.KeepClean = Config.Options.CleanupInactiveSessions;
                socket.Start();
            }catch (System.InvalidOperationException e)
            {
                InGamePopup.ShowError("Error", "An error occurred while hosting the game: " + e.Message, "Close");
                Stop();
                return;
            }

            ((LocalPlayer)Multiplayer.Session.LocalPlayer).IsHost = true;

            ((LocalPlayer)Multiplayer.Session.LocalPlayer).SetPlayerData(new PlayerData(
                                                                             PlayerManager.GetNextAvailablePlayerId(),
                                                                             GameMain.localPlanet?.id ?? -1,
                                                                             Config.Options.GetMechaColors(),
                                                                             !string.IsNullOrWhiteSpace(Config.Options.Nickname) ? Config.Options.Nickname : GameMain.data.account.userName), loadSaveFile);

            Task.Run(async() =>
            {
                if (ngrokManager.IsNgrokActive())
                {
                    DiscordManager.UpdateRichPresence(ip: await ngrokManager.GetNgrokAddressAsync(), updateTimestamp: true);
                }
                else
                {
                    DiscordManager.UpdateRichPresence(ip: $"{(Config.Options.IPConfiguration != IPUtils.IPConfiguration.IPv6 ? await IPUtils.GetWANv4Address() : string.Empty)};" +
                                                      $"{(Config.Options.IPConfiguration != IPUtils.IPConfiguration.IPv4 ? await IPUtils.GetWANv6Address() : string.Empty)};" +
                                                      $"{port}",
                                                      updateTimestamp: true);
                }
            });

            NebulaModAPI.OnMultiplayerGameStarted?.Invoke();
        }
Exemplo n.º 6
0
        public override void Start()
        {
            foreach (Assembly assembly in AssembliesUtils.GetNebulaAssemblies())
            {
                PacketUtils.RegisterAllPacketNestedTypesInAssembly(assembly, PacketProcessor);
            }
            PacketUtils.RegisterAllPacketProcessorsInCallingAssembly(PacketProcessor, false);

            foreach (Assembly assembly in NebulaModAPI.TargetAssemblies)
            {
                PacketUtils.RegisterAllPacketNestedTypesInAssembly(assembly, PacketProcessor);
                PacketUtils.RegisterAllPacketProcessorsInAssembly(assembly, PacketProcessor, false);
            }
#if DEBUG
            PacketProcessor.SimulateLatency = true;
#endif

            clientSocket            = new WebSocket($"ws://{serverEndpoint}/socket");
            clientSocket.Log.Level  = LogLevel.Debug;
            clientSocket.OnOpen    += ClientSocket_OnOpen;
            clientSocket.OnClose   += ClientSocket_OnClose;
            clientSocket.OnMessage += ClientSocket_OnMessage;

            var currentLogOutput = clientSocket.Log.Output;
            clientSocket.Log.Output = (logData, arg2) =>
            {
                currentLogOutput(logData, arg2);

                // This method of detecting an authentication failure is super finicky, however there is no other way to do this in the websocket package we are currently using
                if (logData.Level == LogLevel.Fatal && logData.Message == "Requires the authentication.")
                {
                    websocketAuthenticationFailure = true;
                }
            };

            if (!string.IsNullOrWhiteSpace(serverPassword))
            {
                clientSocket.SetCredentials("nebula-player", serverPassword, true);
            }

            websocketAuthenticationFailure = false;

            clientSocket.Connect();

            ((LocalPlayer)Multiplayer.Session.LocalPlayer).IsHost = false;

            if (Config.Options.RememberLastIP)
            {
                // We've successfully connected, set connection as last ip, cutting out "ws://" and "/socket"
                Config.Options.LastIP = serverEndpoint.ToString();
                Config.SaveOptions();
            }

            if (Config.Options.RememberLastClientPassword && !string.IsNullOrWhiteSpace(serverPassword))
            {
                Config.Options.LastClientPassword = serverPassword;
                Config.SaveOptions();
            }

            NebulaModAPI.OnMultiplayerGameStarted?.Invoke();
        }