From e58fc9c38f2bab77027733c85bf637f8fa073b1c Mon Sep 17 00:00:00 2001 From: Green Sky Date: Mon, 27 Nov 2023 18:45:38 +0100 Subject: [PATCH] more wiring --- src/solanaceae/toxic_games/games/chess.cpp | 35 +++++++++++++- src/solanaceae/toxic_games/games/chess.hpp | 10 +++- src/solanaceae/toxic_games/toxic_games.cpp | 53 ++++++++++++++++++++++ 3 files changed, 95 insertions(+), 3 deletions(-) diff --git a/src/solanaceae/toxic_games/games/chess.cpp b/src/solanaceae/toxic_games/games/chess.cpp index 5b210fd..b79f569 100644 --- a/src/solanaceae/toxic_games/games/chess.cpp +++ b/src/solanaceae/toxic_games/games/chess.cpp @@ -1,5 +1,24 @@ #include "./chess.hpp" +#include "../toxic_games.hpp" + +Chess::ChessInstance::ChessInstance( + Chess& game_type_static, + uint32_t game_id +) : _game_type_static(game_type_static) { + _id = game_id; +} + +void Chess::ChessInstance::quit(void) { +} + +bool Chess::ChessInstance::allInvitesAccepted(void) { + return false; +} + +void Chess::ChessInstance::onPacket(uint32_t from, const uint8_t* data, const uint32_t data_size) { +} + Chess::Chess(ToxicGames& tg) : ToxicGameI(tg) { } @@ -10,7 +29,19 @@ std::unique_ptr Chess::createGame(std::vector with) return nullptr; } -std::unique_ptr Chess::acceptInvite(uint32_t from, uint32_t id) { - return nullptr; +std::unique_ptr Chess::acceptInvite(uint32_t from, uint32_t game_id) { + sendAcceptInvite(from, game_id); + + auto new_instance = std::make_unique(*this, game_id); + + return new_instance; +} + +bool Chess::sendAcceptInvite(uint32_t to, uint32_t game_id) { + std::vector pkg; + + // init accept invite (chess specific) + pkg.push_back(0x02); + return _tg.sendPacket(static_cast(to), getGameType(), game_id, pkg.data(), pkg.size()); } diff --git a/src/solanaceae/toxic_games/games/chess.hpp b/src/solanaceae/toxic_games/games/chess.hpp index 411b741..c8a4eae 100644 --- a/src/solanaceae/toxic_games/games/chess.hpp +++ b/src/solanaceae/toxic_games/games/chess.hpp @@ -7,6 +7,10 @@ struct Chess final : public ToxicGameI { ~Chess(void); struct ChessInstance final : public ToxicGameI::InstanceI { + Chess& _game_type_static; + + ChessInstance(Chess& game_type_static, uint32_t game_id); + ~ChessInstance(void) {} // TODO: just destructor? @@ -19,11 +23,15 @@ struct Chess final : public ToxicGameI { // ?? //virtual void tick(); + }; uint8_t getGameType(void) const override { return 1; }; std::unique_ptr createGame(std::vector with) override; - std::unique_ptr acceptInvite(uint32_t from, uint32_t id) override; + std::unique_ptr acceptInvite(uint32_t from, uint32_t game_id) override; + + private: + bool sendAcceptInvite(uint32_t to, uint32_t game_id); }; diff --git a/src/solanaceae/toxic_games/toxic_games.cpp b/src/solanaceae/toxic_games/toxic_games.cpp index 45d0eaf..5793c4f 100644 --- a/src/solanaceae/toxic_games/toxic_games.cpp +++ b/src/solanaceae/toxic_games/toxic_games.cpp @@ -43,6 +43,30 @@ void ToxicGames::createGame(uint8_t game_type, std::vector with) { } void ToxicGames::acceptInvite(Contact3 from, uint8_t game_type, uint32_t game_id) { + if (!_cr.valid(from)) { + return; + } + + // online gaming + if (!_cr.all_of(from) && !_cr.all_of(from)) { + return; + } + + // instanciate from invite + if (!_game_types.count(game_type)) { + return; // error + } + + auto& game_type_static = _game_types.at(game_type); + + { + auto new_instance = game_type_static->acceptInvite(static_cast(from), game_id); + if (!new_instance) { + return; // error + } + + _game_instances[game_type][game_id] = std::move(new_instance); + } } bool ToxicGames::sendPacket(Contact3 to, uint8_t game_type, uint32_t game_id, const uint8_t* data, const size_t data_size) { @@ -116,8 +140,37 @@ bool ToxicGames::onToxEvent(const Tox_Event_Friend_Lossless_Packet* e) { if (data[0] == 160) { std::cout << "TG: game invite packet gt:" << (uint32_t)game_type << " id:" << game_id << "\n"; + + if (_game_types.count(game_type)) { + if (!_game_instances[game_type].count(game_id)) { + const Contact3 from = _tcm.getContactFriend(friend_number); + + // HACK: auto accept + std::cout << "TG: autoaccepting game ...\n"; + acceptInvite(from, game_type, game_id); + } else { + std::cerr << "TG error: game invite for existing game id gt:" << (uint32_t)game_type << " id:" << game_id << "\n"; + } + } else { + // unknown/unsupported game + std::cerr << "TG warning: unknown/unsupported game" << (uint32_t)game_type << "\n"; + } + } else if (data[0] == 161) { std::cout << "TG: game packet gt:" << (uint32_t)game_type << " id:" << game_id << "\n"; + + if (_game_types.count(game_type)) { + if (_game_instances[game_type].count(game_id)) { + const Contact3 from = _tcm.getContactFriend(friend_number); + _game_instances.at(game_type).at(game_id)->onPacket(static_cast(from), nullptr, 0); + } else { + // error, unk game + std::cerr << "TG error: packet for unknown game id gt:" << (uint32_t)game_type << " id:" << game_id << "\n"; + } + } else { + // unknown/unsupported game + std::cerr << "TG warning: unknown/unsupported game" << (uint32_t)game_type << "\n"; + } } return true;