|
| 1 | +using Microsoft.Extensions.Logging; |
| 2 | + |
| 3 | +namespace RLBotCS.ManagerTools; |
| 4 | + |
| 5 | +public class CustomMap |
| 6 | +{ |
| 7 | + private static readonly ILogger Logger = Logging.GetLogger("CustomMap"); |
| 8 | + |
| 9 | + public const string RL_MAP_KEY = "Haunted_TrainStation_P"; |
| 10 | + private const string MAP_SACRIFICE = RL_MAP_KEY + ".upk"; |
| 11 | + private const string TEMP_MAP_NAME = RL_MAP_KEY + "_copy.upk"; |
| 12 | + |
| 13 | + public static bool IsCustomMap(string path) |
| 14 | + { |
| 15 | + bool isMapPath = path.EndsWith(".upk") || path.EndsWith(".udk"); |
| 16 | + return isMapPath && File.Exists(path); |
| 17 | + } |
| 18 | + |
| 19 | + private static string GetMapsBasePath() |
| 20 | + { |
| 21 | + // rocketleague/Binaries/Win64/RocketLeague.exe |
| 22 | + string? gamePath = LaunchManager.GetRocketLeaguePath(); |
| 23 | + if (gamePath == null) |
| 24 | + { |
| 25 | + // throw exception because we shouldn't construct this class before Rocket League has launched |
| 26 | + throw new InvalidOperationException("Could not find Rocket League executable"); |
| 27 | + } |
| 28 | + |
| 29 | + // rocketleague/ |
| 30 | + string basePath = Path.GetDirectoryName( |
| 31 | + Path.GetDirectoryName(Path.GetDirectoryName(gamePath)!)! |
| 32 | + )!; |
| 33 | + // rocketleague/TAGame/CookedPCConsole |
| 34 | + return Path.Combine(basePath, "TAGame", "CookedPCConsole"); |
| 35 | + } |
| 36 | + |
| 37 | + private string _originalMapPath; |
| 38 | + private string _tempMapPath; |
| 39 | + |
| 40 | + public CustomMap(string path) |
| 41 | + { |
| 42 | + if (!IsCustomMap(path)) |
| 43 | + { |
| 44 | + // throw exception because we shouldn't construct this class with an invalid path |
| 45 | + throw new ArgumentException("Provided path is not a valid custom map"); |
| 46 | + } |
| 47 | + |
| 48 | + string mapsBasePath = GetMapsBasePath(); |
| 49 | + _originalMapPath = Path.Combine(mapsBasePath, MAP_SACRIFICE); |
| 50 | + _tempMapPath = Path.Combine(mapsBasePath, TEMP_MAP_NAME); |
| 51 | + |
| 52 | + Logger.LogInformation($"Custom map detected. Temporarily replacing {RL_MAP_KEY}"); |
| 53 | + |
| 54 | + // don't overwrite the original map if it already exists |
| 55 | + if (!File.Exists(_tempMapPath)) |
| 56 | + { |
| 57 | + // copy the original map to a temporary file so we can restore it later |
| 58 | + File.Copy(_originalMapPath, _tempMapPath, false); |
| 59 | + } |
| 60 | + |
| 61 | + // replace the original map with the custom map |
| 62 | + File.Copy(path, _originalMapPath, true); |
| 63 | + } |
| 64 | + |
| 65 | + public void TryRestoreOriginalMap() |
| 66 | + { |
| 67 | + if (!File.Exists(_tempMapPath)) |
| 68 | + return; |
| 69 | + |
| 70 | + File.Copy(_tempMapPath, _originalMapPath, true); |
| 71 | + File.Delete(_tempMapPath); |
| 72 | + Logger.LogInformation($"Restored original map of {RL_MAP_KEY}"); |
| 73 | + } |
| 74 | + |
| 75 | + ~CustomMap() |
| 76 | + { |
| 77 | + // Doing this in the destructor to ensure that the original map is restored, |
| 78 | + // even if an invalid state occurs elsewhere |
| 79 | + TryRestoreOriginalMap(); |
| 80 | + } |
| 81 | +} |
0 commit comments