public void RegisterNetworkableEntities(TypeRegistryBuilder typeRegistryBuilder)
        {
            //Register all entity classes that have been marked networkable
            //This includes classes not marked with LinkEntityToClass since base types can be mapped to
            foreach (var type in typeof(ClientEntities)
                     .Assembly
                     .GetTypes()
                     .ToList()
                     .Where(type => typeof(BaseEntity).IsAssignableFrom(type) &&
                            type.GetCustomAttribute <NetworkableAttribute>() != null))
            {
                var networkableAttr = type.GetCustomAttribute <NetworkableAttribute>();

                //All entities use this because they don't share a base class
                //Make sure not to replace words in names, just the namespace
                var mapsFromType = networkableAttr.MapsFromType ?? type.FullName.Replace(".Client.", ".Server.");

                typeRegistryBuilder
                .NewBuilder(type)
                .AddNetworkedFields()
                .AddNetworkedProperties()
                .MapsFromType(mapsFromType)
                .WithFactory(EntityFactory)
                .Build();
            }
        }
Example #2
0
        public static void RegisterSharedTypes(TypeRegistryBuilder typeRegistryBuilder, IEngineModels engineModels)
        {
            if (typeRegistryBuilder == null)
            {
                throw new ArgumentNullException(nameof(typeRegistryBuilder));
            }

            typeRegistryBuilder.RegisterArrayConverter(typeof(ListConverter <>));

            typeRegistryBuilder.RegisterType(typeof(bool), BooleanConverter.Instance);

            typeRegistryBuilder.RegisterType(typeof(sbyte), Int8Converter.Instance);
            typeRegistryBuilder.RegisterType(typeof(short), Int16Converter.Instance);
            typeRegistryBuilder.RegisterType(typeof(int), Int32Converter.Instance);
            typeRegistryBuilder.RegisterType(typeof(long), Int64Converter.Instance);

            typeRegistryBuilder.RegisterType(typeof(byte), UInt8Converter.Instance);
            typeRegistryBuilder.RegisterType(typeof(ushort), UInt16Converter.Instance);
            typeRegistryBuilder.RegisterType(typeof(uint), UInt32Converter.Instance);
            typeRegistryBuilder.RegisterType(typeof(ulong), UInt64Converter.Instance);

            typeRegistryBuilder.RegisterType(typeof(float), FloatConverter.Instance);
            typeRegistryBuilder.RegisterType(typeof(double), DoubleConverter.Instance);

            typeRegistryBuilder.RegisterType(typeof(string), StringConverter.Instance);

            typeRegistryBuilder.RegisterType(typeof(Vector2), Vector2Converter.Instance);
            typeRegistryBuilder.RegisterType(typeof(Vector3), Vector3Converter.Instance);

            typeRegistryBuilder.RegisterType(typeof(IModel), new ModelConverter(engineModels));
        }
        public void RegisterNetworkableEntities(TypeRegistryBuilder typeRegistryBuilder)
        {
            var registeredTypes = new HashSet <Type>();

            void AddType(Type type, NetworkableAttribute networkableAttr)
            {
                //MapsFromType is not required on the server side

                typeRegistryBuilder
                .NewBuilder(type)
                .AddNetworkedFields()
                .AddNetworkedProperties()
                .Build();

                registeredTypes.Add(type);
            }

            bool AddBaseType(Type type)
            {
                if (type != null)
                {
                    //Already registered, we're done
                    if (registeredTypes.Contains(type))
                    {
                        return(true);
                    }

                    var networkableAttr = type.GetCustomAttribute <NetworkableAttribute>();

                    if (networkableAttr != null)
                    {
                        if (!networkableAttr.UseBaseType)
                        {
                            AddType(type, networkableAttr);
                            return(true);
                        }

                        //Base class also depends on its base, try that
                        //This will recursively register all base types
                        var registered = AddBaseType(type.BaseType);

                        if (!registered)
                        {
                            throw new NotSupportedException($"The type {type.FullName} is declared as using a base class for networking, but no base class is configured for networking");
                        }

                        typeRegistryBuilder.RegisterRemappedType(type, type.BaseType);

                        //Register the type as networked so any subclasses will know
                        registeredTypes.Add(type);

                        return(registered);
                    }
                }

                return(false);
            }

            foreach (var entityMetaData in EntityDictionary.Types)
            {
                //Don't need to check return value because entities can be server only
                AddBaseType(entityMetaData.Type);
            }
        }
        public void RegisterObjectListTypes(TypeRegistryBuilder typeRegistryBuilder)
        {
            SharedObjectListTypes.RegisterSharedTypes(typeRegistryBuilder, _engineModels);

            _entities.RegisterNetworkableEntities(typeRegistryBuilder);
        }
Example #5
0
        public EngineServerHost(IEngine engine, ILogger logger, IBridge gameBridge)
        {
            _engine = engine ?? throw new ArgumentNullException(nameof(engine));
            _logger = logger ?? throw new ArgumentNullException(nameof(logger));

            CommandContext = _engine.CommandSystem.CreateContext("ServerContext");

            _ipname = CommandContext.RegisterVariable(new VariableInfo("ip")
                                                      .WithHelpInfo("The IP address to use for server hosts")
                                                      .WithValue(NetConstants.LocalHost));

            _hostport = CommandContext.RegisterVariable(new VariableInfo("hostport")
                                                        .WithHelpInfo("The port to use for server hosts")
                                                        .WithValue(0));

            _defport = CommandContext.RegisterVariable(new VariableInfo("port")
                                                       .WithHelpInfo("The default port to use for server hosts")
                                                       .WithValue(NetConstants.DefaultServerPort));

            _sv_timeout = CommandContext.RegisterVariable(new VariableInfo("sv_timeout")
                                                          .WithHelpInfo("Maximum time to wait before timing out client connections")
                                                          .WithValue(60));

            _net_sv_log_messages = CommandContext.RegisterVariable(new VariableInfo("net_sv_log_messages")
                                                                   .WithHelpInfo("Whether to log received client-to-server network messages")
                                                                   .WithValue(false)
                                                                   .WithBooleanFilter()
                                                                   .WithChangeHandler((ref VariableChangeEvent @event) =>
            {
                if (_netServer != null)
                {
                    _netServer.TraceMessageLogging = @event.Boolean;
                }
            }));

            _maxPlayers = CommandContext.RegisterVariable(new VariableInfo("maxplayers")
                                                          .WithHelpInfo("The maximum number of players that can connect to this server")
                                                          .WithValue(_engine.IsDedicatedServer ? 6 : NetConstants.MinClients)
                                                          .WithDelegateFilter((ref string _, ref float __) =>
            {
                if (Active)
                {
                    _logger.Information("maxplayers cannot be changed while a server is running.");
                }

                return(!Active);
            })
                                                          .WithNumberFilter()
                                                          .WithMinMaxFilter(NetConstants.MinClients, NetConstants.MaxClients));

            if (_engine.CommandLine.TryGetValue("-port", out var portValue))
            {
                _hostport.String = portValue;
            }

            if (_engine.CommandLine.TryGetValue("-maxplayers", out var maxPlayersValue))
            {
                _maxPlayers.String = maxPlayersValue;
            }

            _serverModels = new ServerModels(_engine.ModelManager, Framework.FallbackModelName);

            LoadGameServer(gameBridge);

            var objectListTypeRegistryBuilder = new TypeRegistryBuilder();

            _serverNetworking.RegisterObjectListTypes(objectListTypeRegistryBuilder);

            _objectListTypeRegistry = objectListTypeRegistryBuilder.BuildRegistry();

            var dataSetBuilder = new BinaryDataSetBuilder();

            RegisterNetworkBinaryData(dataSetBuilder);

            _binaryDataDescriptorSet = dataSetBuilder.BuildTransmissionSet();
        }