diff --git a/src/network/network_client.cpp b/src/network/network_client.cpp index 1a177e87d3..008fe64294 100644 --- a/src/network/network_client.cpp +++ b/src/network/network_client.cpp @@ -31,6 +31,7 @@ #include "network_gamelist.h" #include "../core/backup_type.hpp" #include "../thread.h" +#include "../social_integration.h" #include "table/strings.h" @@ -845,6 +846,8 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_MAP_DONE(Packet SetLocalCompany(_network_join.company); } + SocialIntegration::EventEnterMultiplayer(Map::SizeX(), Map::SizeY()); + return NETWORK_RECV_STATUS_OKAY; } diff --git a/src/openttd.cpp b/src/openttd.cpp index 79642f43b1..f49f0792b8 100644 --- a/src/openttd.cpp +++ b/src/openttd.cpp @@ -1000,6 +1000,28 @@ bool SafeLoad(const std::string &filename, SaveLoadOperation fop, DetailedFileTy return false; } +static void UpdateSocialIntegration(GameMode game_mode) +{ + switch (game_mode) { + case GM_BOOTSTRAP: + case GM_MENU: + SocialIntegration::EventEnterMainMenu(); + break; + + case GM_NORMAL: + if (_networking) { + SocialIntegration::EventEnterMultiplayer(Map::SizeX(), Map::SizeY()); + } else { + SocialIntegration::EventEnterSingleplayer(Map::SizeX(), Map::SizeY()); + } + break; + + case GM_EDITOR: + SocialIntegration::EventEnterScenarioEditor(Map::SizeX(), Map::SizeY()); + break; + } +} + void SwitchToMode(SwitchMode new_mode) { /* If we are saving something, the network stays in its current state */ @@ -1047,6 +1069,8 @@ void SwitchToMode(SwitchMode new_mode) case SM_EDITOR: // Switch to scenario editor MakeNewEditorWorld(); GenerateSavegameId(); + + UpdateSocialIntegration(GM_EDITOR); break; case SM_RELOADGAME: // Reload with what-ever started the game @@ -1064,12 +1088,16 @@ void SwitchToMode(SwitchMode new_mode) MakeNewGame(false, new_mode == SM_NEWGAME); GenerateSavegameId(); + + UpdateSocialIntegration(GM_NORMAL); break; case SM_RESTARTGAME: // Restart --> 'Random game' with current settings case SM_NEWGAME: // New Game --> 'Random game' MakeNewGame(false, new_mode == SM_NEWGAME); GenerateSavegameId(); + + UpdateSocialIntegration(GM_NORMAL); break; case SM_LOAD_GAME: { // Load game, Play Scenario @@ -1087,6 +1115,8 @@ void SwitchToMode(SwitchMode new_mode) /* Decrease pause counter (was increased from opening load dialog) */ Command::Post(PM_PAUSED_SAVELOAD, false); } + + UpdateSocialIntegration(GM_NORMAL); break; } @@ -1094,6 +1124,8 @@ void SwitchToMode(SwitchMode new_mode) case SM_START_HEIGHTMAP: // Load a heightmap and start a new game from it MakeNewGame(true, new_mode == SM_START_HEIGHTMAP); GenerateSavegameId(); + + UpdateSocialIntegration(GM_NORMAL); break; case SM_LOAD_HEIGHTMAP: // Load heightmap from scenario editor @@ -1102,6 +1134,8 @@ void SwitchToMode(SwitchMode new_mode) GenerateWorld(GWM_HEIGHTMAP, 1 << _settings_game.game_creation.map_x, 1 << _settings_game.game_creation.map_y); GenerateSavegameId(); MarkWholeScreenDirty(); + + UpdateSocialIntegration(GM_NORMAL); break; case SM_LOAD_SCENARIO: { // Load scenario from scenario editor @@ -1115,12 +1149,16 @@ void SwitchToMode(SwitchMode new_mode) SetDParamStr(0, GetSaveLoadErrorString()); ShowErrorMessage(STR_JUST_RAW_STRING, INVALID_STRING_ID, WL_CRITICAL); } + + UpdateSocialIntegration(GM_NORMAL); break; } case SM_JOIN_GAME: // Join a multiplayer game LoadIntroGame(); NetworkClientJoinGame(); + + SocialIntegration::EventJoiningMultiplayer(); break; case SM_MENU: // Switch to game intro menu @@ -1137,6 +1175,8 @@ void SwitchToMode(SwitchMode new_mode) ShowNetworkAskSurvey(); } } + + UpdateSocialIntegration(GM_MENU); break; case SM_SAVE_GAME: // Save game. @@ -1547,4 +1587,5 @@ void GameLoop() SoundDriver::GetInstance()->MainLoop(); MusicLoop(); + SocialIntegration::RunCallbacks(); } diff --git a/src/social_integration.cpp b/src/social_integration.cpp index ec5042d7f2..609c8a678f 100644 --- a/src/social_integration.cpp +++ b/src/social_integration.cpp @@ -119,8 +119,84 @@ void SocialIntegration::Initialize() fs.Scan(); } +/** + * Wrapper to call a function pointer of a plugin if it isn't a nullptr. + * + * @param plugin Plugin to call the function pointer on. + * @param func Function pointer to call. + */ +template +static void PluginCall(std::unique_ptr &plugin, T func, Ts... args) +{ + if (plugin->external.state != SocialIntegrationPlugin::RUNNING) { + return; + } + + if (func != nullptr) { + func(args...); + } +} + void SocialIntegration::Shutdown() { + for (auto &plugin : _plugins) { + PluginCall(plugin, plugin->plugin_api.shutdown); + } + _plugins.clear(); _loaded_social_platform.clear(); } + +void SocialIntegration::RunCallbacks() +{ + for (auto &plugin : _plugins) { + if (plugin->external.state != SocialIntegrationPlugin::RUNNING) { + continue; + } + + if (plugin->plugin_api.run_callbacks != nullptr) { + if (!plugin->plugin_api.run_callbacks()) { + Debug(misc, 1, "[Social Plugin: {}] Requested to be unloaded", plugin->external.basepath); + + _loaded_social_platform.erase(plugin->plugin_info.social_platform); + plugin->external.state = SocialIntegrationPlugin::UNLOADED; + PluginCall(plugin, plugin->plugin_api.shutdown); + } + } + } +} + +void SocialIntegration::EventEnterMainMenu() +{ + for (auto &plugin : _plugins) { + PluginCall(plugin, plugin->plugin_api.event_enter_main_menu); + } +} + +void SocialIntegration::EventEnterScenarioEditor(uint map_width, uint map_height) +{ + for (auto &plugin : _plugins) { + PluginCall(plugin, plugin->plugin_api.event_enter_scenario_editor, map_width, map_height); + } +} + +void SocialIntegration::EventEnterSingleplayer(uint map_width, uint map_height) +{ + for (auto &plugin : _plugins) { + PluginCall(plugin, plugin->plugin_api.event_enter_singleplayer, map_width, map_height); + } +} + +void SocialIntegration::EventEnterMultiplayer(uint map_width, uint map_height) +{ + for (auto &plugin : _plugins) { + PluginCall(plugin, plugin->plugin_api.event_enter_multiplayer, map_width, map_height); + } +} + +void SocialIntegration::EventJoiningMultiplayer() +{ + for (auto &plugin : _plugins) { + PluginCall(plugin, plugin->plugin_api.event_joining_multiplayer); + } +} diff --git a/src/social_integration.h b/src/social_integration.h index f8f7e9eb5c..f4fa9f4faf 100644 --- a/src/social_integration.h +++ b/src/social_integration.h @@ -21,6 +21,36 @@ public: * Shutdown the social integration system, and all social integration plugins that are loaded. */ static void Shutdown(); + + /** + * Allow any social integration library to handle their own events. + */ + static void RunCallbacks(); + + /** + * Event: user entered the main menu. + */ + static void EventEnterMainMenu(); + + /** + * Event: user entered the Scenario Editor. + */ + static void EventEnterScenarioEditor(uint map_width, uint map_height); + + /** + * Event: user entered a singleplayer game. + */ + static void EventEnterSingleplayer(uint map_width, uint map_height); + + /** + * Event: user entered a multiplayer game. + */ + static void EventEnterMultiplayer(uint map_width, uint map_height); + + /** + * Event: user is joining a multiplayer game. + */ + static void EventJoiningMultiplayer(); }; #endif /* SOCIAL_INTEGRATION_H */