-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathGmodFileHelper.cs
More file actions
129 lines (114 loc) · 4.62 KB
/
GmodFileHelper.cs
File metadata and controls
129 lines (114 loc) · 4.62 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
using System.Text;
namespace GTerm
{
internal static class GmodFileHelper
{
public static string GenerateDirectoryTree(string path, int maxDepth = 5)
{
if (!Directory.Exists(path))
{
return $"Directory not found: {path}";
}
StringBuilder sb = new();
sb.AppendLine(path);
GenerateTreeRecursive(path, "", true, sb, 0, maxDepth);
return sb.ToString();
}
private static void GenerateTreeRecursive(string path, string indent, bool isLast, StringBuilder sb, int currentDepth, int maxDepth)
{
if (currentDepth >= maxDepth)
{
sb.AppendLine($"{indent}{(isLast ? "└── " : "├── ")}[max depth reached]");
return;
}
try
{
string[] directories = Directory.GetDirectories(path);
string[] files = Directory.GetFiles(path);
// Combine directories and files
var items = directories.Select(d => (Path: d, IsDirectory: true))
.Concat(files.Select(f => (Path: f, IsDirectory: false)))
.OrderBy(x => !x.IsDirectory) // Directories first
.ThenBy(x => Path.GetFileName(x.Path))
.ToArray();
for (int i = 0; i < items.Length; i++)
{
bool isLastItem = (i == items.Length - 1);
string name = Path.GetFileName(items[i].Path);
string marker = isLastItem ? "└── " : "├── ";
string newIndent = indent + (isLast ? " " : "│ ");
if (items[i].IsDirectory)
{
sb.AppendLine($"{indent}{marker}{name}/");
GenerateTreeRecursive(items[i].Path, newIndent, isLastItem, sb, currentDepth + 1, maxDepth);
}
else
{
FileInfo fi = new(items[i].Path);
string size = FormatFileSize(fi.Length);
sb.AppendLine($"{indent}{marker}{name} ({size})");
}
}
}
catch (UnauthorizedAccessException)
{
sb.AppendLine($"{indent}{(isLast ? "└── " : "├── ")}[Access Denied]");
}
catch (Exception ex)
{
sb.AppendLine($"{indent}{(isLast ? "└── " : "├── ")}[Error: {ex.Message}]");
}
}
private static string FormatFileSize(long bytes)
{
string[] sizes = { "B", "KB", "MB", "GB" };
double len = bytes;
int order = 0;
while (len >= 1024 && order < sizes.Length - 1)
{
order++;
len /= 1024;
}
return $"{len:0.##} {sizes[order]}";
}
public static string ReadFile(string basePath, string relativePath, int maxSizeKB = 1024)
{
try
{
// Normalize the path and prevent directory traversal attacks
string fullPath = Path.GetFullPath(Path.Combine(basePath, relativePath));
string normalizedBasePath = Path.GetFullPath(basePath);
// Ensure the requested file is within the Garry's Mod directory
if (!fullPath.StartsWith(normalizedBasePath, StringComparison.OrdinalIgnoreCase))
{
return "Error: Access denied - path is outside Garry's Mod directory";
}
if (!File.Exists(fullPath))
{
return $"Error: File not found: {relativePath}";
}
FileInfo fi = new(fullPath);
long maxSizeBytes = maxSizeKB * 1024;
if (fi.Length > maxSizeBytes)
{
return $"Error: File too large ({FormatFileSize(fi.Length)}). Maximum size: {maxSizeKB} KB";
}
// Try to read as text
try
{
string content = File.ReadAllText(fullPath);
return content;
}
catch (Exception)
{
// If text reading fails, it might be binary
return "Error: File appears to be binary or cannot be read as text";
}
}
catch (Exception ex)
{
return $"Error: {ex.Message}";
}
}
}
}