mirror of
https://github.com/PixelGuys/Cubyz.git
synced 2025-08-03 03:06:55 -04:00
Allow arbitrary and duplicate Save names.
This is done by replacing all illegal file name characters with `-`. Unicode is still preserved because it doesn't seem to be a problem for modern file systems. The idea of file name encoding/decoding is discarded, instead the name is just stored in the zon fixes #606
This commit is contained in:
parent
8bcc00f536
commit
73bbdcc033
@ -44,16 +44,48 @@ fn createWorld(_: usize) void {
|
||||
};
|
||||
}
|
||||
|
||||
fn findValidFolderName(allocator: NeverFailingAllocator, name: []const u8) []const u8 {
|
||||
// Remove illegal ASCII characters:
|
||||
const escapedName = main.stackAllocator.alloc(u8, name.len);
|
||||
defer main.stackAllocator.free(escapedName);
|
||||
for(name, 0..) |char, i| {
|
||||
escapedName[i] = switch(char) {
|
||||
'a'...'z',
|
||||
'A'...'Z',
|
||||
'0'...'9',
|
||||
'_',
|
||||
'-',
|
||||
'.',
|
||||
' ' => char,
|
||||
128...255 => char,
|
||||
else => '-',
|
||||
};
|
||||
}
|
||||
|
||||
// Avoid duplicates:
|
||||
var resultName = main.stackAllocator.dupe(u8, escapedName);
|
||||
defer main.stackAllocator.free(resultName);
|
||||
var i: usize = 0;
|
||||
while(true) {
|
||||
const resultPath = std.fmt.allocPrint(main.stackAllocator.allocator, "saves/{s}", .{resultName}) catch unreachable;
|
||||
defer main.stackAllocator.free(resultPath);
|
||||
|
||||
var dir = std.fs.cwd().openDir(resultPath, .{}) catch break;
|
||||
dir.close();
|
||||
|
||||
main.stackAllocator.free(resultName);
|
||||
resultName = std.fmt.allocPrint(main.stackAllocator.allocator, "{s}_{}", .{escapedName, i}) catch unreachable;
|
||||
i += 1;
|
||||
}
|
||||
return allocator.dupe(u8, resultName);
|
||||
}
|
||||
|
||||
fn flawedCreateWorld() !void {
|
||||
const worldName = textInput.currentString.items;
|
||||
const worldPath = worldName; // TODO: Make sure that only valid file name characters are used, and add a check to allow different worlds of the same name.
|
||||
const worldPath = findValidFolderName(main.stackAllocator, worldName);
|
||||
defer main.stackAllocator.free(worldPath);
|
||||
const saveFolder = std.fmt.allocPrint(main.stackAllocator.allocator, "saves/{s}", .{worldPath}) catch unreachable;
|
||||
defer main.stackAllocator.free(saveFolder);
|
||||
if(std.fs.cwd().openDir(saveFolder, .{})) |_dir| {
|
||||
var dir = _dir;
|
||||
dir.close();
|
||||
return error.AlreadyExists;
|
||||
} else |_| {}
|
||||
try main.files.makeDir(saveFolder);
|
||||
{
|
||||
const generatorSettingsPath = std.fmt.allocPrint(main.stackAllocator.allocator, "saves/{s}/generatorSettings.zig.zon", .{worldPath}) catch unreachable;
|
||||
|
@ -94,33 +94,6 @@ fn openFolder(index: usize) void {
|
||||
main.files.openDirInWindow(path);
|
||||
}
|
||||
|
||||
fn parseEscapedFolderName(allocator: NeverFailingAllocator, name: []const u8) []const u8 {
|
||||
var result = main.List(u8).init(allocator);
|
||||
defer result.deinit();
|
||||
var i: u32 = 0;
|
||||
while(i < name.len) : (i += 1) {
|
||||
if(name[i] == '_') {
|
||||
var val: u21 = 0;
|
||||
for(0..4) |_| {
|
||||
i += 1;
|
||||
if(i < name.len) {
|
||||
val = val*16 + switch(name[i]) {
|
||||
'0'...'9' => name[i] - '0',
|
||||
'a'...'f' => name[i] - 'a' + 10,
|
||||
'A'...'F' => name[i] - 'A' + 10,
|
||||
else => 0,
|
||||
};
|
||||
}
|
||||
}
|
||||
var buf: [4]u8 = undefined;
|
||||
result.appendSlice(buf[0 .. std.unicode.utf8Encode(val, &buf) catch 0]); // TODO: Change this to full unicode rather than using this broken utf-16 converter.
|
||||
} else {
|
||||
result.append(name[i]);
|
||||
}
|
||||
}
|
||||
return result.toOwnedSlice();
|
||||
}
|
||||
|
||||
pub fn update() void {
|
||||
if(needsUpdate) {
|
||||
needsUpdate = false;
|
||||
@ -157,13 +130,10 @@ pub fn onOpen() void {
|
||||
};
|
||||
defer worldInfo.deinit(main.stackAllocator);
|
||||
|
||||
const decodedName = parseEscapedFolderName(main.stackAllocator, entry.name);
|
||||
defer main.stackAllocator.free(decodedName);
|
||||
|
||||
worldList.append(main.globalAllocator, .{
|
||||
.fileName = main.globalAllocator.dupe(u8, entry.name),
|
||||
.lastUsedTime = worldInfo.get(i64, "lastUsedTime", 0),
|
||||
.name = main.globalAllocator.dupe(u8, worldInfo.get([]const u8, "", decodedName)),
|
||||
.name = main.globalAllocator.dupe(u8, worldInfo.get([]const u8, "name", entry.name)),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user