public void OnLoadResultCommand(Commands.LoadResult res, NetPeer peer)
        {
            Debug.Assert(MasterState == State.Loading);
            var client = Clients.Find(c => c.Peer == peer);

            Debug.Assert(client != null);
            Debug.Assert(client.State == State.Loading);

            if (res.Success)
            {
                Debug.Log("Client loaded");
            }
            else
            {
                // TODO: stop simulation / cancel loading for other clients
                Debug.LogError($"Client failed to load: ${res.ErrorMessage}");

                // TODO: reset all other clients

                Debug.Log($"Failed to start '{Simulation.Name}' simulation");

                // TODO: update simulation status in DB
                // simulation.Status = "Invalid";
                // db.Update(simulation);

                // NotificationManager.SendNotification("simulation", SimulationResponse.Create(simulation), simulation.Owner);

                Loader.ResetLoaderScene();

                Clients.Clear();
                return;
            }

            client.State = State.Ready;

            if (!Loader.Instance.PendingSimulation.ApiOnly.GetValueOrDefault())
            {
                if (Clients.All(c => c.State == State.Ready))
                {
                    Debug.Log("All clients are ready. Resuming time.");

                    var run = new Commands.Run();
                    foreach (var c in Clients)
                    {
                        Packets.Send(c.Peer, run, DeliveryMethod.ReliableOrdered);
                        c.State = State.Running;
                    }

                    MasterState = State.Running;

                    Loader.Instance.CurrentSimulation = Loader.Instance.PendingSimulation;
                    Loader.Instance.PendingSimulation = null;

                    SimulatorManager.SetTimeScale(1.0f);
                }
            }
        }
Exemple #2
0
        void DownloadVehicleBundles(Commands.Load load)
        {
            try
            {
                using (var web = new WebClient())
                {
                    foreach (var agent in load.Agents)
                    {
                        var vehiclePath = Path.Combine(Web.Config.Root, agent.Name);
                        if (!File.Exists(vehiclePath))
                        {
                            Debug.Log($"Downloading {agent.Name}");

                            web.DownloadFile($"http://{Master.EndPoint.Address}:8080/download/vehicle/{agent.Name}", agent.Name);
                        }
                        else
                        {
                            Debug.Log($"Vehicle {agent.Name} exists");
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Debug.LogException(ex);

                var err = new Commands.LoadResult()
                {
                    Success      = false,
                    ErrorMessage = ex.ToString(),
                };
                Packets.Send(Master, err, DeliveryMethod.ReliableOrdered);

                Loader.ResetLoaderScene();
            }
        }
Exemple #3
0
        void LoadMapBundle(Commands.Load load)
        {
            DownloadVehicleBundles(load);

            var mapPath = Path.Combine(Web.Config.Root, load.Name);

            var mapBundle = AssetBundle.LoadFromFile(mapPath);

            if (mapBundle == null)
            {
                throw new Exception($"Failed to load environment from '{mapPath}' asset bundle");
            }

            var scenes = mapBundle.GetAllScenePaths();

            if (scenes.Length != 1)
            {
                throw new Exception($"Unsupported environment in '{mapPath}' asset bundle, only 1 scene expected");
            }

            var sceneName = Path.GetFileNameWithoutExtension(scenes[0]);

            var loader = SceneManager.LoadSceneAsync(sceneName);

            loader.completed += op =>
            {
                if (op.isDone)
                {
                    mapBundle.Unload(false);

                    try
                    {
                        var prefabs = LoadVehicleBundles(load);

                        Loader.Instance.SimConfig = new SimulationConfig()
                        {
                            Name           = load.Name,
                            ApiOnly        = load.ApiOnly,
                            Headless       = load.Headless,
                            Interactive    = load.Interactive,
                            TimeOfDay      = DateTime.ParseExact(load.TimeOfDay, "o", CultureInfo.InvariantCulture),
                            Rain           = load.Rain,
                            Fog            = load.Fog,
                            Wetness        = load.Wetness,
                            Cloudiness     = load.Cloudiness,
                            UseTraffic     = load.UseTraffic,
                            UsePedestrians = load.UsePedestrians,
                            Agents         = load.Agents.Zip(prefabs, (agent, prefab) =>
                            {
                                var config = new AgentConfig()
                                {
                                    Name       = agent.Name,
                                    Prefab     = prefab,
                                    Connection = agent.Connection,
                                    Sensors    = agent.Sensors,
                                };

                                if (!string.IsNullOrEmpty(agent.Bridge))
                                {
                                    config.Bridge = Web.Config.Bridges.Find(bridge => bridge.Name == agent.Bridge);
                                    if (config.Bridge == null)
                                    {
                                        throw new Exception($"Bridge {agent.Bridge} not found");
                                    }
                                }

                                return(config);
                            }).ToArray(),
                        };

                        Loader.CreateSimulationManager();

                        Debug.Log($"Client ready to start");

                        var result = new Commands.LoadResult()
                        {
                            Success = true,
                        };
                        Packets.Send(Master, result, DeliveryMethod.ReliableOrdered);

                        ClientState = State.Ready;
                    }
                    catch (Exception ex)
                    {
                        Debug.LogException(ex);

                        var err = new Commands.LoadResult()
                        {
                            Success      = false,
                            ErrorMessage = ex.ToString(),
                        };
                        Packets.Send(Master, err, DeliveryMethod.ReliableOrdered);

                        Loader.ResetLoaderScene();
                    }
                }
            };
        }
Exemple #4
0
        public void OnLoadCommand(Commands.Load load)
        {
            Debug.Assert(ClientState == State.Connected);
            ClientState = State.Loading;

            Debug.Log("Preparing simulation");

            try
            {
                using (var web = new WebClient())
                {
                    var mapPath = Path.Combine(Web.Config.Root, load.Name);

                    if (!File.Exists(mapPath))
                    {
                        Debug.Log($"Downloading {load.Name}");

                        AsyncCompletedEventHandler mapDownloadHandler          = null;
                        Action <object, AsyncCompletedEventArgs> mapDownloaded = (sender, args) =>
                        {
                            web.DownloadFileCompleted -= mapDownloadHandler;

                            if (args.Error != null)
                            {
                                Debug.LogException(args.Error);

                                var err = new Commands.LoadResult()
                                {
                                    Success      = false,
                                    ErrorMessage = args.Error.ToString(),
                                };
                                Packets.Send(Master, err, DeliveryMethod.ReliableOrdered);
                                return;
                            }

                            LoadMapBundle(load);
                        };

                        mapDownloadHandler         = new AsyncCompletedEventHandler(mapDownloaded);
                        web.DownloadFileCompleted += mapDownloadHandler;
                        web.DownloadFileAsync(new Uri($"http://{Master.EndPoint.Address}:8080/download/map/{load.Name}"), mapPath);
                    }
                    else
                    {
                        Debug.Log($"Map {load.Name} exists");
                        LoadMapBundle(load);
                    }
                }
            }
            catch (Exception ex)
            {
                Debug.LogException(ex);

                var err = new Commands.LoadResult()
                {
                    Success      = false,
                    ErrorMessage = ex.ToString(),
                };
                Packets.Send(Master, err, DeliveryMethod.ReliableOrdered);

                Loader.ResetLoaderScene();
            }
        }
        void LoadMapBundle(Commands.Load load, string mapBundlePath)
        {
            var vehicleBundles = new List <string>();

            DownloadVehicleBundles(load, vehicleBundles, () =>
            {
                var zip = new ZipFile(mapBundlePath);
                {
                    string manfile;
                    ZipEntry entry = zip.GetEntry("manifest");
                    using (var ms = zip.GetInputStream(entry))
                    {
                        int streamSize = (int)entry.Size;
                        byte[] buffer  = new byte[streamSize];
                        streamSize     = ms.Read(buffer, 0, streamSize);
                        manfile        = Encoding.UTF8.GetString(buffer);
                    }

                    Manifest manifest = new Deserializer().Deserialize <Manifest>(manfile);

                    var texStream     = zip.GetInputStream(zip.GetEntry($"{manifest.bundleGuid}_environment_textures"));
                    var textureBundle = AssetBundle.LoadFromStream(texStream, 0, 1 << 20);

                    string platform = SystemInfo.operatingSystemFamily == OperatingSystemFamily.Windows ? "windows" : "linux";
                    var mapStream   = zip.GetInputStream(zip.GetEntry($"{manifest.bundleGuid}_environment_main_{platform}"));
                    var mapBundle   = AssetBundle.LoadFromStream(mapStream, 0, 1 << 20);

                    if (mapBundle == null || textureBundle == null)
                    {
                        throw new Exception($"Failed to load environment from '{load.MapName}' asset bundle");
                    }

                    textureBundle.LoadAllAssets();

                    var scenes = mapBundle.GetAllScenePaths();
                    if (scenes.Length != 1)
                    {
                        throw new Exception($"Unsupported environment in '{load.MapName}' asset bundle, only 1 scene expected");
                    }

                    var sceneName = Path.GetFileNameWithoutExtension(scenes[0]);

                    var loader        = SceneManager.LoadSceneAsync(sceneName);
                    loader.completed += op =>
                    {
                        if (op.isDone)
                        {
                            textureBundle.Unload(false);
                            mapBundle.Unload(false);
                            zip.Close();

                            try
                            {
                                var prefabs = LoadVehicleBundles(vehicleBundles);

                                Loader.Instance.SimConfig = new SimulationConfig()
                                {
                                    Name           = load.Name,
                                    ApiOnly        = load.ApiOnly,
                                    Headless       = load.Headless,
                                    Interactive    = load.Interactive,
                                    TimeOfDay      = DateTime.ParseExact(load.TimeOfDay, "o", CultureInfo.InvariantCulture),
                                    Rain           = load.Rain,
                                    Fog            = load.Fog,
                                    Wetness        = load.Wetness,
                                    Cloudiness     = load.Cloudiness,
                                    UseTraffic     = load.UseTraffic,
                                    UsePedestrians = load.UsePedestrians,
                                    Agents         = load.Agents.Zip(prefabs, (agent, prefab) =>
                                    {
                                        var config = new AgentConfig()
                                        {
                                            Name       = agent.Name,
                                            Prefab     = prefab,
                                            Connection = agent.Connection,
                                            Sensors    = agent.Sensors,
                                        };

                                        if (!string.IsNullOrEmpty(agent.Bridge))
                                        {
                                            config.Bridge = Web.Config.Bridges.Find(bridge => bridge.Name == agent.Bridge);
                                            if (config.Bridge == null)
                                            {
                                                throw new Exception($"Bridge {agent.Bridge} not found");
                                            }
                                        }

                                        return(config);
                                    }).ToArray(),
                                };

                                Loader.CreateSimulationManager();

                                Debug.Log($"Client ready to start");

                                var result = new Commands.LoadResult()
                                {
                                    Success = true,
                                };
                                Packets.Send(Master, result, DeliveryMethod.ReliableOrdered);

                                ClientState = State.Ready;
                            }
                            catch (Exception ex)
                            {
                                Debug.LogException(ex);

                                var err = new Commands.LoadResult()
                                {
                                    Success      = false,
                                    ErrorMessage = ex.ToString(),
                                };
                                Packets.Send(Master, err, DeliveryMethod.ReliableOrdered);

                                Loader.ResetLoaderScene();
                            }
                        }
                    };
                }
            });
        }
        void DownloadVehicleBundles(Commands.Load load, List <string> bundles, Action finished)
        {
            try
            {
                int count = 0;

                var agents = load.Agents;
                for (int i = 0; i < load.Agents.Length; i++)
                {
                    VehicleModel vehicleModel;
                    using (var db = DatabaseManager.Open())
                    {
                        var sql = Sql.Builder.Where("url = @0", agents[i].Url);
                        vehicleModel = db.SingleOrDefault <VehicleModel>(sql);
                    }

                    if (vehicleModel == null)
                    {
                        Debug.Log($"Downloading {agents[i].Name} from {agents[i].Url}");

                        vehicleModel = new VehicleModel()
                        {
                            Name       = agents[i].Name,
                            Url        = agents[i].Url,
                            BridgeType = agents[i].Bridge,
                            LocalPath  = WebUtilities.GenerateLocalPath("Vehicles"),
                            Sensors    = agents[i].Sensors,
                        };
                        bundles.Add(vehicleModel.LocalPath);

                        DownloadManager.AddDownloadToQueue(new Uri(vehicleModel.Url), vehicleModel.LocalPath, null,
                                                           (success, ex) =>
                        {
                            if (ex != null)
                            {
                                var err = new Commands.LoadResult()
                                {
                                    Success      = false,
                                    ErrorMessage = ex.ToString(),
                                };
                                Packets.Send(Master, err, DeliveryMethod.ReliableOrdered);
                                return;
                            }

                            using (var db = DatabaseManager.Open())
                            {
                                db.Insert(vehicleModel);
                            }

                            if (Interlocked.Increment(ref count) == bundles.Count)
                            {
                                finished();
                            }
                        }
                                                           );
                    }
                    else
                    {
                        Debug.Log($"Vehicle {agents[i].Name} exists");

                        bundles.Add(vehicleModel.LocalPath);
                        if (Interlocked.Increment(ref count) == bundles.Count)
                        {
                            finished();
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Debug.LogException(ex);

                var err = new Commands.LoadResult()
                {
                    Success      = false,
                    ErrorMessage = ex.ToString(),
                };
                Packets.Send(Master, err, DeliveryMethod.ReliableOrdered);

                Loader.ResetLoaderScene();
            }
        }
        public void OnLoadCommand(Commands.Load load)
        {
            Debug.Assert(ClientState == State.Connected);
            ClientState = State.Loading;

            Debug.Log("Preparing simulation");

            try
            {
                MapModel map;
                using (var db = DatabaseManager.Open())
                {
                    var sql = Sql.Builder.Where("url = @0", load.MapUrl);
                    map = db.SingleOrDefault <MapModel>(sql);
                }

                if (map == null)
                {
                    Debug.Log($"Downloading {load.MapName} from {load.MapUrl}");

                    map = new MapModel()
                    {
                        Name      = load.MapName,
                        Url       = load.MapUrl,
                        LocalPath = WebUtilities.GenerateLocalPath("Maps"),
                    };

                    using (var db = DatabaseManager.Open())
                    {
                        db.Insert(map);
                    }

                    DownloadManager.AddDownloadToQueue(new Uri(map.Url), map.LocalPath, null, (success, ex) =>
                    {
                        if (ex != null)
                        {
                            map.Error = ex.Message;
                            using (var db = DatabaseManager.Open())
                            {
                                db.Update(map);
                            }

                            Debug.LogException(ex);
                        }

                        if (success)
                        {
                            LoadMapBundle(load, map.LocalPath);
                        }
                        else
                        {
                            var err = new Commands.LoadResult()
                            {
                                Success      = false,
                                ErrorMessage = ex.ToString(),
                            };
                            Packets.Send(Master, err, DeliveryMethod.ReliableOrdered);
                            return;
                        }
                    });
                }
                else
                {
                    Debug.Log($"Map {load.MapName} exists");
                    LoadMapBundle(load, map.LocalPath);
                }
            }
            catch (Exception ex)
            {
                Debug.LogException(ex);

                var err = new Commands.LoadResult()
                {
                    Success      = false,
                    ErrorMessage = ex.ToString(),
                };
                Packets.Send(Master, err, DeliveryMethod.ReliableOrdered);

                Loader.ResetLoaderScene();
            }
        }