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); } } }
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(); } }
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(); } } }; }
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(); } }