mirror of
https://github.com/PixelGuys/Cubyz.git
synced 2025-08-03 11:17:05 -04:00
Some improvements to error handling
This commit is contained in:
parent
2c33f3779d
commit
05769cc765
@ -30,6 +30,7 @@ pub fn readAllJsonFilesInAddons(externalAllocator: NeverFailingAllocator, addons
|
||||
if(entry.kind == .file and std.ascii.endsWithIgnoreCase(entry.basename, ".json")) {
|
||||
const folderName = addonName;
|
||||
const id: []u8 = externalAllocator.alloc(u8, folderName.len + 1 + entry.path.len - 5);
|
||||
errdefer externalAllocator.free(id);
|
||||
@memcpy(id[0..folderName.len], folderName);
|
||||
id[folderName.len] = ':';
|
||||
for(0..entry.path.len-5) |i| {
|
||||
@ -219,9 +220,8 @@ pub fn loadWorldAssets(assetFolder: []const u8, palette: *BlockPalette) !void {
|
||||
json = value;
|
||||
} else {
|
||||
std.log.err("Missing block: {s}. Replacing it with default block.", .{id});
|
||||
json = JsonElement.initObject(main.globalAllocator);
|
||||
json = .{.JsonNull={}};
|
||||
}
|
||||
defer if(nullValue == null) json.free(main.globalAllocator);
|
||||
try registerBlock(assetFolder, id, json);
|
||||
block += 1;
|
||||
}
|
||||
|
@ -206,7 +206,7 @@ fn moveCursorRight(self: *TextInput, mods: main.Key.Modifiers) void {
|
||||
if(self.cursor.? >= self.currentString.items.len) return;
|
||||
}
|
||||
} else {
|
||||
self.cursor.? += std.unicode.utf8ByteSequenceLength(self.currentString.items[self.cursor.?]) catch unreachable;
|
||||
self.cursor.? += std.unicode.utf8ByteSequenceLength(self.currentString.items[self.cursor.?]) catch 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -28,18 +28,16 @@ var gotIpAddress: std.atomic.Value(bool) = std.atomic.Value(bool).init(false);
|
||||
var thread: ?std.Thread = null;
|
||||
const width: f32 = 420;
|
||||
|
||||
fn flawedDiscoverIpAddress() !void {
|
||||
connection = try ConnectionManager.init(12347, true); // TODO: default port
|
||||
fn discoverIpAddress() void {
|
||||
connection = ConnectionManager.init(12347, true) catch |err| {
|
||||
std.log.err("Could not open Connection: {s}", .{@errorName(err)});
|
||||
ipAddress = main.globalAllocator.dupe(u8, @errorName(err));
|
||||
return;
|
||||
}; // TODO: default port
|
||||
ipAddress = std.fmt.allocPrint(main.globalAllocator.allocator, "{}", .{connection.?.externalAddress}) catch unreachable;
|
||||
gotIpAddress.store(true, .Release);
|
||||
}
|
||||
|
||||
fn discoverIpAddress() void {
|
||||
flawedDiscoverIpAddress() catch |err| {
|
||||
std.log.err("Encountered error {s} while discovering the ip address for multiplayer.", .{@errorName(err)});
|
||||
};
|
||||
}
|
||||
|
||||
fn discoverIpAddressFromNewThread() void {
|
||||
var sta = main.utils.StackAllocator.init(main.globalAllocator, 1 << 23);
|
||||
defer sta.deinit();
|
||||
|
@ -25,7 +25,7 @@ const width: f32 = 128;
|
||||
var buttonNameArena: main.utils.NeverFailingArenaAllocator = undefined;
|
||||
|
||||
pub fn openWorld(name: []const u8) void {
|
||||
std.log.info("TODO: Open world {s}", .{name});
|
||||
std.log.info("Opening world {s}", .{name});
|
||||
main.server.thread = std.Thread.spawn(.{}, main.server.start, .{name}) catch |err| {
|
||||
std.log.err("Encountered error while starting server thread: {s}", .{@errorName(err)});
|
||||
return;
|
||||
@ -44,14 +44,6 @@ pub fn openWorld(name: []const u8) void {
|
||||
gui.closeWindow(openWindow);
|
||||
}
|
||||
gui.openHud();
|
||||
// while(Server.world == null) {
|
||||
// try {
|
||||
// Thread.sleep(10);
|
||||
// } catch(InterruptedException e) {}
|
||||
// }
|
||||
// try {
|
||||
// GameLauncher.logic.loadWorld(new ClientWorld("127.0.0.1", new UDPConnectionManager(Constants.DEFAULT_PORT+1, false))); // TODO: Don't go over the local network in singleplayer.
|
||||
// } catch(InterruptedException e) {}
|
||||
}
|
||||
|
||||
fn openWorldWrap(namePtr: usize) void { // TODO: Improve this situation. Maybe it makes sense to always use 2 arguments in the Callback.
|
||||
@ -109,29 +101,33 @@ pub fn onOpen() void {
|
||||
const list = VerticalList.init(.{padding, 16 + padding}, 300, 8);
|
||||
// TODO: list.add(Button.initText(.{0, 0}, 128, "Create World", gui.openWindowCallback("save_creation")));
|
||||
|
||||
var dir = std.fs.cwd().makeOpenPath("saves", .{.iterate = true}) catch |err| {
|
||||
std.log.err("Encountered error while trying to open folder \"saves\": {s}", .{@errorName(err)});
|
||||
return;
|
||||
};
|
||||
defer dir.close();
|
||||
readingSaves: {
|
||||
var dir = std.fs.cwd().makeOpenPath("saves", .{.iterate = true}) catch |err| {
|
||||
list.add(Label.init(.{0, 0}, 128, "Encountered error while trying to open saves folder:", .center));
|
||||
list.add(Label.init(.{0, 0}, 128, @errorName(err), .center));
|
||||
break :readingSaves;
|
||||
};
|
||||
defer dir.close();
|
||||
|
||||
var iterator = dir.iterate();
|
||||
while(iterator.next() catch |err| {
|
||||
std.log.err("Encountered error while iterating over folder \"saves\": {s}", .{@errorName(err)});
|
||||
return;
|
||||
}) |entry| {
|
||||
if(entry.kind == .directory) {
|
||||
const row = HorizontalList.init();
|
||||
var iterator = dir.iterate();
|
||||
while(iterator.next() catch |err| {
|
||||
list.add(Label.init(.{0, 0}, 128, "Encountered error while iterating over saves folder:", .center));
|
||||
list.add(Label.init(.{0, 0}, 128, @errorName(err), .center));
|
||||
break :readingSaves;
|
||||
}) |entry| {
|
||||
if(entry.kind == .directory) {
|
||||
const row = HorizontalList.init();
|
||||
|
||||
const decodedName = parseEscapedFolderName(main.stackAllocator, entry.name);
|
||||
defer main.stackAllocator.free(decodedName);
|
||||
const name = buttonNameArena.allocator().dupeZ(u8, entry.name); // Null terminate, so we can later recover the string from just the pointer.
|
||||
const buttonName = std.fmt.allocPrint(buttonNameArena.allocator().allocator, "Play {s}", .{decodedName}) catch unreachable;
|
||||
|
||||
row.add(Button.initText(.{0, 0}, 128, buttonName, .{.callback = &openWorldWrap, .arg = @intFromPtr(name.ptr)}));
|
||||
row.add(Button.initText(.{8, 0}, 64, "delete", .{.callback = &deleteWorld, .arg = @intFromPtr(name.ptr)}));
|
||||
row.finish(.{0, 0}, .center);
|
||||
list.add(row);
|
||||
const decodedName = parseEscapedFolderName(main.stackAllocator, entry.name);
|
||||
defer main.stackAllocator.free(decodedName);
|
||||
const name = buttonNameArena.allocator().dupeZ(u8, entry.name); // Null terminate, so we can later recover the string from just the pointer.
|
||||
const buttonName = std.fmt.allocPrint(buttonNameArena.allocator().allocator, "Play {s}", .{decodedName}) catch unreachable;
|
||||
|
||||
row.add(Button.initText(.{0, 0}, 128, buttonName, .{.callback = &openWorldWrap, .arg = @intFromPtr(name.ptr)}));
|
||||
row.add(Button.initText(.{8, 0}, 64, "delete", .{.callback = &deleteWorld, .arg = @intFromPtr(name.ptr)}));
|
||||
row.finish(.{0, 0}, .center);
|
||||
list.add(row);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
21
src/json.zig
21
src/json.zig
@ -237,13 +237,13 @@ pub const JsonElement = union(JsonType) {
|
||||
list.append('\t');
|
||||
}
|
||||
}
|
||||
fn recurseToString(json: JsonElement, list: *List(u8), tabs: u32, comptime visualCharacters: bool) !void {
|
||||
fn recurseToString(json: JsonElement, list: *List(u8), tabs: u32, comptime visualCharacters: bool) void {
|
||||
switch(json) {
|
||||
.JsonInt => |value| {
|
||||
try std.fmt.formatInt(value, 10, .lower, .{}, list.writer());
|
||||
std.fmt.formatInt(value, 10, .lower, .{}, list.writer()) catch unreachable;
|
||||
},
|
||||
.JsonFloat => |value| {
|
||||
try std.fmt.formatFloatScientific(value, .{}, list.writer());
|
||||
std.fmt.formatFloatScientific(value, .{}, list.writer()) catch unreachable;
|
||||
},
|
||||
.JsonBool => |value| {
|
||||
if(value) {
|
||||
@ -268,7 +268,7 @@ pub const JsonElement = union(JsonType) {
|
||||
}
|
||||
if(visualCharacters) list.append('\n');
|
||||
if(visualCharacters) writeTabs(list, tabs + 1);
|
||||
try recurseToString(elem, list, tabs + 1, visualCharacters);
|
||||
recurseToString(elem, list, tabs + 1, visualCharacters);
|
||||
}
|
||||
if(visualCharacters) list.append('\n');
|
||||
if(visualCharacters) writeTabs(list, tabs);
|
||||
@ -292,7 +292,7 @@ pub const JsonElement = union(JsonType) {
|
||||
list.append(':');
|
||||
if(visualCharacters) list.append(' ');
|
||||
|
||||
try recurseToString(elem.value_ptr.*, list, tabs + 1, visualCharacters);
|
||||
recurseToString(elem.value_ptr.*, list, tabs + 1, visualCharacters);
|
||||
first = false;
|
||||
}
|
||||
if(visualCharacters) list.append('\n');
|
||||
@ -303,7 +303,7 @@ pub const JsonElement = union(JsonType) {
|
||||
}
|
||||
pub fn toString(json: JsonElement, allocator: NeverFailingAllocator) []const u8 {
|
||||
var string = List(u8).init(allocator);
|
||||
recurseToString(json, &string, 0, true) catch unreachable;
|
||||
recurseToString(json, &string, 0, true);
|
||||
return string.toOwnedSlice();
|
||||
}
|
||||
|
||||
@ -311,7 +311,7 @@ pub const JsonElement = union(JsonType) {
|
||||
pub fn toStringEfficient(json: JsonElement, allocator: NeverFailingAllocator, prefix: []const u8) []const u8 {
|
||||
var string = List(u8).init(allocator);
|
||||
string.appendSlice(prefix);
|
||||
recurseToString(json, &string, 0, false) catch unreachable;
|
||||
recurseToString(json, &string, 0, false);
|
||||
return string.toOwnedSlice();
|
||||
}
|
||||
|
||||
@ -505,10 +505,11 @@ const Parser = struct {
|
||||
index.* += 1;
|
||||
skipWhitespaces(chars, index);
|
||||
const value: JsonElement = parseElement(allocator, chars, index);
|
||||
map.putNoClobber(key, value) catch {
|
||||
if(map.fetchPut(key, value) catch unreachable) |old| {
|
||||
printError(chars, index.*, "Duplicate key.");
|
||||
allocator.free(key);
|
||||
};
|
||||
allocator.free(old.key);
|
||||
old.value.free(allocator);
|
||||
}
|
||||
skipWhitespaces(chars, index);
|
||||
if(index.* < chars.len and chars[index.*] == ',') {
|
||||
index.* += 1;
|
||||
|
@ -668,7 +668,7 @@ pub fn main() !void {
|
||||
|
||||
// init logging.
|
||||
try std.fs.cwd().makePath("logs");
|
||||
logFile = std.fs.cwd().createFile("logs/latest.log", .{}) catch unreachable;
|
||||
logFile = try std.fs.cwd().createFile("logs/latest.log", .{});
|
||||
defer logFile.close();
|
||||
supportsANSIColors = std.io.getStdOut().supportsAnsiEscapeCodes();
|
||||
|
||||
|
@ -288,7 +288,7 @@ const STUN = struct {
|
||||
std.log.err("Cannot resolve stun server address: {s}, error: {s}", .{ip, @errorName(err)});
|
||||
continue;
|
||||
},
|
||||
.port=std.fmt.parseUnsigned(u16, splitter.rest(), 10) catch 3478
|
||||
.port=std.fmt.parseUnsigned(u16, splitter.rest(), 10) catch 3478,
|
||||
};
|
||||
if(connection.sendRequest(main.globalAllocator, &data, serverAddress, 500*1000000)) |answer| {
|
||||
defer main.globalAllocator.free(answer);
|
||||
|
@ -482,6 +482,7 @@ pub const MenuBackGround = struct {
|
||||
c.glBufferData(c.GL_ELEMENT_ARRAY_BUFFER, @intCast(indices.len*@sizeOf(c_int)), &indices, c.GL_STATIC_DRAW);
|
||||
|
||||
// Load a random texture from the backgrounds folder. The player may make their own pictures which can be chosen as well.
|
||||
texture = .{.textureID = 0};
|
||||
var dir = try std.fs.cwd().makeOpenPath("assets/backgrounds", .{.iterate = true});
|
||||
defer dir.close();
|
||||
|
||||
@ -502,7 +503,6 @@ pub const MenuBackGround = struct {
|
||||
}
|
||||
if(fileList.items.len == 0) {
|
||||
std.log.warn("Couldn't find any background scene images in \"assets/backgrounds\".", .{});
|
||||
texture = .{.textureID = 0};
|
||||
return;
|
||||
}
|
||||
const theChosenOne = main.random.nextIntBounded(u32, &main.seed, @as(u32, @intCast(fileList.items.len)));
|
||||
|
@ -610,7 +610,7 @@ pub const ChunkMesh = struct {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn generateLightingData(self: *ChunkMesh) !void {
|
||||
pub fn generateLightingData(self: *ChunkMesh) error{AlreadyStored}!void {
|
||||
self.mutex.lock();
|
||||
self.opaqueMesh.reset();
|
||||
self.transparentMesh.reset();
|
||||
|
@ -963,7 +963,7 @@ pub fn addToUpdateListAndDecreaseRefCount(mesh: *chunk_meshing.ChunkMesh) void {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn addMeshToStorage(mesh: *chunk_meshing.ChunkMesh) !void {
|
||||
pub fn addMeshToStorage(mesh: *chunk_meshing.ChunkMesh) error{AlreadyStored}!void {
|
||||
mutex.lock();
|
||||
defer mutex.unlock();
|
||||
if(isInRenderDistance(mesh.pos)) {
|
||||
@ -1018,13 +1018,7 @@ pub const MeshGenerationTask = struct {
|
||||
const mesh = main.globalAllocator.create(chunk_meshing.ChunkMesh);
|
||||
mesh.init(pos, self.mesh);
|
||||
defer mesh.decreaseRefCount();
|
||||
mesh.generateLightingData() catch |err| {
|
||||
switch(err) {
|
||||
error.AlreadyStored => {
|
||||
return;
|
||||
},
|
||||
}
|
||||
};
|
||||
mesh.generateLightingData() catch return;
|
||||
}
|
||||
|
||||
pub fn clean(self: *MeshGenerationTask) void {
|
||||
|
@ -117,7 +117,7 @@ fn init(name: []const u8) void {
|
||||
users = main.List(*User).init(main.globalAllocator);
|
||||
lastTime = std.time.nanoTimestamp();
|
||||
connectionManager = ConnectionManager.init(main.settings.defaultPort, false) catch |err| {
|
||||
std.log.err("Couldn't create connection from port: {s}", .{@errorName(err)});
|
||||
std.log.err("Couldn't create socket: {s}", .{@errorName(err)});
|
||||
@panic("Could not open Server.");
|
||||
}; // TODO Configure the second argument in the server settings.
|
||||
// TODO: Load the assets.
|
||||
@ -128,7 +128,7 @@ fn init(name: []const u8) void {
|
||||
};
|
||||
if(true) blk: { // singleplayer // TODO: Configure this in the server settings.
|
||||
const user = User.init(connectionManager, "127.0.0.1:47650") catch |err| {
|
||||
std.log.err("Cannot create user {s}", .{@errorName(err)});
|
||||
std.log.err("Cannot create singleplayer user {s}", .{@errorName(err)});
|
||||
break :blk;
|
||||
};
|
||||
user.isLocal = true;
|
||||
|
@ -204,7 +204,7 @@ pub const BlockStructure = struct {
|
||||
};
|
||||
for(blockStackDescriptions, self.structure) |jsonString, *blockStack| {
|
||||
blockStack.init(jsonString.as([]const u8, "That's not a json string.")) catch |err| {
|
||||
std.log.warn("Couldn't parse blockStack '{s}': {s} Removing it.", .{jsonString.as([]const u8, "That's not a json string."), @errorName(err)});
|
||||
std.log.warn("Couldn't parse blockStack '{s}': {s} Removing it.", .{jsonString.as([]const u8, "(not a json string)"), @errorName(err)});
|
||||
blockStack.* = .{};
|
||||
};
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ pub fn generate(map: *CaveMapFragment, worldSeed: u64) void {
|
||||
const outerSize = @max(map.pos.voxelSize, interpolatedPart);
|
||||
const outerSizeShift = std.math.log2_int(u31, outerSize);
|
||||
const outerSizeFloat: f32 = @floatFromInt(outerSize);
|
||||
const noise = FractalNoise3D.generateAligned(main.stackAllocator, map.pos.wx, map.pos.wy, map.pos.wz, outerSize, CaveMapFragment.width*map.pos.voxelSize/outerSize + 1, CaveMapFragment.height*map.pos.voxelSize/outerSize + 1, CaveMapFragment.width*map.pos.voxelSize/outerSize + 1, worldSeed, scale);//try Cached3DFractalNoise.init(map.pos.wx, map.pos.wy & ~@as(i32, CaveMapFragment.width*map.pos.voxelSize - 1), map.pos.wz, outerSize, map.pos.voxelSize*CaveMapFragment.width, worldSeed, scale);
|
||||
const noise = FractalNoise3D.generateAligned(main.stackAllocator, map.pos.wx, map.pos.wy, map.pos.wz, outerSize, CaveMapFragment.width*map.pos.voxelSize/outerSize + 1, CaveMapFragment.height*map.pos.voxelSize/outerSize + 1, CaveMapFragment.width*map.pos.voxelSize/outerSize + 1, worldSeed, scale);
|
||||
defer noise.deinit(main.stackAllocator);
|
||||
biomeMap.bulkInterpolateValue("caves", map.pos.wx, map.pos.wy, map.pos.wz, outerSize, noise, .addToMap, scale);
|
||||
var x: u31 = 0;
|
||||
|
@ -39,7 +39,7 @@ pub fn samplePoint2D(x: f32, _y: f32, worldSeed: u64) f32 {
|
||||
|
||||
const percentileTable = [_]f32 {0.0e+00, 9.20569300e-02, 1.18748918e-01, 1.38117700e-01, 1.53936773e-01, 1.67584523e-01, 1.79740771e-01, 1.90797567e-01, 2.01004371e-01, 2.10530936e-01, 2.19498828e-01, 2.27998286e-01, 2.36098647e-01, 2.43854254e-01, 2.51308768e-01, 2.58497864e-01, 2.65450924e-01, 2.72192806e-01, 2.78744399e-01, 2.85123795e-01, 2.91346460e-01, 2.97426044e-01, 3.03374379e-01, 3.09202045e-01, 3.14918369e-01, 3.20531696e-01, 3.26049506e-01, 3.31478625e-01, 3.36825191e-01, 3.42094779e-01, 3.47292482e-01, 3.52423042e-01, 3.57490718e-01, 3.62499535e-01, 3.67453157e-01, 3.72355014e-01, 3.77208292e-01, 3.82015973e-01, 3.86780887e-01, 3.91505628e-01, 3.96192669e-01, 4.00844365e-01, 4.05462920e-01, 4.10050421e-01, 4.14608865e-01, 4.19140160e-01, 4.23646122e-01, 4.28128510e-01, 4.32588934e-01, 4.37029063e-01, 4.41450417e-01, 4.45854485e-01, 4.50242727e-01, 4.54616576e-01, 4.58977371e-01, 4.63326483e-01, 4.67665165e-01, 4.71994757e-01, 4.76316481e-01, 4.80631619e-01, 4.84941333e-01, 4.89246904e-01, 4.93549466e-01, 4.97850269e-01, 5.02150475e-01, 5.06451249e-01, 5.10753810e-01, 5.15059411e-01, 5.19369125e-01, 5.23684263e-01, 5.28005957e-01, 5.32335579e-01, 5.36674261e-01, 5.41023373e-01, 5.45384168e-01, 5.49758017e-01, 5.54146230e-01, 5.58550298e-01, 5.62971651e-01, 5.67411780e-01, 5.71872234e-01, 5.76354622e-01, 5.80860555e-01, 5.85391879e-01, 5.89950323e-01, 5.94537794e-01, 5.99156379e-01, 6.03808045e-01, 6.08495116e-01, 6.13219857e-01, 6.17984771e-01, 6.22792422e-01, 6.27645730e-01, 6.32547557e-01, 6.37501180e-01, 6.42509996e-01, 6.47577702e-01, 6.52708232e-01, 6.57905936e-01, 6.63175523e-01, 6.68522059e-01, 6.73951208e-01, 6.79469048e-01, 6.85082376e-01, 6.90798640e-01, 6.96626305e-01, 7.02574670e-01, 7.08654224e-01, 7.14876949e-01, 7.21256315e-01, 7.27807879e-01, 7.34549760e-01, 7.41502821e-01, 7.48691916e-01, 7.56146430e-01, 7.63902068e-01, 7.72002398e-01, 7.80501842e-01, 7.89469778e-01, 7.98996329e-01, 8.09203147e-01, 8.20259928e-01, 8.32416176e-01, 8.46063911e-01, 8.61882984e-01, 8.81251752e-01, 9.07943725e-01, 1.0e+00};
|
||||
|
||||
fn preGeneratePercentileTable() !void {
|
||||
fn preGeneratePercentileTable() void {
|
||||
const randomNumbers = 4096;
|
||||
const positions = 4096;
|
||||
const totalValues = randomNumbers*positions;
|
||||
@ -66,7 +66,7 @@ fn preGeneratePercentileTable() !void {
|
||||
}
|
||||
var samples: u128 = 0;
|
||||
for(&amount2D) |val| {
|
||||
samples = try std.math.add(u128, samples, val);
|
||||
samples = std.math.add(u128, samples, val) catch @panic("Number too big");
|
||||
}
|
||||
std.log.info("{}", .{samples});
|
||||
|
||||
|
@ -463,7 +463,7 @@ pub const ServerWorld = struct {
|
||||
// for(MetaChunk chunk : metaChunks.values().toArray(new MetaChunk[0])) {
|
||||
// if (chunk != null) chunk.save();
|
||||
// }
|
||||
self.wio.saveWorldData();
|
||||
try self.wio.saveWorldData();
|
||||
// TODO:
|
||||
// savePlayers();
|
||||
// chunkManager.forceSave();
|
||||
@ -471,7 +471,7 @@ pub const ServerWorld = struct {
|
||||
const itemDropJson = self.itemDropManager.store(main.globalAllocator);
|
||||
defer itemDropJson.free(main.globalAllocator);
|
||||
var buf: [32768]u8 = undefined;
|
||||
files.writeJson(try std.fmt.bufPrint(&buf, "saves/{s}/items.json", .{self.name}), itemDropJson);
|
||||
try files.writeJson(try std.fmt.bufPrint(&buf, "saves/{s}/items.json", .{self.name}), itemDropJson);
|
||||
}
|
||||
// TODO:
|
||||
// public void addEntity(Entity ent) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user