예제 #1
0
    public void StartMachine(ICoroutineScheduler scheduler, DependencyContainer globalDependencies)
    {
        #region Networking

        var gameSettings = _gameSettingsProvider.ActiveSettings;

        var networking           = GameObject.Find("Networking");
        var lidgrenTransporter   = networking.GetComponentInChildren <LidgrenNetworkTransporter>();
        var networkMessageSender = networking.GetComponentInChildren <QueueingMessageSender>();
        networkMessageSender.Transporter = lidgrenTransporter;

        var connectionIdPool = new ConnectionIdPool(maxConnectionIds: 64);
        //var connectionManager = new DefaultConnectionManager(lidgrenTransporter, connectionIdPool);
        var natFacilitatorEndpoint    = Ipv4Endpoint.Parse(gameSettings.Other.NatFacilitatorEndpoint).ToIpEndPoint();
        var natFacilitatorConnection  = new LidgrenNatFacilitatorConnection(natFacilitatorEndpoint, lidgrenTransporter);
        var natPunchClient            = new LidgrenNatPunchClient(scheduler, natFacilitatorConnection);
        var connectionAttemptTimeout  = gameSettings.Other.ConnectionAttemptTimeout;
        var natPunchConnectionManager = new LidgrenPunchThroughFacilitator(lidgrenTransporter, scheduler, natPunchClient,
                                                                           connectionAttemptTimeout, connectionIdPool);

        lidgrenTransporter.ConnectionIdPool = connectionIdPool;
        var latencyInfo = new LatencyInfo(connectionIdPool.MaxConnectionIds);

        var groupRouterConfig = ConnectionGroups.RouterConfig;
        var networkSystems    = NetworkSystem.Create(
            lidgrenTransporter,
            lidgrenTransporter,
            groupRouterConfig,
            ConnectionGroups.Default,
            ReplicationObjects.Factories,
            networkMessageSender,
            natPunchConnectionManager,
            latencyInfo,
            globalDependencies);
        var voloServer = networking.GetComponentInChildren <VoloNetworkServer>();
        voloServer.NetworkSystems           = networkSystems;
        voloServer.NatFacilitatorConnection = natFacilitatorConnection;
        var voloClient = networking.GetComponentInChildren <VoloNetworkClient>();
        voloClient.NetworkSystems = networkSystems;
        voloClient.LatencyInfo    = latencyInfo;

        var activeNetwork = new ActiveNetwork(networkSystems, voloServer, voloClient, scheduler);
        _playingData.ActiveNetwork       = activeNetwork;
        _mainMenuData.ActiveNetwork      = activeNetwork;
        _serverBrowserData.ActiveNetwork = activeNetwork;

        /*
         * Create lean and mean main menu system that allows a player to choose between single and multiplayer
         *
         * Notes:
         *   - Keep as much logic that is generic to both single and multiplayer generic. Don't make a special code path
         *     for singleplayer unless it is a feature that is only available in singleplayer.
         *   - Options menu should be as game independent as possible, not relying on a specific singleplayer state for example.
         *   - State machine transitions should also become separate states such that we can handle them in a better, cleaner way
         *
         *
         * Case 1: Single player game
         * - Boot game, start singleplayer, fly for one round, quit game
         *   - On boot: create instance of a network system
         *   - Pass network system into the state machine
         *   - When going into the playing state, spawn/despawn/respawn pilot through replicator
         *
         * Case 2: Multiplayer game - server
         * - Boot game, main screen: choose to create multiplayer server,
         *   - on boot create instance of network system
         *   - when in starting multiplayer server state open transporter
         *   - when a spawnpoint is selected replicate the player
         * - separate state machine for multiplayer logic
         *
         * Case 3: Multiplayer game - client
         * - Boot game, main screen: choose to join a multiplayer server
         *   - server list: allow client to join a game, show if join/connect is in progress, allow for cancellation
         *   - when a spawnpoint is selected request a spawn to the server
         */


        #endregion

        _machine = new StateMachine <VoloStateMachine>(this, scheduler);

        _machine.AddState(States.NewsFlash, new NewsFlash(_machine, _newsFlashData))
        .Permit(States.TitleScreen);

        _machine.AddState(States.TitleScreen, new TitleScreen(_machine, _titleScreenData))
        .PermitChild(States.Frozen)
        .Permit(States.MainMenu);

        _machine.AddState(States.MainMenu, new MainMenu(_machine, _mainMenuData))
        .PermitChild(States.Frozen)
        .Permit(States.TitleScreen)
        .Permit(States.ServerBrowser)
        .Permit(States.SpawnScreen);

        _machine.AddState(States.ServerBrowser, new ServerBrowser(_machine, _serverBrowserData))
        .PermitChild(States.Frozen)
        .Permit(States.MainMenu)
        .Permit(States.SpawnScreen);

        _machine.AddState(States.SpawnScreen, new SpawnScreen(_machine, _spawnScreenData))
        .PermitChild(States.Frozen)
        .PermitChild(States.OptionsMenu)
        .Permit(States.MainMenu)
        .Permit(States.Playing);

        _machine.AddState(States.Playing, new Playing(_machine, _playingData, _flyWingsuitData, _flyParachuteData, _spectatorModeData))
        .PermitChild(States.Frozen)
        .PermitChild(States.OptionsMenu)
        .Permit(States.SpawnScreen);

        _machine.AddState(States.OptionsMenu, new OptionsMenuState(_machine, _optionsMenuData))
        .PermitChild(States.Frozen)
        .Permit(States.SpawnScreen)
        .Permit(States.MainMenu);

        _machine.AddState(States.Frozen, new Frozen(_machine, _frozenData));

        _machine.Transition(States.NewsFlash);
    }
예제 #2
0
    public RamnetBase(
        ICoroutineScheduler coroutineScheduler,
        LidgrenNetworkTransporter transporter,
        IPEndPoint natFacilitatorEndpoint,
        IMessageSender messageSender,
        IDictionary <ObjectType, GameObject> prefabs,
        DependencyContainer dependencyContainer)
    {
        _messageSender = messageSender;
        _transporter   = transporter;
        ILatencyInfo latencyInfo = _transporter;

        var networkMessageTypes = MessageExtensions.GenerateNetworkIds(MessageExtensions.GetNetworkMessageTypes(Assembly.GetExecutingAssembly()));
        var objectMessageTypes  = MessageExtensions.GenerateNetworkIds(MessageExtensions.GetObjectMessageTypes(Assembly.GetExecutingAssembly()));

        _messagePool = new MessagePool(MessageExtensions.CreateMessagePools(networkMessageTypes));
        var objectMessagePools = MessageExtensions.CreateMessagePools(objectMessageTypes);

        var routerConfig = new TransportRouterConfig(
            new KeyValuePair <TransportGroupId, TransportGroupConfig>(NetworkGroup.Default,
                                                                      new TransportGroupConfig(32)));

        _natFacilitatorConnection = new LidgrenNatFacilitatorConnection(natFacilitatorEndpoint, _transporter);
        _natPunchClient           = new LidgrenNatPunchClient(coroutineScheduler, _natFacilitatorConnection, transporter);
        _connectionManager        = new LidgrenPunchThroughFacilitator(
            _transporter,
            coroutineScheduler,
            connectionAttemptTimeout: 10f,
            natPunchClient: _natPunchClient);
        _groupRouter = new TransportGroupRouter(_transporter, routerConfig);

        Func <ObjectMessageRouter> objectMessageDispatcherFactory =
            () => new ObjectMessageRouter(latencyInfo, objectMessageTypes);
        var networkMessagePool = new BasicObjectPool <ReplicatedObjectStore.ObjectMessageSender.MulticastNetworkMessage>(
            pool => new ReplicatedObjectStore.ObjectMessageSender.MulticastNetworkMessage(pool, networkMessageTypes[typeof(BasicMessage.ToObject)]));
        var messageSenderFactory = ReplicatedObjectStore.ObjectMessageSender.CreateFactory(
            messageSender,
            _groupRouter,
            NetworkGroup.Default,
            networkMessagePool);

        var objectDependencies = new List <object>();

        objectDependencies.Add(latencyInfo);
        foreach (var pool in objectMessagePools)
        {
            objectDependencies.Add(pool.Value);
        }
        var replicationDecorator = ReplicatedObjectStore.GameObjectReplicationDecorator(objectMessageDispatcherFactory,
                                                                                        messageSenderFactory,
                                                                                        objectDependencies,
                                                                                        objectMessageTypes);

        var gameObjectFactories = new Dictionary <ObjectType, Func <GameObject> >();

        foreach (var kvPair in prefabs)
        {
            var objectType = kvPair.Key;
            var prefab     = kvPair.Value;
            gameObjectFactories[objectType] = () => {
                var instance = GameObject.Instantiate(prefab);
                // TODO Copy dependencies into global object dependency container
                DependencyInjection.Inject(instance, dependencyContainer);
                return(instance);
            };
        }
        int replicatedObjectCapacity = 256;
        var objectMessageParser      = new ObjectMessageParser(objectMessageTypes);

        _replicatedObjectStore = new ReplicatedObjectStore(objectMessageParser, gameObjectFactories, replicationDecorator, replicatedObjectCapacity);

        _messageRouter = new MessageRouter(networkMessageTypes);
        _groupRouter.SetDataHandler(NetworkGroup.Default, _messageRouter);

        _connectionlessMessageSender = new ConnectionlessMessageSender(_transporter);

        _preExistingObjects = RamjetAnvil.RamNet.PreExistingObjects.FindAll();
    }