]> jxnshi.xyz Git - mesange.git/commitdiff
Add favicon
authorjxnshi <jxnshi@cock.li>
Sun, 19 Jan 2025 16:25:37 +0000 (17:25 +0100)
committerjxnshi <jxnshi@cock.li>
Sun, 19 Jan 2025 16:25:51 +0000 (17:25 +0100)
client-cli/client-cli
client-cli/command.odin
client-cli/main.odin
client-cli/profile.odin
client-cli/state.odin

index f8e03945b4fe42385a1d46a04e55317468e01c92..f2552d029036fb66a90fd960b5d4da44e12e3640 100755 (executable)
Binary files a/client-cli/client-cli and b/client-cli/client-cli differ
index 39d0e7e1d6a40478ccff9a686700fa917c26fe21..5e6aa75afc51e58d1425eccdb7cbe420043a5755 100644 (file)
@@ -60,7 +60,7 @@ handle_command :: proc(app: ^App, command: string) -> Maybe(Handle_Command_Error
             return nil
         }
 
-    case .Invalid_Host:
+    case .Invalid_Hosts:
         switch command_name {
         case ":r", ":retry":
             app_set_state(app, .Connect_To_Host)
@@ -166,8 +166,9 @@ handle_command :: proc(app: ^App, command: string) -> Maybe(Handle_Command_Error
                 app_set_info_bar(app, "TODO")
                 return nil
 
-            case "host":
-                app_set_info_bar(app, "%v", app.profile.host)
+            case "hosts":
+                app_set_info_bar(app, "%v", app.profile.hosts)
+                return nil
 
             case:
                 app_set_info_bar(app, "Invalid field name.")
index b66bbae77fbe747d7b48f153f432fb9e2d41e5b9..c4f70c74aa6647755a08ee0766eb18d4f530d5fa 100644 (file)
@@ -69,6 +69,7 @@ app_init :: proc(storage_path: string) -> App {
 
     nc.noecho()
     nc.cbreak()
+    nc.timeout(0)
     nc.curs_set(0)
 
     nc.use_default_colors()
@@ -358,36 +359,42 @@ app_clear_box_message :: proc(app: ^App) {
 }
 
 handle_getch :: proc(app: ^App, buffer_len, cursor_pos: ^int) -> Maybe(int) {
-    char := int(nc.wgetch(app.input_window))
+    for {
+        char := nc.wgetch(app.input_window)
 
-    switch char {
-    case nc.KEY_BACKSPACE:
-        if cursor_pos^ != 0 {
-            buffer_len^ -= 1
-            cursor_pos^ -=1
+        if char == nc.ERR {
+            continue
         }
 
-        return nil
+        switch char {
+        case nc.KEY_BACKSPACE:
+            if cursor_pos^ != 0 {
+                buffer_len^ -= 1
+                cursor_pos^ -=1
+            }
 
-    case nc.KEY_LEFT:
-        if cursor_pos^ != 0 {
-            cursor_pos^ -= 1
-        }
+            return nil
 
-        return nil
+        case nc.KEY_LEFT:
+            if cursor_pos^ != 0 {
+                cursor_pos^ -= 1
+            }
 
-    case nc.KEY_RIGHT:
-        if cursor_pos^ != buffer_len^ {
-            cursor_pos^ += 1
-        }
+            return nil
 
-        return nil
+        case nc.KEY_RIGHT:
+            if cursor_pos^ != buffer_len^ {
+                cursor_pos^ += 1
+            }
+
+            return nil
 
-    case 0o400..=0o777:
-        return nil
+        case 0o400..=0o777:
+            return nil
 
-    case:
-        return char
+        case:
+            return int(char)
+        }
     }
 }
 
@@ -422,20 +429,19 @@ app_get_input :: proc(
                     buffer_len = 0
                     cursor_pos = 0
 
-                    continue
-                }
-
-                buffer_len += 1
+                case:
+                    buffer_len += 1
 
-                mem.copy(
-                    raw_data(buffer[cursor_pos + 1 : buffer_len]),
-                    raw_data(buffer[cursor_pos : buffer_len - 1]),
-                    int(buffer_len - cursor_pos - 1)
-                )
+                    mem.copy(
+                        raw_data(buffer[cursor_pos + 1 : buffer_len]),
+                        raw_data(buffer[cursor_pos : buffer_len - 1]),
+                        int(buffer_len - cursor_pos - 1)
+                    )
 
-                buffer[cursor_pos] = u8(char)
+                    buffer[cursor_pos] = u8(char)
 
-                cursor_pos += 1
+                    cursor_pos += 1
+                }
             }
 
             buffer[buffer_len] = 0
@@ -647,13 +653,13 @@ handle_state :: proc(app: ^App) {
         case .Invalid_Profile: state_invalid_profile(app)
         case .Ask_Profile: state_ask_profile(app)
         case .Ask_Profile_Seed_Phrase: state_ask_profile_seed_phrase(app)
-        case .Ask_Profile_Host: state_ask_profile_host(app)
+        case .Ask_Profile_Hosts: state_ask_profile_hosts(app)
         case .Ask_Profile_Set_Password: state_ask_profile_set_password(app)
         case .Ask_Profile_Confirm_Password: state_ask_profile_confirm_password(app)
         case .Ask_Profile_Password: state_ask_profile_password(app)
 
         case .Connect_To_Host: state_connect_to_host(app)
-        case .Invalid_Host: state_invalid_host(app)
+        case .Invalid_Hosts: state_invalid_hosts(app)
 
         case .Room_List: state_room_list(app)
         case .Room: state_room(app)
index 30ef64674c43d8c0cacda0dd06fca6563c9796a6..68f5c69c316a01ddcf0261befc7e5163a83e23f8 100644 (file)
@@ -57,13 +57,13 @@ room_get_name :: proc(room: ^Room) -> string {
 
 Profile :: struct {
     private_key: ed25519.Private_Key,
-    host: string,
+    hosts: string,
     rooms: [dynamic]Room,
 }
 
 Profile_Parsed :: struct {
     private_key: [ed25519.PRIVATE_KEY_SIZE]u8,
-    host: string,
+    hosts: string,
     rooms: [dynamic]Room,
 }
 
@@ -87,7 +87,7 @@ profile_from_parsed :: proc(parsed_profile: Profile_Parsed, allocator := context
 
     return {
         private_key = private_key,
-        host = parsed_profile.host,
+        hosts = parsed_profile.hosts,
         rooms = parsed_profile.rooms,
     }
 }
@@ -100,14 +100,14 @@ profile_to_parsed :: proc(profile: Profile) -> Profile_Parsed {
 
     return {
         private_key = private_key,
-        host = profile.host,
+        hosts = profile.hosts,
         rooms = profile.rooms,
     }
 }
 
 profile_deinit :: proc(profile: Profile) {
     delete(profile.rooms)
-    delete(profile.host)
+    delete(profile.hosts)
 }
 
 profile_load_from_name :: proc(name: string, app: ^App) -> (Profile, Maybe(Profile_Load_Error)) {
index e16dd4b0e04ea041b7b8e95dd7d31fd39b2ef1bf..e58a7d7ecae594d3dc7922b27f9f11ef94a0edd9 100644 (file)
@@ -24,13 +24,13 @@ State :: enum {
     Invalid_Profile,
     Ask_Profile,
     Ask_Profile_Seed_Phrase,
-    Ask_Profile_Host,
+    Ask_Profile_Hosts,
     Ask_Profile_Set_Password,
     Ask_Profile_Confirm_Password,
     Ask_Profile_Password,
 
     Connect_To_Host,
-    Invalid_Host,
+    Invalid_Hosts,
 
     Room_List,
     Room,
@@ -300,14 +300,15 @@ state_ask_profile_seed_phrase :: proc(app: ^App) {
         return
     }
 
-    app_set_state(app, .Ask_Profile_Host)
+    app_set_state(app, .Ask_Profile_Hosts)
 }
 
-state_ask_profile_host :: proc(app: ^App) {
+state_ask_profile_hosts :: proc(app: ^App) {
     app_set_box_message(
         app,
         {
-            "Enter your host.",
+            "Enter your hosts,",
+            "seperated with spaces.",
         },
     )
 
@@ -325,7 +326,7 @@ state_ask_profile_host :: proc(app: ^App) {
         sync.mutex_lock(&app.mutex)
         defer sync.mutex_unlock(&app.mutex)
 
-        app.profile.host = input
+        app.profile.hosts = input
     }
 
     app_set_state(app, .Ask_Profile_Set_Password)
@@ -386,60 +387,65 @@ state_ask_profile_confirm_password :: proc(app: ^App) {
 state_connect_to_host :: proc(app: ^App) {
     app_set_info_bar(app, "Connecting to host..")
 
-    host_endpoint: net.Endpoint
+    maybe_host: Maybe(net.TCP_Socket)
+    hosts := strings.clone(app.profile.hosts, context.temp_allocator)
 
-    blk: { // Resolve host endpoint.
-        ok: bool
-        host_endpoint, ok = net.parse_endpoint(app.profile.host)
+    for host_address in strings.split_iterator(&hosts, " ") {
+        host_endpoint: net.Endpoint
 
-        if ok {
-            break blk
+        resolve_endpoint: {
+            ok: bool
+            host_endpoint, ok = net.parse_endpoint(host_address)
+
+            if ok {
+                break resolve_endpoint
+            }
+
+            err: net.Network_Error
+            host_endpoint, err = net.resolve_ip4(host_address)
+
+            if err == nil {
+                break resolve_endpoint
+            }
+            
+            continue
         }
-        
-        err: net.Network_Error
-        host_endpoint, err = net.resolve_ip4(app.profile.host)
 
-        if err != nil {
-            log.errorf("Failed to resolve host with error: %v", err)
-            app_set_info_bar(app, "Connection failed.")
-            app_set_state(app, .Invalid_Host)
+        if host_endpoint.port == 0 {
+            host_endpoint.port = DEFAULT_PORT
+        }
 
-            return
+        host, err := net.dial_tcp_from_endpoint(host_endpoint)
+
+        if err != nil {
+            continue
         }
+        
+        maybe_host = host
     }
 
-    if host_endpoint.port == 0 {
-        host_endpoint.port = DEFAULT_PORT
-    }
-    
-    host, err := net.dial_tcp_from_endpoint(host_endpoint)
+    host, ok := maybe_host.?
 
-    if err != nil {
-        log.errorf("Failed to connect to host with error: %v", err)
-        app_set_info_bar(app, "Connection failed.")
-        app_set_state(app, .Invalid_Host)
+    if !ok {
+        app_set_info_bar(app, "Connection to host failed.")
+        app_set_state(app, .Invalid_Hosts)
 
         return
     }
 
     app_set_info_bar(app, "Connected to host.")
 
-    {
-        sync.mutex_lock(&app.mutex)
-        defer sync.mutex_unlock(&app.mutex)
-
-        app.host = host
-    }
+    app.host = host
 
     app_set_state(app, .Room_List)
 }
 
-state_invalid_host :: proc(app: ^App) {
+state_invalid_hosts :: proc(app: ^App) {
     app_set_box_message(
         app,
         {
-            "Failed to connect to host.",
-            "Either enter a new host,",
+            "Failed to connect to hosts.",
+            "Either enter a new hosts,",
             "or :retry."
         }
     )
@@ -455,13 +461,8 @@ state_invalid_host :: proc(app: ^App) {
         return
     }
 
-    {
-        sync.mutex_lock(&app.mutex)
-        defer sync.mutex_unlock(&app.mutex)
-
-        delete(app.profile.host)
-        app.profile.host = input
-    }
+    delete(app.profile.hosts)
+    app.profile.hosts = input
 
     profile_update(app.profile, app)