Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

loading other scripts from a single script #1504

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion UndertaleModCli/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -721,7 +721,8 @@

try
{
CSharpScript.EvaluateAsync(code, CliScriptOptions, this, typeof(IScriptInterface)).GetAwaiter().GetResult();
var processedCode = ScriptUtil.ProcessScriptText(code, scriptFile);
CSharpScript.EvaluateAsync(processedCode, CliScriptOptions, this, typeof(IScriptInterface)).GetAwaiter().GetResult();
ScriptExecutionSuccess = true;
ScriptErrorMessage = "";
}
Expand All @@ -729,7 +730,7 @@
{
ScriptExecutionSuccess = false;
ScriptErrorMessage = exc.ToString();
ScriptErrorType = "Exception";

Check warning on line 733 in UndertaleModCli/Program.cs

View workflow job for this annotation

GitHub Actions / publish_cli (macOS-latest, Debug, false)

XML comment has cref attribute 'code' that could not be resolved

Check warning on line 733 in UndertaleModCli/Program.cs

View workflow job for this annotation

GitHub Actions / publish_cli (macOS-latest, Debug, false)

XML comment has cref attribute 'code' that could not be resolved

Check warning on line 733 in UndertaleModCli/Program.cs

View workflow job for this annotation

GitHub Actions / publish_cli (ubuntu-latest, Debug, false)

XML comment has cref attribute 'code' that could not be resolved

Check warning on line 733 in UndertaleModCli/Program.cs

View workflow job for this annotation

GitHub Actions / publish_cli (ubuntu-latest, Debug, false)

XML comment has cref attribute 'code' that could not be resolved

Check warning on line 733 in UndertaleModCli/Program.cs

View workflow job for this annotation

GitHub Actions / publish_cli (windows-latest, Debug, false)

XML comment has cref attribute 'code' that could not be resolved

Check warning on line 733 in UndertaleModCli/Program.cs

View workflow job for this annotation

GitHub Actions / publish_cli (windows-latest, Debug, false)

XML comment has cref attribute 'code' that could not be resolved
}

if (!FinishedMessageEnabled) return;
Expand Down
37 changes: 37 additions & 0 deletions UndertaleModLib/Util/ScriptUtil.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using System.IO;
using System.Text.RegularExpressions;

namespace UndertaleModLib.Util
{
/// <summary>
/// Utils related to running scripts
/// </summary>
public static class ScriptUtil
{
/// <summary>
/// Processes a script text so that it can use relative `#load` preprocessing
/// </summary>
/// <param name="code">The script code</param>
/// <param name="path">The path to the script</param>
/// <returns></returns>
public static string ProcessScriptText(string code, string path)
{
var output = code;
// since attempting to load scripts with #load in a file will lead to it using the UTMT path,
// we can circumvent this by hardcoding the absolute path to the script directory
// in all instances of #load with a relative path
var scriptDir = Path.GetDirectoryName(path);
var matches = Regex.Matches(code, @"(?<=^#load\s+"").*\.csx(?=""\s*$)", RegexOptions.Multiline);
foreach (Match match in matches)
{
if (Path.IsPathRooted(match.Value))
{
continue;
}
output = output.Replace(match.Value, Path.Combine(scriptDir, match.Value));
}

return output;
}
}
}
48 changes: 38 additions & 10 deletions UndertaleModTool/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2467,9 +2467,10 @@
}
}

public string ProcessException(in Exception exc, in string scriptText)
public string ProcessException(in Exception exc)
{
List<int> excLineNums = new();
// each member is a (file name, line number) pair for all lines in the stack trace
List<Tuple<string, int>> loadedScriptLineNums = new();
string excText = string.Empty;
List<string> traceLines = new();
Dictionary<string, int> exTypesDict = null;
Expand Down Expand Up @@ -2505,12 +2506,15 @@
{
if (traceLine.TrimStart()[..13] == "at Submission") // only stack trace lines from the script
{
// matches full path of the script file
string sourceFile = Regex.Match(traceLine, @"(?<=in ).*\.csx(?=:line \d+)").Value;
nhaar marked this conversation as resolved.
Show resolved Hide resolved
if (!File.Exists(sourceFile))
continue;
int linePos = traceLine.IndexOf(":line ") + 6; // ":line ".Length = 6
if (linePos != (-1 + 6))
{
int lineNum = Convert.ToInt32(traceLine[linePos..]);
if (!excLineNums.Contains(lineNum))
excLineNums.Add(lineNum);
loadedScriptLineNums.Add(new Tuple<string, int>(sourceFile, lineNum));
}
}
}
Expand All @@ -2526,10 +2530,35 @@
return $"An error occurred while processing the exception text.\nError message - \"{e.Message}\"\nThe unprocessed text is below.\n\n" + excString;
}

if (excLineNums.Count > 0) //if line number(s) is found
if (loadedScriptLineNums.Count > 0) //if line number(s) is found
{
string[] scriptLines = scriptText.Split('\n');
string excLines = string.Join('\n', excLineNums.Select(n => $"Line {n}: {scriptLines[n].TrimStart(new char[] { '\t', ' ' })}"));
// read the code for the files to know what the code line associated with the stack trace is
Dictionary<string, List<string>> scriptsCode = new();
foreach (Tuple<string, int> scriptLineNum in loadedScriptLineNums)
{
string scriptPath = scriptLineNum.Item1;
if (!scriptsCode.ContainsKey(scriptPath))
{
string scriptCode = null;
try
{
scriptCode = File.ReadAllText(scriptPath);
}
catch (Exception e)
{
string excString = exc.ToString();

return $"An error occurred while processing the exception text.\nError message - \"{e.Message}\"\nThe unprocessed text is below.\n\n" + excString;
}
scriptsCode.Add(scriptPath, scriptCode.Split('\n').ToList());
}
}

string excLines = string.Join('\n', loadedScriptLineNums.Select(pair =>
{
string scriptName = pair.Item1.Split(Path.DirectorySeparatorChar)[^1];
return $"Line {pair.Item2} in script {scriptName}: {scriptsCode[pair.Item1][pair.Item2 - 1]}"; // - 1 because line numbers start from 1
}));
if (exTypesDict is not null)
{
string exTypesStr = string.Join(",\n", exTypesDict.Select(x => $"{x.Key}{((x.Value > 1) ? " (x" + x.Value + ")" : string.Empty)}"));
Expand Down Expand Up @@ -2577,8 +2606,7 @@

private async Task RunScriptNow(string path)
{
string scriptText = $"#line 1 \"{path}\"\n" + File.ReadAllText(path);
Debug.WriteLine(path);
string scriptText = ScriptUtil.ProcessScriptText($"#line 1 \"{path}\"\n" + File.ReadAllText(path), path);

Dispatcher.Invoke(() => CommandBox.Text = "Running " + Path.GetFileName(path) + " ...");
try
Expand Down Expand Up @@ -2615,7 +2643,7 @@
string excString = string.Empty;

if (!isScriptException)
excString = ProcessException(in exc, in scriptText);
excString = ProcessException(in exc);

await StopProgressBarUpdater();

Expand Down Expand Up @@ -2998,7 +3026,7 @@
webClient.DownloadProgressChanged += new DownloadProgressChangedEventHandler((sender, e) =>
{
if (!end)
downloaded = (e.BytesReceived / bytesToMB).ToString("F2", CultureInfo.InvariantCulture);

Check warning on line 3029 in UndertaleModTool/MainWindow.xaml.cs

View workflow job for this annotation

GitHub Actions / build_gui (windows-latest, Debug, false, false)

'WebClient.WebClient()' is obsolete: 'WebRequest, HttpWebRequest, ServicePoint, and WebClient are obsolete. Use HttpClient instead.' (https://aka.ms/dotnet-warnings/SYSLIB0014)

Check warning on line 3029 in UndertaleModTool/MainWindow.xaml.cs

View workflow job for this annotation

GitHub Actions / build_gui (windows-latest, Debug, false, false)

'WebClient.WebClient()' is obsolete: 'WebRequest, HttpWebRequest, ServicePoint, and WebClient are obsolete. Use HttpClient instead.' (https://aka.ms/dotnet-warnings/SYSLIB0014)

Check warning on line 3029 in UndertaleModTool/MainWindow.xaml.cs

View workflow job for this annotation

GitHub Actions / build_gui (windows-latest, Debug, false, true)

'WebClient.WebClient()' is obsolete: 'WebRequest, HttpWebRequest, ServicePoint, and WebClient are obsolete. Use HttpClient instead.' (https://aka.ms/dotnet-warnings/SYSLIB0014)

Check warning on line 3029 in UndertaleModTool/MainWindow.xaml.cs

View workflow job for this annotation

GitHub Actions / build_gui (windows-latest, Debug, false, true)

'WebClient.WebClient()' is obsolete: 'WebRequest, HttpWebRequest, ServicePoint, and WebClient are obsolete. Use HttpClient instead.' (https://aka.ms/dotnet-warnings/SYSLIB0014)
});
webClient.DownloadFileCompleted += new AsyncCompletedEventHandler((sender, e) =>
{
Expand Down
Loading