]> jxnshi.xyz Git - mesange.git/commitdiff
Client receive message master
authorjxnshi <jxnshi@cock.li>
Fri, 7 Mar 2025 15:11:37 +0000 (16:11 +0100)
committerjxnshi <jxnshi@cock.li>
Fri, 7 Mar 2025 15:11:37 +0000 (16:11 +0100)
client-cli/client-cli
client-cli/main.odin
client-cli/profile.odin
client-cli/room.odin [new file with mode: 0644]
common/request.odin
server/main.odin
server/server

index 0fa5051ce0226045fdaa0a3ca415911d1df0bad6..e20a6a3d1eb07cd2edaed4ba9b66937f34087217 100755 (executable)
Binary files a/client-cli/client-cli and b/client-cli/client-cli differ
index ecc845dd94920d6dc23eb094190d37fc3e4fc074..b61e2beb7449b09da66ab85f47db4028fc8cc01e 100644 (file)
@@ -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)
index 07651cadebd88e0ffa610dc3cb476b96c5e86718..2e842f3d7e349cb6b03c355f5771604dcaf80719 100644 (file)
@@ -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 (file)
index 0000000..b57d8ea
--- /dev/null
@@ -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
+}
index 9825c6324f459ea7c940f08cb8c5fdd75ac97f34..3ba4c3d1a8394b691609723c0f7a1eaedc41722c 100644 (file)
@@ -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
index 6b6169a24e0571fc0d91aab0700cb936ddb4a932..4c43da5a0cdfd0786e07cc32310d5c517c64c2d4 100644 (file)
@@ -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)
                     }
                 }
index 886322106591c3ddaa22594d33c908e2bf34ee09..15539ca2cc5bd0668a62610958724c434e32c10e 100755 (executable)
Binary files a/server/server and b/server/server differ