Skip to content
Open
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
2,048 changes: 2,048 additions & 0 deletions assets/cubyz/wordlist

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions src/gui/components/TextInput.zig
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ const Callbacks = struct {
onNewline: main.callbacks.SimpleCallback,
onUp: main.callbacks.SimpleCallback = .{},
onDown: main.callbacks.SimpleCallback = .{},
onUpdate: main.callbacks.SimpleCallback = .{},
};

pub fn init(pos: Vec2f, maxWidth: f32, maxHeight: f32, text: []const u8, callbacks: Callbacks) *TextInput {
Expand Down Expand Up @@ -161,6 +162,7 @@ pub fn deselect(self: *TextInput) void {
}

fn reloadText(self: *TextInput) void {
self.callbacks.onUpdate.run();
self.textBuffer.deinit();
self.textBuffer = TextBuffer.init(main.globalAllocator, self.currentString.items, .{}, true, .left);
self.textSize = self.textBuffer.calculateLineBreaks(fontSize, self.maxWidth - 2*border - scrollBarWidth);
Expand Down
5 changes: 5 additions & 0 deletions src/gui/windows/_windowlist.zig
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
pub const @"authentication/create_account" = @import("authentication/create_account.zig");
pub const @"authentication/login" = @import("authentication/login.zig");
pub const @"authentication/logout" = @import("authentication/logout.zig");
pub const @"authentication/unlock" = @import("authentication/unlock.zig");

pub const advanced_controls = @import("advanced_controls.zig");
pub const change_name = @import("change_name.zig");
pub const chat = @import("chat.zig");
Expand Down
67 changes: 67 additions & 0 deletions src/gui/windows/authentication/create_account.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
const std = @import("std");

const main = @import("main");
const settings = main.settings;
const Vec2f = main.vec.Vec2f;

const gui = main.gui;
const GuiComponent = gui.GuiComponent;
const GuiWindow = gui.GuiWindow;
const Button = GuiComponent.Button;
const CheckBox = GuiComponent.CheckBox;
const HorizontalList = GuiComponent.HorizontalList;
const Label = GuiComponent.Label;
const TextInput = GuiComponent.TextInput;
const VerticalList = GuiComponent.VerticalList;

pub var window = GuiWindow{
.contentSize = Vec2f{128, 256},
.closeIfMouseIsGrabbed = true,
.closeable = false,
};

const padding: f32 = 8;

var seedPhraseLabel: *Label = undefined;
var seedPhrase: main.network.authentication.SeedPhrase = undefined;

fn next() void {
gui.closeWindowFromRef(&window);
gui.openWindow("authentication/login");
}

fn copy() void {
main.Window.setClipboardString(seedPhrase.text);
}

pub fn onOpen() void {
seedPhrase = .initRandomly();

const list = VerticalList.init(.{padding, 16 + padding}, 300, 16);
const width = 420;
list.add(Label.init(.{0, 0}, width, "This is your account's seed phrase:", .left));
const row = HorizontalList.init();
seedPhraseLabel = Label.init(.{0, 0}, 350, seedPhrase.text, .left);
row.add(seedPhraseLabel);
row.add(Button.initText(.{0, 0}, 70, "Copy", .init(copy)));
list.add(row);
list.add(Label.init(.{0, 0}, width, "Note: Do not give this to anyone else. We will only ask for the seed phrase on the start of the game.", .left));
list.add(Label.init(.{0, 0}, width, "Note 2: Make sure you store this somewhere safely and securely, there is no recovery option if you lose it. We recommend a password manager.", .left));
list.add(Button.initText(.{0, 0}, 70, "Next", .init(next)));
list.finish(.center);
window.rootComponent = list.toComponent();
window.contentSize = window.rootComponent.?.pos() + window.rootComponent.?.size() + @as(Vec2f, @splat(padding));
gui.updateWindowPositions();
}

pub fn onClose() void {
// Make sure there remains no trace of the seed phrase in memory
@memset(seedPhraseLabel.text.glyphs, std.mem.zeroes(@TypeOf(seedPhraseLabel.text.glyphs[0])));
seedPhrase.deinit();
// This also serves as a measure to ensure that the user indeed copied it somewhere else before closing the window
main.Window.setClipboardString("");

if (window.rootComponent) |*comp| {
comp.deinit();
}
}
99 changes: 99 additions & 0 deletions src/gui/windows/authentication/login.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
const std = @import("std");

const main = @import("main");
const settings = main.settings;
const Vec2f = main.vec.Vec2f;

const gui = main.gui;
const GuiComponent = gui.GuiComponent;
const GuiWindow = gui.GuiWindow;
const Button = GuiComponent.Button;
const CheckBox = GuiComponent.CheckBox;
const Label = GuiComponent.Label;
const HorizontalList = GuiComponent.HorizontalList;
const TextInput = GuiComponent.TextInput;
const VerticalList = GuiComponent.VerticalList;

pub var window = GuiWindow{
.contentSize = Vec2f{128, 256},
.closeIfMouseIsGrabbed = true,
.closeable = false,
};
var textComponent: *TextInput = undefined;
var applyButton: *Button = undefined;
var applyAnyways: bool = false;

const padding: f32 = 8;

fn apply() void {
var failureText: main.List(u8) = .init(main.stackAllocator);
defer failureText.deinit();
const seedPhrase = main.network.authentication.SeedPhrase.initFromUserInput(textComponent.currentString.items, &failureText);
defer seedPhrase.deinit();

if (failureText.items.len != 0 and !applyAnyways) {
failureText.insertSlice(0, "Encountered errors while verifying your Account. This may happen if you created your account in a future version, in which case it's fine to continue.\n");

main.gui.windowlist.notification.raiseNotification("{s}", .{failureText.items});

applyAnyways = true;
applyButton.child.label.updateText("Apply anyways");

return;
}

main.network.authentication.KeyCollection.init(seedPhrase);

gui.closeWindowFromRef(&window);
if (settings.playerName.len == 0) {
gui.openWindow("change_name");
} else {
gui.openWindow("main");
}
}

fn updateText() void {
applyAnyways = false;
applyButton.child.label.updateText("Apply");
}

fn showTextCallback(showText: bool) void {
textComponent.obfuscated = !showText;
}

fn openCreateAccountWindow() void {
gui.closeWindowFromRef(&window);
gui.openWindow("authentication/create_account");
}

pub fn onOpen() void {
const list = VerticalList.init(.{padding, 16 + padding}, 300, 16);
const width = 420;
list.add(Label.init(.{0, 0}, width, "Please enter your account's seed phrase!", .center));
list.add(Label.init(.{0, 0}, width, "Note: We will only ask for the seed phrase on the start of the game.", .center));
list.add(Label.init(.{0, 0}, width, "Do not enter your seed phrase under any other circumstance and do not send it to anyone else.", .center));
textComponent = TextInput.init(.{0, 0}, width, 32, "", .{.onNewline = .init(apply), .onUpdate = .init(updateText)});
textComponent.obfuscated = true;
list.add(textComponent);
list.add(CheckBox.init(.{0, 0}, width, "Show text", false, &showTextCallback));
const buttonRow = HorizontalList.init();
buttonRow.add(Button.initText(.{0, 0}, 200, "Create new Account", .init(openCreateAccountWindow)));
applyButton = Button.initText(.{padding, 0}, 200, "Apply", .init(apply));
buttonRow.add(applyButton);
list.add(buttonRow);
list.finish(.center);
window.rootComponent = list.toComponent();
window.contentSize = window.rootComponent.?.pos() + window.rootComponent.?.size() + @as(Vec2f, @splat(padding));
gui.updateWindowPositions();
}

pub fn onClose() void {
// Make sure there remains no trace of the seed phrase in memory
@memset(textComponent.textBuffer.glyphs, std.mem.zeroes(@TypeOf(textComponent.textBuffer.glyphs[0])));
@memset(textComponent.currentString.items, 0);
main.Window.setClipboardString("");

if (window.rootComponent) |*comp| {
comp.deinit();
}
}
19 changes: 19 additions & 0 deletions src/gui/windows/authentication/logout.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
const std = @import("std");

const main = @import("main");
const settings = main.settings;
const Vec2f = main.vec.Vec2f;

const gui = main.gui;
const GuiComponent = gui.GuiComponent;
const GuiWindow = gui.GuiWindow;
const Button = GuiComponent.Button;
const CheckBox = GuiComponent.CheckBox;
const Label = GuiComponent.Label;
const TextInput = GuiComponent.TextInput;
const VerticalList = GuiComponent.VerticalList;

pub var window = GuiWindow{
.contentSize = Vec2f{128, 256},
.closeIfMouseIsGrabbed = true,
};
19 changes: 19 additions & 0 deletions src/gui/windows/authentication/unlock.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
const std = @import("std");

const main = @import("main");
const settings = main.settings;
const Vec2f = main.vec.Vec2f;

const gui = main.gui;
const GuiComponent = gui.GuiComponent;
const GuiWindow = gui.GuiWindow;
const Button = GuiComponent.Button;
const CheckBox = GuiComponent.CheckBox;
const Label = GuiComponent.Label;
const TextInput = GuiComponent.TextInput;
const VerticalList = GuiComponent.VerticalList;

pub var window = GuiWindow{
.contentSize = Vec2f{128, 256},
.closeIfMouseIsGrabbed = true,
};
8 changes: 3 additions & 5 deletions src/gui/windows/multiplayer.zig
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,8 @@ fn join() void {
main.game.world = &main.game.testWorld;
std.log.info("Connecting to server: {s}", .{ipAddressEntry.currentString.items});
main.game.testWorld.init(ipAddressEntry.currentString.items, _connection) catch |err| {
const formattedError = std.fmt.allocPrint(main.stackAllocator.allocator, "Encountered error while opening world: {s}", .{@errorName(err)}) catch unreachable;
defer main.stackAllocator.free(formattedError);
std.log.err("{s}", .{formattedError});
main.gui.windowlist.notification.raiseNotification(formattedError);
std.log.err("Encountered error while opening world: {s}", .{@errorName(err)});
main.gui.windowlist.notification.raiseNotification("Encountered error while opening world: {s}", .{@errorName(err)});
main.game.world = null;
_connection.world = null;
return;
Expand All @@ -73,7 +71,7 @@ fn join() void {
connection = null;
} else {
std.log.err("No connection found. Cannot connect.", .{});
main.gui.windowlist.notification.raiseNotification("No connection found. Cannot connect.");
main.gui.windowlist.notification.raiseNotification("No connection found. Cannot connect.", .{});
}
for (gui.openWindows.items) |openWindow| {
gui.closeWindowFromRef(openWindow);
Expand Down
8 changes: 4 additions & 4 deletions src/gui/windows/notification.zig
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,14 @@ pub fn deinit() void {
text = "";
}

fn setNotificationText(newText: []const u8) void {
fn setNotificationText(comptime formatText: []const u8, args: anytype) void {
main.globalAllocator.free(text);
text = main.globalAllocator.dupe(u8, newText);
text = std.fmt.allocPrint(main.globalAllocator.allocator, formatText, args) catch unreachable;
}

pub fn raiseNotification(notifText: []const u8) void {
pub fn raiseNotification(comptime formatText: []const u8, args: anytype) void {
main.gui.closeWindow("notification");
setNotificationText(notifText);
setNotificationText(formatText, args);
main.gui.openWindow("notification");
}

Expand Down
24 changes: 17 additions & 7 deletions src/main.zig
Original file line number Diff line number Diff line change
Expand Up @@ -601,13 +601,23 @@ pub fn main() void { // MARK: main()
}

pub fn clientMain() void { // MARK: clientMain()
if (settings.playerName.len == 0) {
gui.openWindow("change_name");
} else if (settings.launchConfig.autoEnterWorld.len == 0) {
gui.openWindow("main");
} else {
// Speed up the dev process by entering the world directly.
gui.windowlist.save_selection.openWorld(settings.launchConfig.autoEnterWorld);
switch (settings.accountState) {
.unknown => {
gui.openWindow("authentication/login");
},
.encrypted => {
gui.openWindow("authentication/unlock");
},
.stored => {
if (settings.playerName.len == 0) {
gui.openWindow("change_name");
} else if (settings.launchConfig.autoEnterWorld.len == 0) {
gui.openWindow("main");
} else {
// Speed up the dev process by entering the world directly.
gui.windowlist.save_selection.openWorld(settings.launchConfig.autoEnterWorld);
}
},
}

const c = Window.c;
Expand Down
2 changes: 2 additions & 0 deletions src/network.zig
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const settings = main.settings;
const utils = main.utils;
const NeverFailingAllocator = main.heap.NeverFailingAllocator;

pub const authentication = @import("network/authentication.zig");
pub const protocols = @import("network/protocols.zig");

// TODO: Might want to use SSL or something similar to encode the message
Expand Down Expand Up @@ -191,6 +192,7 @@ const Socket = struct {
pub fn init() void {
Socket.startup();
protocols.init();
authentication.init();
}

pub const Address = struct {
Expand Down
Loading