mirror of
https://github.com/PixelGuys/Cubyz.git
synced 2025-09-08 03:29:48 -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 {
|
fn flawedCreateWorld() !void {
|
||||||
const worldName = textInput.currentString.items;
|
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;
|
const saveFolder = std.fmt.allocPrint(main.stackAllocator.allocator, "saves/{s}", .{worldPath}) catch unreachable;
|
||||||
defer main.stackAllocator.free(saveFolder);
|
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);
|
try main.files.makeDir(saveFolder);
|
||||||
{
|
{
|
||||||
const generatorSettingsPath = std.fmt.allocPrint(main.stackAllocator.allocator, "saves/{s}/generatorSettings.zig.zon", .{worldPath}) catch unreachable;
|
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);
|
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 {
|
pub fn update() void {
|
||||||
if(needsUpdate) {
|
if(needsUpdate) {
|
||||||
needsUpdate = false;
|
needsUpdate = false;
|
||||||
@ -157,13 +130,10 @@ pub fn onOpen() void {
|
|||||||
};
|
};
|
||||||
defer worldInfo.deinit(main.stackAllocator);
|
defer worldInfo.deinit(main.stackAllocator);
|
||||||
|
|
||||||
const decodedName = parseEscapedFolderName(main.stackAllocator, entry.name);
|
|
||||||
defer main.stackAllocator.free(decodedName);
|
|
||||||
|
|
||||||
worldList.append(main.globalAllocator, .{
|
worldList.append(main.globalAllocator, .{
|
||||||
.fileName = main.globalAllocator.dupe(u8, entry.name),
|
.fileName = main.globalAllocator.dupe(u8, entry.name),
|
||||||
.lastUsedTime = worldInfo.get(i64, "lastUsedTime", 0),
|
.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