2022-02-16 21:39:36 +01:00
|
|
|
|
// Defines the process to monitor. We are not reading anything from the game’s memory, so it’s empty.
|
|
|
|
|
// We still need it though, LiveSplit will only run the auto splitter if the corresponding process is present.
|
|
|
|
|
// See https://github.com/LiveSplit/LiveSplit.AutoSplitters/blob/master/README.md#state-descriptors
|
|
|
|
|
state("EliteDangerous64") {}
|
|
|
|
|
|
|
|
|
|
// Executes when LiveSplit (re-)loads the auto splitter. Does general setup tasks.
|
|
|
|
|
// See https://github.com/LiveSplit/LiveSplit.AutoSplitters/blob/master/README.md#script-startup
|
|
|
|
|
startup {
|
|
|
|
|
// Relevant journal entries
|
|
|
|
|
vars.journalReader = null;
|
|
|
|
|
vars.journalEntries = new Dictionary<string, System.Text.RegularExpressions.Regex>();
|
|
|
|
|
vars.journalEntries["start"] =
|
2022-02-18 16:32:49 +01:00
|
|
|
|
new System.Text.RegularExpressions.Regex(@"\{ ""timestamp"":""(?<timestamp>.*)"", ""event"":""Undocked"", ""StationName"":""Garden Ring"", ""StationType"":"".*"", ""MarketID"":\d+(, ""Taxi"":(true|false), ""Multicrew"":(true|false))? \}");
|
2022-02-16 21:39:36 +01:00
|
|
|
|
vars.journalEntries["docked"] =
|
2022-02-18 16:32:49 +01:00
|
|
|
|
new System.Text.RegularExpressions.Regex(@"\{ ""timestamp"":""(?<timestamp>.*)"", ""event"":""Docked"", ""StationName"":""(?<station>.*)"", ""StationType"":"".*""(, ""Taxi"":(true|false), ""Multicrew"":(true|false))?, ""StarSystem"":""Pareco"", .*\}");
|
2022-02-18 16:55:58 +01:00
|
|
|
|
vars.journalEntries["died"] =
|
|
|
|
|
new System.Text.RegularExpressions.Regex(@"\{ ""timestamp"":""(?<timestamp>.*)"", ""event"":""Died"" .*\}");
|
2022-02-16 21:39:36 +01:00
|
|
|
|
|
2022-02-20 12:59:48 +01:00
|
|
|
|
// Journal file handling
|
|
|
|
|
vars.journalPath = Path.Combine(
|
|
|
|
|
Environment.GetFolderPath(Environment.SpecialFolder.UserProfile),
|
|
|
|
|
"Saved Games",
|
|
|
|
|
"Frontier Developments",
|
|
|
|
|
"Elite Dangerous"
|
|
|
|
|
);
|
|
|
|
|
vars.currentJournal = "none";
|
|
|
|
|
vars.updateJournalReader = (Action)delegate() {
|
2022-03-18 21:44:23 +01:00
|
|
|
|
FileInfo journalFile = new DirectoryInfo(vars.journalPath).GetFiles("journal.*.log").OrderByDescending(file => file.LastWriteTime).First();
|
2022-02-20 12:59:48 +01:00
|
|
|
|
print("Current journal file: " + vars.currentJournal + ", latest journal file: " + journalFile.Name);
|
|
|
|
|
if (journalFile.Name != vars.currentJournal) {
|
|
|
|
|
vars.journalReader = new StreamReader(new FileStream(journalFile.FullName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite));
|
|
|
|
|
vars.currentJournal = journalFile.Name;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
vars.updateJournalReader();
|
|
|
|
|
vars.journalReader.ReadToEnd();
|
|
|
|
|
|
|
|
|
|
// Watch for new files
|
|
|
|
|
FileSystemWatcher journalWatcher = new FileSystemWatcher(vars.journalPath);
|
|
|
|
|
journalWatcher.Created += (object sender, FileSystemEventArgs eventArgs) => {
|
|
|
|
|
vars.updateJournalReader();
|
|
|
|
|
};
|
|
|
|
|
journalWatcher.EnableRaisingEvents = true;
|
|
|
|
|
|
2022-02-16 21:39:36 +01:00
|
|
|
|
// List of stations in a lap
|
|
|
|
|
vars.stations = (new string[] { "Crown Orbital", "Asire Dock", "Webb Station", "Phillips Market", "Neville Ring", "Garden Ring" }).ToList();
|
|
|
|
|
|
|
|
|
|
// Stopwatch for keeping track of the elapsed time; time limit is 20 minutes
|
|
|
|
|
vars.stopWatch = new System.Diagnostics.Stopwatch();
|
|
|
|
|
vars.timeLimit = new System.TimeSpan(0, 20, 0); // 20 minutes
|
|
|
|
|
|
2022-02-16 22:50:31 +01:00
|
|
|
|
// Since there is no technical “last split”, we need some way to stop the timer when the time is up
|
|
|
|
|
vars.finished = false;
|
|
|
|
|
|
2022-02-17 16:30:18 +01:00
|
|
|
|
// Initialize stops counter
|
|
|
|
|
vars.stops = 0;
|
|
|
|
|
|
|
|
|
|
// Initialize docking counter file
|
|
|
|
|
vars.logFile = new FileInfo(Path.Combine(
|
2022-02-18 16:36:54 +01:00
|
|
|
|
Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
|
2022-02-17 16:30:18 +01:00
|
|
|
|
"LiveSplit",
|
|
|
|
|
"Magic 8-Ball",
|
|
|
|
|
"Back to Pareco",
|
|
|
|
|
"stops.txt")
|
|
|
|
|
);
|
|
|
|
|
vars.writeStops = (Action)delegate () {
|
|
|
|
|
Directory.CreateDirectory(vars.logFile.Directory.FullName);
|
|
|
|
|
File.WriteAllText(vars.logFile.FullName, vars.stops.ToString());
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Initialize settings
|
|
|
|
|
settings.Add("writeStops", false, "Write the number of stops to a file, e.g. for a stream overlay");
|
|
|
|
|
settings.SetToolTip("writeStops", "You will find the file at " + vars.logFile.FullName);
|
|
|
|
|
settings.Add("autoReset", true, "Automatically reset when docking back at Garden Ring");
|
2022-02-18 16:55:58 +01:00
|
|
|
|
settings.Add("resetOnDeath", false, "Automatically stop the timer after death");
|
|
|
|
|
settings.SetToolTip("resetOnDeath", "Will also reset once you dock at Garden Ring afterwards if auto reset is enabled");
|
2022-02-16 21:39:36 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Executes when LiveSplit detects the game process (see “state” at the top of the file).
|
|
|
|
|
// See https://github.com/LiveSplit/LiveSplit.AutoSplitters/blob/master/README.md#script-initialization-game-start
|
|
|
|
|
init {
|
2022-08-26 17:28:36 +02:00
|
|
|
|
vars.updateJournalReader();
|
|
|
|
|
vars.journalReader.ReadToEnd();
|
2022-02-16 21:39:36 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Executes as long as the game process is running, by default 60 times per second.
|
|
|
|
|
// Unless explicitly returning `false`, `start`, `split` and `reset` are executed right after.
|
|
|
|
|
// See https://github.com/LiveSplit/LiveSplit.AutoSplitters/blob/master/README.md#generic-update
|
|
|
|
|
update {
|
|
|
|
|
current.journalString = vars.journalReader.ReadToEnd();
|
2022-02-18 16:55:58 +01:00
|
|
|
|
if (settings["resetOnDeath"] && !String.IsNullOrEmpty(current.journalString)
|
|
|
|
|
&& vars.journalEntries["died"].Match(current.journalString).Success) {
|
|
|
|
|
vars.finished = true;
|
|
|
|
|
}
|
2022-02-16 21:39:36 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Executes every `update`. Starts the timer if undocking from Garden Ring is detected.
|
|
|
|
|
// See https://github.com/LiveSplit/LiveSplit.AutoSplitters/blob/master/README.md#automatic-timer-start-1
|
|
|
|
|
start {
|
|
|
|
|
bool start = false;
|
|
|
|
|
|
|
|
|
|
if (vars.journalEntries["start"].Match(current.journalString).Success) {
|
|
|
|
|
start = true;
|
2022-02-16 22:50:31 +01:00
|
|
|
|
vars.finished = false;
|
2022-02-17 16:30:18 +01:00
|
|
|
|
vars.stops = 0;
|
|
|
|
|
if (settings["writeStops"]) {
|
|
|
|
|
vars.writeStops();
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-16 22:24:53 +01:00
|
|
|
|
vars.stopWatch = System.Diagnostics.Stopwatch.StartNew();
|
2022-02-16 21:39:36 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return start;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Executes every `update`. Triggers a split if docking at the next station in the current lap is detected.
|
|
|
|
|
// See https://github.com/LiveSplit/LiveSplit.AutoSplitters/blob/master/README.md#automatic-splits-1
|
|
|
|
|
split {
|
|
|
|
|
bool split = false;
|
|
|
|
|
|
|
|
|
|
if (!String.IsNullOrEmpty(current.journalString)) {
|
|
|
|
|
System.Text.RegularExpressions.Match match = vars.journalEntries["docked"].Match(current.journalString);
|
|
|
|
|
if (match.Success) {
|
2022-02-17 16:30:18 +01:00
|
|
|
|
if (match.Groups["station"].Value == vars.stations[vars.stops % vars.stations.Count]) {
|
2022-02-16 21:39:36 +01:00
|
|
|
|
split = true;
|
2022-02-17 16:30:18 +01:00
|
|
|
|
vars.stops++;
|
|
|
|
|
if (settings["writeStops"]) {
|
|
|
|
|
vars.writeStops();
|
|
|
|
|
}
|
2022-02-16 22:50:31 +01:00
|
|
|
|
if (vars.stopWatch.Elapsed > vars.timeLimit) {
|
|
|
|
|
vars.finished = true;
|
|
|
|
|
}
|
2022-02-16 21:39:36 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return split;
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-16 22:50:31 +01:00
|
|
|
|
// Executes every `update`. Triggers a reset if a dock at Garden Ring is detected after the 20 minute time limit has
|
|
|
|
|
// run out.
|
2022-02-16 21:39:36 +01:00
|
|
|
|
// See https://github.com/LiveSplit/LiveSplit.AutoSplitters/blob/master/README.md#automatic-resets-1
|
|
|
|
|
reset {
|
|
|
|
|
bool reset = false;
|
|
|
|
|
|
2022-02-18 16:55:58 +01:00
|
|
|
|
if (vars.finished && settings["autoReset"] && !String.IsNullOrEmpty(current.journalString)) {
|
2022-02-16 21:39:36 +01:00
|
|
|
|
System.Text.RegularExpressions.Match match = vars.journalEntries["docked"].Match(current.journalString);
|
|
|
|
|
if (match.Success) {
|
2022-02-16 23:00:35 +01:00
|
|
|
|
// Since you can do one last dock after the time limit has been reached, we can _not_ reset on docking at
|
|
|
|
|
// Garden Ring if that is the next stop in your current lap. Otherwise `split` is not executed.
|
|
|
|
|
if (match.Groups["station"].Value == "Garden Ring"
|
2022-02-17 16:30:18 +01:00
|
|
|
|
&& vars.stations[vars.stops % vars.stations.Count] != "Garden Ring") {
|
2022-02-16 21:39:36 +01:00
|
|
|
|
reset = true;
|
2022-02-17 16:30:18 +01:00
|
|
|
|
vars.stops = 0;
|
|
|
|
|
if (settings["writeStops"]) {
|
|
|
|
|
vars.writeStops();
|
|
|
|
|
}
|
2022-02-16 21:39:36 +01:00
|
|
|
|
vars.stopWatch.Reset();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return reset;
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-16 22:50:31 +01:00
|
|
|
|
// This one is technically used to pause the timer while a game is loading; we can abuse this to stop the timer after
|
|
|
|
|
// the time limit has been passed.
|
2022-02-16 21:39:36 +01:00
|
|
|
|
// See https://github.com/LiveSplit/LiveSplit.AutoSplitters/blob/5efb4201b86e4cba0f0e10e096f6049b947c6ff5/README.md#load-time-removal
|
|
|
|
|
isLoading {
|
2022-02-16 22:50:31 +01:00
|
|
|
|
return vars.finished;
|
2022-02-16 21:39:36 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Executes when the game process is shut down.
|
|
|
|
|
// In our case we’re going to close the files we opened in `init`.
|
|
|
|
|
// See https://github.com/LiveSplit/LiveSplit.AutoSplitters/blob/master/README.md#game-exit
|
|
|
|
|
exit {
|
|
|
|
|
vars.journalReader.Close();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Executes when LiveScript shuts the auto splitter down, e.g. on reloading it.
|
|
|
|
|
// When reloading the splitter with the game running, LiveSplit does **not** execute `exit`, but it does execute `shutdown`.
|
|
|
|
|
// see https://github.com/LiveSplit/LiveSplit.AutoSplitters/blob/master/README.md#script-shutdown
|
|
|
|
|
shutdown {
|
|
|
|
|
if (vars.journalReader != null) {
|
|
|
|
|
vars.journalReader.Close();
|
|
|
|
|
}
|
|
|
|
|
}
|