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
129 << " z3ed net proposal submit --description <DESC> --data <JSON>\n";
130 std::cout << " z3ed net proposal status --id <ID>\n";
131 std::cout << " z3ed net proposal wait --id <ID> [--timeout <SEC>]\n";
132 return absl::OkStatus();
133 }
134
135 std::string subcommand = args[0];
136 std::vector<std::string> subargs(args.begin() + 1, args.end());
137
138 if (subcommand == "submit") {
139 return HandleProposalSubmit(subargs);
140 } else if (subcommand == "status") {
141 return HandleProposalStatus(subargs);
142 } else if (subcommand == "wait") {
143 return HandleProposalWait(subargs);
144 } else {
145 return absl::InvalidArgumentError(
146 absl::StrFormat("Unknown proposal subcommand: %s", subcommand));
147 }
148}
149
150absl::Status HandleProposalSubmit(const std::vector<std::string>& args) {
151 std::string description;
152 std::string data_json;
153 std::string username = "cli_user"; // Default
154
155 for (size_t i = 0; i < args.size(); ++i) {
156 if (args[i] == "--description" && i + 1 < args.size()) {
157 description = args[i + 1];
158 ++i;
159 } else if (args[i] == "--data" && i + 1 < args.size()) {
160 data_json = args[i + 1];
161 ++i;
162 } else if (args[i] == "--username" && i + 1 < args.size()) {
163 username = args[i + 1];
164 ++i;
165 }
166 }
167
168 if (description.empty() || data_json.empty()) {
169 return absl::InvalidArgumentError(
170 "Usage: z3ed net proposal submit --description <DESC> --data <JSON>");
171 }
172
173 std::cout << "Submitting proposal..." << std::endl;
174 std::cout << " Description: " << description << std::endl;
175
176 auto status =
177 g_network_client->SubmitProposal(description, data_json, username);
178
179 if (status.ok()) {
180 std::cout << "✓ Proposal submitted" << std::endl;
181 std::cout << " Waiting for approval from host..." << std::endl;
182 } else {
183 std::cerr << "✗ Failed to submit: " << status.message() << std::endl;
184 }
185
186 return status;
187}
188
189absl::Status HandleProposalStatus(const std::vector<std::string>& args) {
190 std::string proposal_id;
191
192 for (size_t i = 0; i < args.size(); ++i) {
193 if (args[i] == "--id" && i + 1 < args.size()) {
194 proposal_id = args[i + 1];
195 ++i;
196 }
197 }
198
199 if (proposal_id.empty()) {
200 return absl::InvalidArgumentError(
201 "Usage: z3ed net proposal status --id <ID>");
202 }
203
204 auto status_result = g_network_client->GetProposalStatus(proposal_id);
205
206 if (status_result.ok()) {
207 std::cout << "Proposal " << proposal_id.substr(0, 8) << "..." << std::endl;
208 std::cout << " Status: " << *status_result << std::endl;
209 } else {
210 std::cerr << "✗ Failed to get status: " << status_result.status().message()
211 << std::endl;
212 }
213
214 return status_result.status();
215}
216
217absl::Status HandleProposalWait(const std::vector<std::string>& args) {
218 std::string proposal_id;
219 int timeout_seconds = 60;
220
221 for (size_t i = 0; i < args.size(); ++i) {
222 if (args[i] == "--id" && i + 1 < args.size()) {
223 proposal_id = args[i + 1];
224 ++i;
225 } else if (args[i] == "--timeout" && i + 1 < args.size()) {
226 timeout_seconds = std::stoi(args[i + 1]);
227 ++i;
228 }
229 }
230
231 if (proposal_id.empty()) {
232 return absl::InvalidArgumentError(
233 "Usage: z3ed net proposal wait --id <ID> [--timeout <SEC>]");
234 }
235
236 std::cout << "Waiting for approval (timeout: " << timeout_seconds << "s)..."
237 << std::endl;
238
239 auto approved_result =
240 g_network_client->WaitForApproval(proposal_id, timeout_seconds);
241
242 if (approved_result.ok()) {
243 if (*approved_result) {
244 std::cout << "✓ Proposal approved!" << std::endl;
245 } else {
246 std::cout << "✗ Proposal rejected" << std::endl;
247 }
248 } else {
249 std::cerr << "✗ Error: " << approved_result.status().message() << std::endl;
250 }
251
252 return approved_result.status();
253}
254
255absl::Status HandleNetStatus(const std::vector<std::string>& args) {
256 EnsureClient();
257
258 std::cout << "Network Status:" << std::endl;
259 std::cout << " Connected: "
260 << (g_network_client->IsConnected() ? "Yes" : "No") << std::endl;
261
262 return absl::OkStatus();
263}
264
265} // namespace net
266} // namespace cli
267} // 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)