common/networking/messages.rs
1use std::fmt;
2use std::fmt::Formatter;
3use serde::{Deserialize, Serialize};
4use crate::logging::LogLevel;
5use crate::cli_actions::{CliAction, CliActionResponse};
6use crate::networking::subscription_objects::{SubscribeTopic, UpdateMode, TopicPayload};
7
8/// Unique identifier for an active client session.
9pub type SessionID = u64;
10
11/// Initial payload sent by a client upon connecting to verify compatibility.
12#[derive(Serialize, Deserialize, Debug)]
13pub struct HandshakeRequest {
14 /// Must always be exactly "REKTAL" to identify the protocol.
15 pub magic_string: String,
16 /// A hash verifying the client and server share the exact same network message definitions.
17 pub protocol_hash: String,
18 /// The human-readable version string of the client software.
19 pub client_version: String,
20}
21
22/// The kernel's response to a client's handshake request.
23#[derive(Serialize, Deserialize, Debug)]
24pub enum HandshakeResponse {
25 /// Handshake successful; protocol and versions match.
26 Ok,
27 /// Handshake failed due to a protocol hash mismatch.
28 Mismatch { server_version: String },
29}
30
31/// Represents all valid messages dispatched from a client to the kernel over an active TCP connection.
32#[derive(Serialize, Deserialize, Debug)]
33pub enum TcpClientMessage {
34 /// Request to authenticate a new session.
35 Login {
36 password: String,
37 user_name: String,
38 user_role: UserRole,
39 },
40
41 /// Request to safely terminate the current session.
42 Logout,
43
44 /// Request to resume a previous session using an existing token.
45 Relogin {
46 user_id: SessionID,
47 clear_subscriptions: bool,
48 },
49
50 /// Request to listen for state changes on a specific topic.
51 Subscribe {
52 topic: SubscribeTopic,
53 update_mode: UpdateMode
54 },
55
56 /// Request to stop receiving updates for a specific topic.
57 Unsubscribe {
58 topic: SubscribeTopic,
59 },
60
61 /// Submits a raw CLI string for the server to parse and execute.
62 ExecuteCommand {
63 command: String,
64 response_id: u32
65 },
66
67 /// Submits a pre-parsed, structured CLI action directly.
68 ExecuteImplicitCommand {
69 command: CliAction,
70 response_id: u32
71 },
72
73 /// Requests exclusive editing rights for a specific engine resource.
74 RequestEdit(EditableResource),
75
76 /// Submits modifications for an exclusively locked resource.
77 SubmitEdit {
78 resource: EditableResource,
79 new_data: Vec<u8>
80 },
81
82 /// Drops the Lock on an exclusively locked resource, giving other Clients the chance to lock it.
83 DropEditLock(EditableResource),
84}
85
86/// Represents all valid messages dispatched from the kernel back to a connected client.
87#[derive(Serialize, Deserialize, Debug, Clone)]
88pub enum TcpServerMessage {
89 /// Emitted when a client attempts an action before authenticating.
90 Unauthenticated,
91
92 /// Indicates a successful login, providing the session token (for reconnecting later).
93 LoginOk {token: SessionID},
94 /// Indicates a failed login attempt with the given reason.
95 LoginFailed {reason: String},
96
97 /// Indicates a successful session resumption.
98 ReloginOk {token: SessionID},
99 /// Indicates a failed session resumption.
100 ReloginFailed {reason: String},
101
102 /// Confirms the session has been terminated.
103 LogoutOk,
104
105 /// Informs the client that the server forcibly closed the connection.
106 Kicked {reason: String},
107
108 /// Contains the text and log level output of a standard string command execution.
109 CommandOutput {
110 answer: (LogLevel, String),
111 response_id: u32
112 },
113 /// Contains the structured response of an implicit (pre-parsed) command execution.
114 ImplicitCommandOutput {
115 answer: CliActionResponse,
116 response_id: u32
117 },
118
119 /// Broadcasts new state data for a subscribed topic.
120 TopicUpdate {
121 data: TopicPayload,
122 },
123
124 /// Grants the client exclusive edit access to a resource, providing its current state.
125 EditGranted {
126 resource: EditableResource,
127 current_data: Vec<u8>
128 },
129 /// Denies an edit request because the resource is already locked or unavailable.
130 EditDenied {
131 resource: EditableResource,
132 reason: String
133 },
134 /// Acknowledges, that the Resource-Lock has been dropped, and can be picked up by other clients
135 DropEditAck(EditableResource),
136
137 /// Notifies all clients that the server is gracefully shutting down.
138 ShutdownAnnouncement,
139}
140
141
142
143//Dummy Enum until I implement it right
144/// Identifies a specific engine resource that can be locked for exclusive editing. Has currently no functionality, will
145/// be implemented later.
146#[derive(Serialize, Deserialize, Debug, Clone)]
147pub enum EditableResource {
148 Cuelist,
149}
150
151//This is only Temporarily here, will be moved to a different location once this location is programmed
152//Also, Interface may not belong here, that's why ist commented out, since it should be handled differently than the GUIs
153/// Defines the permission level and operational scope of a connected user.
154#[derive(Serialize, Deserialize, Debug, Copy, Clone, PartialEq)]
155pub enum UserRole {
156 /// Full access to edit the show and trigger outputs.
157 Programmer,
158 /// Access to edit the show without affecting live outputs (blind programming).
159 BlindProgrammer,
160 /// Access to trigger playbacks and run the show, but restricted from editing structural data.
161 Showrunner,
162// Interface
163}
164
165impl fmt::Display for UserRole {
166 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
167 let text = match self {
168 UserRole::Programmer => "programmer",
169 UserRole::BlindProgrammer => "blind programmer",
170 UserRole::Showrunner => "showrunner",
171 };
172
173 write!(f, "{text}")
174 }
175}
176
177/// Retrieves the compile-time protocol hash to verify network message compatibility.
178pub fn get_protocol_version() -> String {
179 env!("PROTOCOL_HASH").to_string()
180}