6#include "absl/strings/str_format.h"
14 version_mgr_(nullptr),
15 approval_mgr_(nullptr),
17 sync_in_progress_(false) {}
31 return absl::InvalidArgumentError(
"version_mgr cannot be null");
35 return absl::InvalidArgumentError(
"approval_mgr cannot be null");
39 client_->OnMessage(
"rom_sync", [
this](
const nlohmann::json& payload) {
43 client_->OnMessage(
"proposal_shared", [
this](
const nlohmann::json& payload) {
48 "proposal_vote_received",
51 client_->OnMessage(
"proposal_updated", [
this](
const nlohmann::json& payload) {
59 client_->OnMessage(
"participant_left", [
this](
const nlohmann::json& payload) {
68 return absl::OkStatus();
72 return client_->Connect(host, port);
82 const std::string& username,
85 return absl::FailedPreconditionError(
"Not connected to server");
89 return absl::FailedPreconditionError(
"ROM not loaded");
100 if (snapshot_result.ok()) {
105 auto session_result =
106 client_->HostSession(session_name, username, rom_hash, ai_enabled);
108 if (!session_result.ok()) {
109 return session_result.status();
114 return absl::OkStatus();
118 const std::string& username) {
120 return absl::FailedPreconditionError(
"Not connected to server");
124 return absl::FailedPreconditionError(
"ROM not loaded");
128 auto snapshot_result =
131 if (snapshot_result.ok()) {
136 auto session_result =
client_->JoinSession(session_code, username);
138 if (!session_result.ok()) {
139 return session_result.status();
144 return absl::OkStatus();
149 return absl::FailedPreconditionError(
"Not in a session");
152 return client_->LeaveSession();
156 const std::string& description,
const std::string& username) {
158 return absl::FailedPreconditionError(
"Not in a session");
162 return absl::FailedPreconditionError(
"ROM not loaded");
168 return absl::OkStatus();
174 nlohmann::json proposal_data = {{
"description", description},
175 {
"type",
"rom_modification"},
178 {
"to_hash", current_hash}};
181 auto status =
client_->ShareProposal(proposal_data, username);
192 const std::string& rom_hash,
193 const std::string& sender) {
195 return absl::FailedPreconditionError(
"ROM not loaded");
199 return absl::UnavailableError(
"Sync already in progress");
207 absl::StrFormat(
"Before sync from %s", sender),
"system",
false);
209 if (!snapshot_result.ok()) {
211 return absl::InternalError(
"Failed to create backup snapshot");
224 if (!snapshots.empty()) {
235 const std::string& proposal_id,
const nlohmann::json& proposal_data,
236 const std::string& sender) {
238 return absl::FailedPreconditionError(
"Approval manager not initialized");
243 proposal_id, sender, proposal_data[
"description"], proposal_data);
247 const std::string& proposal_id,
bool approved,
248 const std::string& username) {
250 return absl::FailedPreconditionError(
"Not in a session");
261 return client_->VoteOnProposal(proposal_id, approved, username);
265 const std::string& proposal_id) {
267 return absl::FailedPreconditionError(
"Proposal not approved");
271 if (!proposal_result.ok()) {
272 return proposal_result.status();
277 auto status =
client_->UpdateProposalStatus(proposal_id,
"applied");
282 absl::StrFormat(
"Applied proposal %s", proposal_id.substr(0, 8)),
294 return client_->GetSessionInfo();
304 std::string diff_data = payload[
"diff_data"];
305 std::string rom_hash = payload[
"rom_hash"];
306 std::string sender = payload[
"sender"];
308 auto status =
ApplyRomSync(diff_data, rom_hash, sender);
316 std::string proposal_id = payload[
"proposal_id"];
317 nlohmann::json proposal_data = payload[
"proposal_data"];
318 std::string sender = payload[
"sender"];
324 std::string proposal_id = payload[
"proposal_id"];
326 if (payload.contains(
"status")) {
327 std::string status = payload[
"status"];
335 if (payload.contains(
"votes")) {
337 nlohmann::json votes = payload[
"votes"];
343 std::string username = payload[
"username"];
348 std::string username = payload[
"username"];
355 const std::string& to_hash) {
367 return "diff_placeholder";
372 return absl::FailedPreconditionError(
"ROM not loaded");
378 return absl::OkStatus();
The Rom class is used to load, save, and modify Rom data. This is a generic SNES ROM container and do...
CollaborationService(Rom *rom)
absl::Status LeaveSession()
std::unique_ptr< WebSocketClient > client_
absl::Status ApplyApprovedProposal(const std::string &proposal_id)
void OnProposalUpdated(const nlohmann::json &payload)
absl::Status VoteOnProposal(const std::string &proposal_id, bool approved, const std::string &username)
absl::Status HandleIncomingProposal(const std::string &proposal_id, const nlohmann::json &proposal_data, const std::string &sender)
absl::Status Initialize(const Config &config, RomVersionManager *version_mgr, ProposalApprovalManager *approval_mgr)
void OnProposalReceived(const nlohmann::json &payload)
void OnRomSyncReceived(const nlohmann::json &payload)
void SetAutoSync(bool enabled)
std::string last_sync_hash_
RomVersionManager * version_mgr_
absl::Status ApplyRomSync(const std::string &diff_data, const std::string &rom_hash, const std::string &sender)
absl::StatusOr< SessionInfo > GetSessionInfo() const
absl::Status SubmitChangesAsProposal(const std::string &description, const std::string &username)
ProposalApprovalManager * approval_mgr_
void OnParticipantJoined(const nlohmann::json &payload)
absl::Status Connect(const std::string &host, int port=8765)
absl::Status JoinSession(const std::string &session_code, const std::string &username)
absl::Status ApplyDiff(const std::string &diff_data)
absl::Status HostSession(const std::string &session_name, const std::string &username, bool ai_enabled=true)
void OnParticipantLeft(const nlohmann::json &payload)
std::string GenerateDiff(const std::string &from_hash, const std::string &to_hash)
Manages proposal approval workflow for collaborative sessions.
absl::StatusOr< ApprovalStatus > GetProposalStatus(const std::string &proposal_id) const
absl::Status VoteOnProposal(const std::string &proposal_id, const std::string &username, bool approved)
bool IsProposalApproved(const std::string &proposal_id) const
absl::Status SubmitProposal(const std::string &proposal_id, const std::string &sender, const std::string &description, const nlohmann::json &proposal_data)
Manages ROM versioning, snapshots, and rollback capabilities.
absl::StatusOr< std::string > CreateSnapshot(const std::string &description, const std::string &creator, bool is_checkpoint=false)
std::string GetCurrentHash() const
absl::Status RestoreSnapshot(const std::string &snapshot_id)
absl::Status MarkAsSafePoint(const std::string &snapshot_id)
std::vector< RomSnapshot > GetSnapshots(bool safe_points_only=false) const
WebSocket client for connecting to yaze-server.
bool require_approval_for_sync
bool create_snapshot_before_sync