From: jxnshi Date: Fri, 7 Mar 2025 15:11:37 +0000 (+0100) Subject: Client receive message X-Git-Url: https://jxnshi.xyz/repos?a=commitdiff_plain;ds=sidebyside;p=mesange.git Client receive message --- diff --git a/client-cli/client-cli b/client-cli/client-cli index 0fa5051..e20a6a3 100755 Binary files a/client-cli/client-cli and b/client-cli/client-cli differ diff --git a/client-cli/main.odin b/client-cli/main.odin index ecc845d..b61e2be 100644 --- a/client-cli/main.odin +++ b/client-cli/main.odin @@ -34,6 +34,11 @@ json_marshal_options := json.Marshal_Options{ use_enum_names = true, } +Message :: struct { + timestamp: i64, + content: [common.MESSAGE_SIZE]u8, +} + App :: struct { ui_mutex: sync.Mutex, data_mutex: sync.Mutex, @@ -66,6 +71,8 @@ App :: struct { requests_callbacks: map[u32]Request_Callback, selected_room: int, + + messages: map[common.Room_ID][dynamic]Message, } app_init :: proc(storage_path: string) -> App { @@ -114,7 +121,9 @@ app_init :: proc(storage_path: string) -> App { info_bar = info_bar, input_window = input_window, - requests_callbacks= make(map[u32]Request_Callback), + requests_callbacks = make(map[u32]Request_Callback), + + messages = make(map[common.Room_ID][dynamic]Message), } app_update_info_bar(&app) @@ -128,6 +137,12 @@ app_deinit :: proc(app: ^App) { sync.mutex_lock(&app.data_mutex) defer sync.mutex_unlock(&app.data_mutex) + for messages in app.messages { + delete(messages) + } + + delete(app.messages) + delete(app.requests_callbacks) if host, ok := app.host.?; ok { @@ -823,7 +838,29 @@ handle_host :: proc(app: ^App) { continue } - #partial switch message in server_message { + switch message in server_message { + case common.Server_Request: + request := message + + #partial switch r in request { + case Push_Request: + user_message := Message{ + timestamp = message.timestamp, + content = request.message, + } + + { + sync.mutex_lock(&app.data_mutex) + defer sync.mutex_unlock(&app.data_mutex) + + if app.messages[request.room_id] == nil { + app.messages[request.room_id] = make([dynamic]Message) + } + + append(&app.messages[request.room_id], user_message) + } + } + case common.Server_Response: response := message defer common.server_response_deinit(response) diff --git a/client-cli/profile.odin b/client-cli/profile.odin index 07651ca..2e842f3 100644 --- a/client-cli/profile.odin +++ b/client-cli/profile.odin @@ -19,67 +19,6 @@ import fpath "core:path/filepath" import "../common" -Room_Name :: small_array.Small_Array(common.ROOM_NAME_SIZE, u8) - -Room :: struct { - name: Room_Name, - key: [common.ROOM_KEY_SIZE]u8, -} - -room_init :: proc(name: string, key: [common.ROOM_KEY_SIZE]u8) -> (Room, bool) { - _, name_len, _ := utf8.grapheme_count(name) - - if name_len > common.ROOM_NAME_LEN { - return {}, false - } - - name_bytes := transmute([]u8)name - - room_name: Room_Name - small_array.append_elems(&room_name, ..name_bytes) - - return { - name = room_name, - key = key, - }, - true -} - -room_init_with_key_string :: proc(name: string, key_string: string) -> (Room, bool) { - if len(key_string) != 44 { - return {}, false - } - - key_bytes: [common.ROOM_KEY_SIZE]u8 - - key_bytes_buffer := bytes.Buffer{ buf = mem.buffer_from_slice(key_bytes[:]) } - key_bytes_stream := bytes.buffer_to_stream(&key_bytes_buffer) - - err := base64.decode_into(key_bytes_stream, key_string) - - if err != nil { - return {}, false - } - - return room_init(name, key_bytes) -} - -room_get_name :: proc(room: ^Room) -> string { - bytes := small_array.slice(&room.name) - return string(bytes) -} - -room_get_id :: proc(room: ^Room) -> [sha3.DIGEST_SIZE_256]u8 { - sha3_context: sha3.Context - sha3.init_256(&sha3_context) - sha3.update(&sha3_context, room.key[:]) - - id: [sha3.DIGEST_SIZE_256]u8 - sha3.final(&sha3_context, id[:]) - - return id -} - Profile :: struct { private_key: ed25519.Private_Key, hosts: string, diff --git a/client-cli/room.odin b/client-cli/room.odin new file mode 100644 index 0000000..b57d8ea --- /dev/null +++ b/client-cli/room.odin @@ -0,0 +1,62 @@ +package main + +Room_Name :: small_array.Small_Array(common.ROOM_NAME_SIZE, u8) + +Room :: struct { + name: Room_Name, + key: [common.ROOM_KEY_SIZE]u8, +} + +room_init :: proc(name: string, key: [common.ROOM_KEY_SIZE]u8) -> (Room, bool) { + _, name_len, _ := utf8.grapheme_count(name) + + if name_len > common.ROOM_NAME_LEN { + return {}, false + } + + name_bytes := transmute([]u8)name + + room_name: Room_Name + small_array.append_elems(&room_name, ..name_bytes) + + return { + name = room_name, + key = key, + }, + true +} + +room_init_with_key_string :: proc(name: string, key_string: string) -> (Room, bool) { + if len(key_string) != 44 { + return {}, false + } + + key_bytes: [common.ROOM_KEY_SIZE]u8 + + key_bytes_buffer := bytes.Buffer{ buf = mem.buffer_from_slice(key_bytes[:]) } + key_bytes_stream := bytes.buffer_to_stream(&key_bytes_buffer) + + err := base64.decode_into(key_bytes_stream, key_string) + + if err != nil { + return {}, false + } + + return room_init(name, key_bytes) +} + +room_get_name :: proc(room: ^Room) -> string { + bytes := small_array.slice(&room.name) + return string(bytes) +} + +room_get_id :: proc(room: ^Room) -> common.Room_ID { + sha3_context: sha3.Context + sha3.init_256(&sha3_context) + sha3.update(&sha3_context, room.key[:]) + + id: [sha3.DIGEST_SIZE_256]u8 + sha3.final(&sha3_context, id[:]) + + return id +} diff --git a/common/request.odin b/common/request.odin index 9825c63..3ba4c3d 100644 --- a/common/request.odin +++ b/common/request.odin @@ -62,6 +62,7 @@ Sync_Request :: struct {} Push_Request :: struct { room_id: Room_ID, + timestamp: i64, message: [MESSAGE_SIZE]u8, } @@ -69,11 +70,17 @@ push_request_from_bytes :: proc(stream: io.Stream) -> (request: Push_Request, er room_id: Room_ID _ = io.read(stream, room_id[:]) or_return + timestamp_bytes: [size_of(i64)]u8 + _ = io.read(stream, timestamp_bytes[:]) or_return + + timestamp, _ := endian.get_i64(timestamp_bytes[:], .Little) + encrypted_message: [MESSAGE_SIZE]u8 _ = io.read(stream, encrypted_message[:]) or_return return { room_id = room_id, + timestamp = timestamp, message = encrypted_message, }, nil @@ -83,6 +90,11 @@ push_request_to_bytes :: proc(stream: io.Stream, request: Push_Request) -> Error request := request _ = io.write(stream, request.room_id[:]) or_return + + timestamp_bytes: [size_of(i64)]u8 + _ = endian.put_i64(timestamp_bytes[:], .Little, request.timestamp) + _ = io.write(stream, timestamp_bytes[:]) or_return + _ = io.write(stream, request.message[:]) or_return return nil diff --git a/server/main.odin b/server/main.odin index 6b6169a..4c43da5 100644 --- a/server/main.odin +++ b/server/main.odin @@ -22,8 +22,8 @@ Subscription :: struct { Client_Info :: struct { endpoint: net.Endpoint, - socket: net.TCP_Socket, public_key: ed25519.Public_Key, + socket: net.TCP_Socket, } App :: struct { @@ -63,16 +63,18 @@ app_get_client_info_by_endpoint :: proc(app: ^App, endpoint: net.Endpoint) -> ^C return nil } -app_get_client_info_by_public_key :: proc(app: ^App, public_key: ed25519.Public_Key) -> ^Client_Info { +app_get_clients_info_by_public_key :: proc(app: ^App, buffer: []^Client_Info, public_key: ed25519.Public_Key) -> []^Client_Info { public_key := public_key + i := 0 for &client_info in app.clients_info { if ed25519.public_key_equal(&client_info.public_key, &public_key) { - return &client_info + buffer[i] = &client_info + i += 1 } } - return nil + return buffer[:i] } app_delete_client_info :: proc(app: ^App, endpoint: net.Endpoint) { @@ -137,10 +139,7 @@ handle_client :: proc(data: Handle_Client_Data) { } } - defer { - log.infof("Response: %v", response) - send_response(client_socket, request_id, response) - } + defer send_response(client_socket, request_id, response) if err1 != nil { response := "Invalid request" @@ -152,33 +151,38 @@ handle_client :: proc(data: Handle_Client_Data) { continue } - log.infof("Received request: %v", request) - #partial switch &inner in request.inner { case common.Sync_Request: sync.mutex_lock(&app.data_mutex) defer sync.mutex_unlock(&app.data_mutex) client_info := app_get_client_info_by_endpoint(app, client_endpoint) - - if client_info != nil { - client_info.public_key = request.public_key - } + client_info.public_key = request.public_key case common.Push_Request: sync.mutex_lock(&app.data_mutex) defer sync.mutex_unlock(&app.data_mutex) for &subscription in app.subscriptions { - if slice.equal(subscription.room_id[:], inner.room_id[:]) { - client_info := app_get_client_info_by_public_key(app, subscription.public_key) - if client_info == nil do continue + if !slice.equal(subscription.room_id[:], inner.room_id[:]) { + continue + } + + clients_info_buffer: [100]^Client_Info + + clients_info := app_get_clients_info_by_public_key(app, clients_info_buffer[:], subscription.public_key) - request := common.Push_Request{ - room_id = inner.room_id, - message = inner.message, - } + if len(clients_info) == 0 { + continue + } + + request := common.Push_Request{ + room_id = inner.room_id, + timestamp = request.timestamp, + message = inner.message, + } + for client_info in clients_info { send_request(client_info.socket, request) } } diff --git a/server/server b/server/server index 8863221..15539ca 100755 Binary files a/server/server and b/server/server differ