yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
net_commands.cc
Go to the documentation of this file.
2
3#include <iostream>
4#include <thread>
5
6#include "absl/strings/str_format.h"
7#include "absl/time/clock.h"
8#include "absl/time/time.h"
9
10#ifdef YAZE_WITH_JSON
11#include "nlohmann/json.hpp"
12#endif
13
14namespace yaze {
15namespace cli {
16namespace net {
17
18namespace {
19
20// Global network client for CLI operations
21std::unique_ptr<Z3edNetworkClient> g_network_client;
22
24 if (!g_network_client) {
25 g_network_client = std::make_unique<Z3edNetworkClient>();
26 }
27}
28
29} // namespace
30
31absl::Status HandleNetConnect(const std::vector<std::string>& args) {
32 EnsureClient();
33
34 std::string host = "localhost";
35 int port = 8765;
36
37 // Parse arguments
38 for (size_t i = 0; i < args.size(); ++i) {
39 if (args[i] == "--host" && i + 1 < args.size()) {
40 host = args[i + 1];
41 ++i;
42 } else if (args[i] == "--port" && i + 1 < args.size()) {
43 port = std::stoi(args[i + 1]);
44 ++i;
45 }
46 }
47
48 std::cout << "Connecting to " << host << ":" << port << "..." << std::endl;
49
50 auto status = g_network_client->Connect(host, port);
51
52 if (status.ok()) {
53 std::cout << "✓ Connected to yaze-server" << std::endl;
54 } else {
55 std::cerr << "✗ Connection failed: " << status.message() << std::endl;
56 }
57
58 return status;
59}
60
61absl::Status HandleNetJoin(const std::vector<std::string>& args) {
62 EnsureClient();
63
64 if (!g_network_client->IsConnected()) {
65 return absl::FailedPreconditionError(
66 "Not connected. Run: z3ed net connect");
67 }
68
69 std::string session_code;
70 std::string username;
71
72 // Parse arguments
73 for (size_t i = 0; i < args.size(); ++i) {
74 if (args[i] == "--code" && i + 1 < args.size()) {
75 session_code = args[i + 1];
76 ++i;
77 } else if (args[i] == "--username" && i + 1 < args.size()) {
78 username = args[i + 1];
79 ++i;
80 }
81 }
82
83 if (session_code.empty() || username.empty()) {
84 return absl::InvalidArgumentError(
85 "Usage: z3ed net join --code <CODE> --username <NAME>");
86 }
87
88 std::cout << "Joining session " << session_code << " as " << username << "..."
89 << std::endl;
90
91 auto status = g_network_client->JoinSession(session_code, username);
92
93 if (status.ok()) {
94 std::cout << "✓ Joined session successfully" << std::endl;
95 } else {
96 std::cerr << "✗ Failed to join: " << status.message() << std::endl;
97 }
98
99 return status;
100}
101
102absl::Status HandleNetLeave(const std::vector<std::string>& args) {
103 EnsureClient();
104
105 if (!g_network_client->IsConnected()) {
106 return absl::FailedPreconditionError("Not connected");
107 }
108
109 std::cout << "Leaving session..." << std::endl;
110
111 g_network_client->Disconnect();
112
113 std::cout << "✓ Left session" << std::endl;
114
115 return absl::OkStatus();
116}
117
118absl::Status HandleNetProposal(const std::vector<std::string>& args) {
119 EnsureClient();
120
121 if (!g_network_client->IsConnected()) {
122 return absl::FailedPreconditionError(
123 "Not connected. Run: z3ed net connect");
124 }
125
126 if (args.empty()) {
127 std::cout << "Usage:\n";
128 std::cout << " z3ed net proposal submit --description <DESC> --data <JSON>\n";
129 std::cout << " z3ed net proposal status --id <ID>\n";
130 std::cout << " z3ed net proposal wait --id <ID> [--timeout <SEC>]\n";
131 return absl::OkStatus();
132 }
133
134 std::string subcommand = args[0];
135 std::vector<std::string> subargs(args.begin() + 1, args.end());
136
137 if (subcommand == "submit") {
138 return HandleProposalSubmit(subargs);
139 } else if (subcommand == "status") {
140 return HandleProposalStatus(subargs);
141 } else if (subcommand == "wait") {
142 return HandleProposalWait(subargs);
143 } else {
144 return absl::InvalidArgumentError(
145 absl::StrFormat("Unknown proposal subcommand: %s", subcommand));
146 }
147}
148
149absl::Status HandleProposalSubmit(const std::vector<std::string>& args) {
150 std::string description;
151 std::string data_json;
152 std::string username = "cli_user"; // Default
153
154 for (size_t i = 0; i < args.size(); ++i) {
155 if (args[i] == "--description" && i + 1 < args.size()) {
156 description = args[i + 1];
157 ++i;
158 } else if (args[i] == "--data" && i + 1 < args.size()) {
159 data_json = args[i + 1];
160 ++i;
161 } else if (args[i] == "--username" && i + 1 < args.size()) {
162 username = args[i + 1];
163 ++i;
164 }
165 }
166
167 if (description.empty() || data_json.empty()) {
168 return absl::InvalidArgumentError(
169 "Usage: z3ed net proposal submit --description <DESC> --data <JSON>");
170 }
171
172 std::cout << "Submitting proposal..." << std::endl;
173 std::cout << " Description: " << description << std::endl;
174
175 auto status = g_network_client->SubmitProposal(
176 description,
177 data_json,
178 username
179 );
180
181 if (status.ok()) {
182 std::cout << "✓ Proposal submitted" << std::endl;
183 std::cout << " Waiting for approval from host..." << std::endl;
184 } else {
185 std::cerr << "✗ Failed to submit: " << status.message() << std::endl;
186 }
187
188 return status;
189}
190
191absl::Status HandleProposalStatus(const std::vector<std::string>& args) {
192 std::string proposal_id;
193
194 for (size_t i = 0; i < args.size(); ++i) {
195 if (args[i] == "--id" && i + 1 < args.size()) {
196 proposal_id = args[i + 1];
197 ++i;
198 }
199 }
200
201 if (proposal_id.empty()) {
202 return absl::InvalidArgumentError(
203 "Usage: z3ed net proposal status --id <ID>");
204 }
205
206 auto status_result = g_network_client->GetProposalStatus(proposal_id);
207
208 if (status_result.ok()) {
209 std::cout << "Proposal " << proposal_id.substr(0, 8) << "..." << std::endl;
210 std::cout << " Status: " << *status_result << std::endl;
211 } else {
212 std::cerr << "✗ Failed to get status: " << status_result.status().message()
213 << std::endl;
214 }
215
216 return status_result.status();
217}
218
219absl::Status HandleProposalWait(const std::vector<std::string>& args) {
220 std::string proposal_id;
221 int timeout_seconds = 60;
222
223 for (size_t i = 0; i < args.size(); ++i) {
224 if (args[i] == "--id" && i + 1 < args.size()) {
225 proposal_id = args[i + 1];
226 ++i;
227 } else if (args[i] == "--timeout" && i + 1 < args.size()) {
228 timeout_seconds = std::stoi(args[i + 1]);
229 ++i;
230 }
231 }
232
233 if (proposal_id.empty()) {
234 return absl::InvalidArgumentError(
235 "Usage: z3ed net proposal wait --id <ID> [--timeout <SEC>]");
236 }
237
238 std::cout << "Waiting for approval (timeout: " << timeout_seconds << "s)..."
239 << std::endl;
240
241 auto approved_result = g_network_client->WaitForApproval(
242 proposal_id,
243 timeout_seconds
244 );
245
246 if (approved_result.ok()) {
247 if (*approved_result) {
248 std::cout << "✓ Proposal approved!" << std::endl;
249 } else {
250 std::cout << "✗ Proposal rejected" << std::endl;
251 }
252 } else {
253 std::cerr << "✗ Error: " << approved_result.status().message() << std::endl;
254 }
255
256 return approved_result.status();
257}
258
259absl::Status HandleNetStatus(const std::vector<std::string>& args) {
260 EnsureClient();
261
262 std::cout << "Network Status:" << std::endl;
263 std::cout << " Connected: "
264 << (g_network_client->IsConnected() ? "Yes" : "No") << std::endl;
265
266 return absl::OkStatus();
267}
268
269} // namespace net
270} // namespace cli
271} // namespace yaze
std::unique_ptr< Z3edNetworkClient > g_network_client
absl::Status HandleNetProposal(const std::vector< std::string > &args)
absl::Status HandleProposalWait(const std::vector< std::string > &args)
absl::Status HandleNetConnect(const std::vector< std::string > &args)
absl::Status HandleProposalSubmit(const std::vector< std::string > &args)
absl::Status HandleProposalStatus(const std::vector< std::string > &args)
absl::Status HandleNetLeave(const std::vector< std::string > &args)
absl::Status HandleNetJoin(const std::vector< std::string > &args)
absl::Status HandleNetStatus(const std::vector< std::string > &args)
Main namespace for the application.
Definition controller.cc:20