diff --git a/setup.bat b/setup.bat index e6a55ecf..be59b2ff 100644 --- a/setup.bat +++ b/setup.bat @@ -1,8 +1,47 @@ -rmdir output\cpp\Party +rmdir /s /q output\cpp\Analytics +mklink /J output\cpp\Analytics src\Stormancer.Plugins\Analytics\cpp + +rmdir /s /q output\cpp\Epic +mklink /J output\cpp\Epic src\Stormancer.Plugins\Epic\cpp + +rmdir /s /q output\cpp\Friends +mklink /J output\cpp\Friends src\Stormancer.Plugins\Friends\cpp + +rmdir /s /q output\cpp\Galaxy +mklink /J output\cpp\Galaxy src\Stormancer.Plugins\Galaxy\cpp + +rmdir /s /q output\cpp\GameFinder +mklink /J output\cpp\GameFinder src\Stormancer.Plugins\GameFinder\cpp + +rmdir /s /q output\cpp\GameSession +mklink /J output\cpp\GameSession src\Stormancer.Plugins\GameSession\cpp + +rmdir /s /q output\cpp\GameVersion +mklink /J output\cpp\GameVersion src\Stormancer.Plugins\GameVersion\cpp + +rmdir /s /q output\cpp\Leaderboards +mklink /J output\cpp\Leaderboards src\Stormancer.Plugins\Leaderboards\cpp + +rmdir /s /q output\cpp\Notification +mklink /J output\cpp\Notification src\Stormancer.Plugins\Notification\cpp + +rmdir /s /q output\cpp\Party mklink /J output\cpp\Party src\Stormancer.Plugins\Party\cpp -rmdir output\cpp\Steam +rmdir /s /q output\cpp\Profile +mklink /J output\cpp\Profile src\Stormancer.Plugins\Profile\cpp + +rmdir /s /q output\cpp\Replication +mklink /J output\cpp\Replication src\Stormancer.Plugins\Replication\cpp + +rmdir /s /q output\cpp\SocketApi +mklink /J output\cpp\SocketApi src\Stormancer.Plugins\SocketApi\cpp + +rmdir /s /q output\cpp\Spectate +mklink /J output\cpp\Spectate src\Stormancer.Plugins\Spectate\cpp + +rmdir /s /q output\cpp\Steam mklink /J output\cpp\Steam src\Stormancer.Plugins\Steam\cpp -rmdir output\cpp\gamesession -mklink /J output\cpp\gamesession src\Stormancer.Plugins\GameSession\cpp \ No newline at end of file +rmdir /s /q output\cpp\Users +mklink /J output\cpp\Users src\Stormancer.Plugins\Users\cpp diff --git a/src/Stormancer.Plugins/Analytics/Stormancer.Server.Plugins.Analytics/Stormancer.Server.Plugins.Analytics.csproj b/src/Stormancer.Plugins/Analytics/Stormancer.Server.Plugins.Analytics/Stormancer.Server.Plugins.Analytics.csproj index 78ed400e..43f148e7 100644 --- a/src/Stormancer.Plugins/Analytics/Stormancer.Server.Plugins.Analytics/Stormancer.Server.Plugins.Analytics.csproj +++ b/src/Stormancer.Plugins/Analytics/Stormancer.Server.Plugins.Analytics/Stormancer.Server.Plugins.Analytics.csproj @@ -47,6 +47,5 @@ - diff --git a/src/Stormancer.Plugins/Epic/Stormancer.Server.Plugins.Epic/Stormancer.Server.Plugins.Epic.csproj b/src/Stormancer.Plugins/Epic/Stormancer.Server.Plugins.Epic/Stormancer.Server.Plugins.Epic.csproj index 94d9f4e3..e3c79479 100644 --- a/src/Stormancer.Plugins/Epic/Stormancer.Server.Plugins.Epic/Stormancer.Server.Plugins.Epic.csproj +++ b/src/Stormancer.Plugins/Epic/Stormancer.Server.Plugins.Epic/Stormancer.Server.Plugins.Epic.csproj @@ -67,7 +67,6 @@ - diff --git a/src/Stormancer.Plugins/Friends/Stormancer.Server.Plugins.Friends/Stormancer.Server.Plugins.Friends.csproj b/src/Stormancer.Plugins/Friends/Stormancer.Server.Plugins.Friends/Stormancer.Server.Plugins.Friends.csproj index b00cae26..d3bb99f0 100644 --- a/src/Stormancer.Plugins/Friends/Stormancer.Server.Plugins.Friends/Stormancer.Server.Plugins.Friends.csproj +++ b/src/Stormancer.Plugins/Friends/Stormancer.Server.Plugins.Friends/Stormancer.Server.Plugins.Friends.csproj @@ -42,7 +42,6 @@ - diff --git a/src/Stormancer.Plugins/Galaxy/Stormancer.Server.Plugins.Galaxy/Stormancer.Server.Plugins.Galaxy.csproj b/src/Stormancer.Plugins/Galaxy/Stormancer.Server.Plugins.Galaxy/Stormancer.Server.Plugins.Galaxy.csproj index 41e628af..89d72f6a 100644 --- a/src/Stormancer.Plugins/Galaxy/Stormancer.Server.Plugins.Galaxy/Stormancer.Server.Plugins.Galaxy.csproj +++ b/src/Stormancer.Plugins/Galaxy/Stormancer.Server.Plugins.Galaxy/Stormancer.Server.Plugins.Galaxy.csproj @@ -45,6 +45,5 @@ - diff --git a/src/Stormancer.Plugins/GameFinder/Stormancer.Server.Plugins.GameFinder/Stormancer.Server.Plugins.GameFinder.csproj b/src/Stormancer.Plugins/GameFinder/Stormancer.Server.Plugins.GameFinder/Stormancer.Server.Plugins.GameFinder.csproj index c33abfb4..efc5b3c6 100644 --- a/src/Stormancer.Plugins/GameFinder/Stormancer.Server.Plugins.GameFinder/Stormancer.Server.Plugins.GameFinder.csproj +++ b/src/Stormancer.Plugins/GameFinder/Stormancer.Server.Plugins.GameFinder/Stormancer.Server.Plugins.GameFinder.csproj @@ -53,7 +53,6 @@ - diff --git a/src/Stormancer.Plugins/GameFinder/cpp/GameFinder.hpp b/src/Stormancer.Plugins/GameFinder/cpp/GameFinder.hpp index aac9fbbd..c36fc648 100644 --- a/src/Stormancer.Plugins/GameFinder/cpp/GameFinder.hpp +++ b/src/Stormancer.Plugins/GameFinder/cpp/GameFinder.hpp @@ -440,14 +440,6 @@ namespace Stormancer struct GameFinderContainer { - ~GameFinderContainer() - { - if (connectionStateChangedSubscription.is_subscribed()) - { - connectionStateChangedSubscription.unsubscribe(); - } - } - //Keep game finder scene alive std::shared_ptr scene; std::shared_ptr service() @@ -458,7 +450,7 @@ namespace Stormancer Subscription gameFoundSubscription; Subscription gameFinderStateUpdatedSubscription; Subscription findGamefailedSubscription; - rxcpp::subscription connectionStateChangedSubscription; + Subscription connectionStateChangedSubscription; }; class GameFinder_Impl : public std::enable_shared_from_this, public GameFinderApi @@ -615,7 +607,7 @@ namespace Stormancer { auto container = std::make_shared(); container->scene = task.get(); - container->connectionStateChangedSubscription = container->scene->getConnectionStateChangedObservable().subscribe([wThat, gameFinderName](ConnectionState s) + container->connectionStateChangedSubscription = container->scene->subscribeConnectionStateChanged([wThat, gameFinderName](ConnectionState s) { if (auto that = wThat.lock()) { diff --git a/src/Stormancer.Plugins/GameSession/Stormancer.Server.Plugins.GameSession/Stormancer.Server.Plugins.GameSession.csproj b/src/Stormancer.Plugins/GameSession/Stormancer.Server.Plugins.GameSession/Stormancer.Server.Plugins.GameSession.csproj index f8864397..29ecaf56 100644 --- a/src/Stormancer.Plugins/GameSession/Stormancer.Server.Plugins.GameSession/Stormancer.Server.Plugins.GameSession.csproj +++ b/src/Stormancer.Plugins/GameSession/Stormancer.Server.Plugins.GameSession/Stormancer.Server.Plugins.GameSession.csproj @@ -67,7 +67,6 @@ - diff --git a/src/Stormancer.Plugins/GameVersion/Stormancer.Server.Plugins.GameVersion/Stormancer.Server.Plugins.GameVersion.csproj b/src/Stormancer.Plugins/GameVersion/Stormancer.Server.Plugins.GameVersion/Stormancer.Server.Plugins.GameVersion.csproj index 7c133ac5..6bbe106b 100644 --- a/src/Stormancer.Plugins/GameVersion/Stormancer.Server.Plugins.GameVersion/Stormancer.Server.Plugins.GameVersion.csproj +++ b/src/Stormancer.Plugins/GameVersion/Stormancer.Server.Plugins.GameVersion/Stormancer.Server.Plugins.GameVersion.csproj @@ -43,8 +43,6 @@ - - diff --git a/src/Stormancer.Plugins/Leaderboards/Stormancer.Server.Plugins.Leaderboards/Stormancer.Server.Plugins.Leaderboards.csproj b/src/Stormancer.Plugins/Leaderboards/Stormancer.Server.Plugins.Leaderboards/Stormancer.Server.Plugins.Leaderboards.csproj index c69510bd..28208f54 100644 --- a/src/Stormancer.Plugins/Leaderboards/Stormancer.Server.Plugins.Leaderboards/Stormancer.Server.Plugins.Leaderboards.csproj +++ b/src/Stormancer.Plugins/Leaderboards/Stormancer.Server.Plugins.Leaderboards/Stormancer.Server.Plugins.Leaderboards.csproj @@ -47,6 +47,5 @@ - diff --git a/src/Stormancer.Plugins/Notification/Stormancer.Server.Plugins.Notification/Stormancer.Server.Plugins.Notification.csproj b/src/Stormancer.Plugins/Notification/Stormancer.Server.Plugins.Notification/Stormancer.Server.Plugins.Notification.csproj index 2753849a..9bf76fdc 100644 --- a/src/Stormancer.Plugins/Notification/Stormancer.Server.Plugins.Notification/Stormancer.Server.Plugins.Notification.csproj +++ b/src/Stormancer.Plugins/Notification/Stormancer.Server.Plugins.Notification/Stormancer.Server.Plugins.Notification.csproj @@ -42,6 +42,5 @@ - diff --git a/src/Stormancer.Plugins/Party/Stormancer.Server.Plugins.Party/Stormancer.Server.Plugins.Party.csproj b/src/Stormancer.Plugins/Party/Stormancer.Server.Plugins.Party/Stormancer.Server.Plugins.Party.csproj index 1934b8e2..b0cd3943 100644 --- a/src/Stormancer.Plugins/Party/Stormancer.Server.Plugins.Party/Stormancer.Server.Plugins.Party.csproj +++ b/src/Stormancer.Plugins/Party/Stormancer.Server.Plugins.Party/Stormancer.Server.Plugins.Party.csproj @@ -15,9 +15,11 @@ Readme.md true + $(Version)-pre + all @@ -39,8 +41,6 @@ - - @@ -57,7 +57,6 @@ - - + diff --git a/src/Stormancer.Plugins/Party/cpp/Party.hpp b/src/Stormancer.Plugins/Party/cpp/Party.hpp index 46092438..f671477e 100644 --- a/src/Stormancer.Plugins/Party/cpp/Party.hpp +++ b/src/Stormancer.Plugins/Party/cpp/Party.hpp @@ -1945,6 +1945,7 @@ namespace Stormancer Event UpdatedPartySettings; Event> UpdatedInviteList; Event OnGameFinderFailed; + Subscription connectionStateChangedSubscription; std::vector members() const { @@ -2042,7 +2043,7 @@ namespace Stormancer } }); - scene->getConnectionStateChangedObservable().subscribe([wThat](ConnectionState state) { + connectionStateChangedSubscription = scene->subscribeConnectionStateChanged([wThat](ConnectionState state) { if (auto that = wThat.lock()) { try @@ -2054,6 +2055,8 @@ namespace Stormancer else if (state == ConnectionState::Disconnected) { that->failInit(state.reason); + //Unsubscribe + that->connectionStateChangedSubscription = nullptr; that->_gameFinder->disconnectFromGameFinder(that->_state.settings.gameFinderName) .then([](pplx::task t) { @@ -3279,7 +3282,7 @@ namespace Stormancer else { return false; - } + } } @@ -4446,8 +4449,8 @@ namespace Stormancer }); if (it != _invitationsNew.end()) { - _invitationsNew.erase(it); - } + _invitationsNew.erase(it); + } } pplx::task joinPartyBySceneId(const std::string& sceneId, const std::vector& userData, const std::unordered_map& userMetadata = {}, pplx::cancellation_token ct = pplx::cancellation_token::none()) override diff --git a/src/Stormancer.Plugins/Profile/Stormancer.Server.Plugins.Profile/Stormancer.Server.Plugins.Profile.csproj b/src/Stormancer.Plugins/Profile/Stormancer.Server.Plugins.Profile/Stormancer.Server.Plugins.Profile.csproj index 8a0e8a8c..3f052ed8 100644 --- a/src/Stormancer.Plugins/Profile/Stormancer.Server.Plugins.Profile/Stormancer.Server.Plugins.Profile.csproj +++ b/src/Stormancer.Plugins/Profile/Stormancer.Server.Plugins.Profile/Stormancer.Server.Plugins.Profile.csproj @@ -37,13 +37,14 @@ + + - - + diff --git a/src/Stormancer.Plugins/Replication/Stormancer.Server.Plugins.Replication/Stormancer.Server.Plugins.Replication.csproj b/src/Stormancer.Plugins/Replication/Stormancer.Server.Plugins.Replication/Stormancer.Server.Plugins.Replication.csproj index 0c73ff21..722d22da 100644 --- a/src/Stormancer.Plugins/Replication/Stormancer.Server.Plugins.Replication/Stormancer.Server.Plugins.Replication.csproj +++ b/src/Stormancer.Plugins/Replication/Stormancer.Server.Plugins.Replication/Stormancer.Server.Plugins.Replication.csproj @@ -14,9 +14,11 @@ Provides server services required for object replication. true + $(Version)-pre + all @@ -28,6 +30,7 @@ icon.png + @@ -41,9 +44,8 @@ - - + diff --git a/src/Stormancer.Plugins/SocketApi/Stormancer.Server.Plugins.SocketApi/Stormancer.Server.Plugins.SocketApi.csproj b/src/Stormancer.Plugins/SocketApi/Stormancer.Server.Plugins.SocketApi/Stormancer.Server.Plugins.SocketApi.csproj index 01e8485b..371e0566 100644 --- a/src/Stormancer.Plugins/SocketApi/Stormancer.Server.Plugins.SocketApi/Stormancer.Server.Plugins.SocketApi.csproj +++ b/src/Stormancer.Plugins/SocketApi/Stormancer.Server.Plugins.SocketApi/Stormancer.Server.Plugins.SocketApi.csproj @@ -13,6 +13,7 @@ Provides a API similar to sockets for P2P communication in a scene. true + $(Version)-pre @@ -21,7 +22,6 @@ icon.png - @@ -44,11 +44,8 @@ - - - diff --git a/src/Stormancer.Plugins/Spectate/Stormancer.Server.Plugins.Spectate/Stormancer.Server.Plugins.Spectate.csproj b/src/Stormancer.Plugins/Spectate/Stormancer.Server.Plugins.Spectate/Stormancer.Server.Plugins.Spectate.csproj index a0dd57c1..c244f0da 100644 --- a/src/Stormancer.Plugins/Spectate/Stormancer.Server.Plugins.Spectate/Stormancer.Server.Plugins.Spectate.csproj +++ b/src/Stormancer.Plugins/Spectate/Stormancer.Server.Plugins.Spectate/Stormancer.Server.Plugins.Spectate.csproj @@ -14,6 +14,7 @@ Provides game data streaming APIs for replay or realtime spectate. true + $(Version)-pre @@ -22,7 +23,6 @@ icon.png - @@ -47,7 +47,6 @@ - diff --git a/src/Stormancer.Plugins/Steam/Stormancer.Server.Plugins.Steam/Stormancer.Server.Plugins.Steam.csproj b/src/Stormancer.Plugins/Steam/Stormancer.Server.Plugins.Steam/Stormancer.Server.Plugins.Steam.csproj index 53116386..e28d5fcf 100644 --- a/src/Stormancer.Plugins/Steam/Stormancer.Server.Plugins.Steam/Stormancer.Server.Plugins.Steam.csproj +++ b/src/Stormancer.Plugins/Steam/Stormancer.Server.Plugins.Steam/Stormancer.Server.Plugins.Steam.csproj @@ -15,6 +15,7 @@ true README.md + $(Version)-pre @@ -52,7 +53,6 @@ - diff --git a/src/Stormancer.Plugins/Users/Stormancer.Abstractions.Server.Users/Stormancer.Abstractions.Server.Users.csproj b/src/Stormancer.Plugins/Users/Stormancer.Abstractions.Server.Users/Stormancer.Abstractions.Server.Users.csproj index 76c37c83..a8898f3c 100644 --- a/src/Stormancer.Plugins/Users/Stormancer.Abstractions.Server.Users/Stormancer.Abstractions.Server.Users.csproj +++ b/src/Stormancer.Plugins/Users/Stormancer.Abstractions.Server.Users/Stormancer.Abstractions.Server.Users.csproj @@ -42,9 +42,9 @@ - + diff --git a/src/Stormancer.Plugins/Users/Stormancer.Server.Plugins.Users/Stormancer.Server.Plugins.Users.csproj b/src/Stormancer.Plugins/Users/Stormancer.Server.Plugins.Users/Stormancer.Server.Plugins.Users.csproj index 9d101473..bdba4e82 100644 --- a/src/Stormancer.Plugins/Users/Stormancer.Server.Plugins.Users/Stormancer.Server.Plugins.Users.csproj +++ b/src/Stormancer.Plugins/Users/Stormancer.Server.Plugins.Users/Stormancer.Server.Plugins.Users.csproj @@ -72,7 +72,6 @@ - diff --git a/src/Stormancer.Plugins/Users/cpp/ClientAPI.hpp b/src/Stormancer.Plugins/Users/cpp/ClientAPI.hpp index a6d2eb33..b5c06254 100644 --- a/src/Stormancer.Plugins/Users/cpp/ClientAPI.hpp +++ b/src/Stormancer.Plugins/Users/cpp/ClientAPI.hpp @@ -52,7 +52,7 @@ namespace Stormancer } std::weak_ptr wScene = scene; - that->_connectionChangedSub = scene->getConnectionStateChangedObservable().subscribe([wThat, wScene, cleanup](ConnectionState state) + that->_connectionChangedSub = scene->subscribeConnectionStateChanged([wThat, wScene, cleanup](ConnectionState state) { auto that = wThat.lock(); if (!that) @@ -63,10 +63,7 @@ namespace Stormancer if (state == ConnectionState::Disconnected || state == ConnectionState::Disconnecting) { cleanup(that, wScene.lock()); - if (that->_connectionChangedSub.is_subscribed()) - { - that->_connectionChangedSub.unsubscribe(); - } + that->_connectionChangedSub = nullptr; that->_scene = nullptr; that->_serviceTask = nullptr; } @@ -74,11 +71,7 @@ namespace Stormancer if (scene->getCurrentConnectionState() == ConnectionState::Disconnected || scene->getCurrentConnectionState() == ConnectionState::Disconnecting) { cleanup(that, scene); - - if (that->_connectionChangedSub.is_subscribed()) - { - that->_connectionChangedSub.unsubscribe(); - } + that->_connectionChangedSub = nullptr; that->_scene = nullptr; that->_serviceTask = nullptr; } @@ -99,10 +92,7 @@ namespace Stormancer } cleanup(that, nullptr); - if (that->_connectionChangedSub.is_subscribed()) - { - that->_connectionChangedSub.unsubscribe(); - } + that->_connectionChangedSub = nullptr; that->_scene = nullptr; that->_serviceTask = nullptr; throw; @@ -148,6 +138,6 @@ namespace Stormancer std::shared_ptr>> _serviceTask; - rxcpp::subscription _connectionChangedSub; + Subscription _connectionChangedSub; }; } diff --git a/src/Stormancer.Plugins/Users/cpp/Users.hpp b/src/Stormancer.Plugins/Users/cpp/Users.hpp index 7590df35..906437a2 100644 --- a/src/Stormancer.Plugins/Users/cpp/Users.hpp +++ b/src/Stormancer.Plugins/Users/cpp/Users.hpp @@ -405,7 +405,6 @@ namespace Stormancer ~UsersApi() { - _connectionSubscription.unsubscribe(); } void setAutoReconnect(bool autoReconnect) @@ -1090,7 +1089,7 @@ namespace Stormancer auto that = wThat.lock(); if (that) { - that->_connectionSubscription = scene->getConnectionStateChangedObservable().subscribe([wThat](ConnectionState state) + that->_connectionSubscription = scene->subscribeConnectionStateChanged([wThat](ConnectionState state) { auto that = wThat.lock(); if (that) @@ -1354,7 +1353,7 @@ namespace Stormancer std::weak_ptr _wClient; GameConnectionState _currentConnectionState; std::string _lastError; - rxcpp::composite_subscription _connectionSubscription; + Subscription _connectionSubscription; ILogger_ptr _logger; LoginCredentialsResult _lastLoginCredentialsResult; std::mutex _loginMutex; diff --git a/tests/Stormancer-Plugins-Tests-cpp/TestBrowseParties.cpp b/tests/Stormancer-Plugins-Tests-cpp/TestBrowseParties.cpp index d89ff427..18cbd5a8 100644 --- a/tests/Stormancer-Plugins-Tests-cpp/TestBrowseParties.cpp +++ b/tests/Stormancer-Plugins-Tests-cpp/TestBrowseParties.cpp @@ -10,7 +10,9 @@ #include "stormancer/IClientFactory.h" #include "stormancer/Logger/VisualStudioLogger.h" -static constexpr const char* ServerEndpoint = "http://localhost:8080";//"http://gc3.stormancer.com"; +//static constexpr const char* ServerEndpoint = "http://localhost:8080"; +//static constexpr const char* ServerEndpoint = "http://gc3.stormancer.com"; +static constexpr const char* ServerEndpoint = "http://stormancer-1.stormancer.com:8081"; constexpr char* Account = "tests"; constexpr char* Application = "test-app"; @@ -18,6 +20,7 @@ static void log(std::shared_ptr client, Stormancer::LogLeve { client->dependencyResolver().resolve()->log(level, "gameplay.test-join-game", msg); } + struct GameCustomParameters { bool test; @@ -34,7 +37,8 @@ static pplx::task BrowseParty(int id) //The get credentialsCallback provided is automatically called by the library whenever authentication is required (during connection/reconnection) // It returns a task to enable you to return credential asynchronously. // please note that if platform plugins are installed, they automatically provide credentials. - users->getCredentialsCallback = []() { + users->getCredentialsCallback = []() + { Stormancer::Users::AuthParameters authParameters; authParameters.type = "ephemeral"; return pplx::task_from_result(authParameters); @@ -42,27 +46,35 @@ static pplx::task BrowseParty(int id) auto party = client->dependencyResolver().resolve(); - return users->login().then([party]() {return party->searchParties("{\"bool\":{\"must\":[{\"match\":{\"field\":\"state_full\",\"value\":false}},{\"match\":{\"field\":\"state_private\",\"value\":false}}]}}", 0, 10, pplx::cancellation_token::none()); }) - .then([client,party](Stormancer::Party::SearchResult t) { - if (t.total != 1) - { - return pplx::task_from_result(false); - } - return party->joinPartyBySceneId(t.hits.front().id, {}).then([]() {return true; }); - }) - .then([client](pplx::task t) - { - try - { - - return t.get(); - } - catch (std::exception& ex) - { - log(client, Stormancer::LogLevel::Error, ex.what()); - return false; - } - }); + return users->login() + .then([party]() + { + return party->searchParties("{\"bool\":{\"must\":[{\"match\":{\"field\":\"state_full\",\"value\":false}},{\"match\":{\"field\":\"state_private\",\"value\":false}}]}}", 0, 10, pplx::cancellation_token::none()); + }) + .then([client, party](Stormancer::Party::SearchResult t) + { + if (t.total != 1) + { + return pplx::task_from_result(false); + } + return party->joinPartyBySceneId(t.hits.front().id, {}) + .then([]() + { + return true; + }); + }) + .then([client](pplx::task t) + { + try + { + return t.get(); + } + catch (std::exception& ex) + { + log(client, Stormancer::LogLevel::Error, ex.what()); + return false; + } + }); } static pplx::task CreateParty(int id) @@ -75,81 +87,70 @@ static pplx::task CreateParty(int id) //The get credentialsCallback provided is automatically called by the library whenever authentication is required (during connection/reconnection) // It returns a task to enable you to return credential asynchronously. // please note that if platform plugins are installed, they automatically provide credentials. - users->getCredentialsCallback = []() { + users->getCredentialsCallback = []() + { Stormancer::Users::AuthParameters authParameters; authParameters.type = "ephemeral"; return pplx::task_from_result(authParameters); }; - auto party = client->dependencyResolver().resolve(); - - Stormancer::Party::PartyCreationOptions request; request.GameFinderName = "joingame-test"; //Name of the matchmaking, defined in Stormancer.Server.TestApp/TestPlugin.cs. //> host.AddGamefinder("matchmaking", "matchmaking"); - return users->login().then([party,request]() {return party->createPartyIfNotJoined(request); }) - .then([client,party,id]() - { - auto settings = party->getPartySettings(); - settings.indexedDocument = "{\"state_full\":false,\"state_private\":false}"; - party->updatePartySettings(settings); - }) - .then([client](pplx::task t) - { - //catch errors - try - { - - return t.get(); - } - catch (std::exception& ex) - { - log(client, Stormancer::LogLevel::Error, ex.what()); - } - }); - - + return users->login().then([party, request]() {return party->createPartyIfNotJoined(request); }) + .then([client, party, id]() + { + auto settings = party->getPartySettings(); + settings.indexedDocument = "{\"state_full\":false,\"state_private\":false}"; + party->updatePartySettings(settings); + }) + .then([client](pplx::task t) + { + //catch errors + try + { + return t.get(); + } + catch (std::exception& ex) + { + log(client, Stormancer::LogLevel::Error, ex.what()); + } + }); } -TEST(Metagame, TestBrowseParty) { - +TEST(Metagame, TestBrowseParty) +{ //Create an action dispatcher to dispatch callbacks and continuation in the thread running the method. auto dispatcher = std::make_shared(); //Create a configurator used for all clients. - Stormancer::IClientFactory::SetDefaultConfigurator([dispatcher](size_t id) { - - //Create a configuration that connects to the test application. - auto config = Stormancer::Configuration::create(std::string(ServerEndpoint), std::string(Account), std::string(Application)); - - //Log in VS output window. - config->logger = std::make_shared(); - + Stormancer::IClientFactory::SetDefaultConfigurator([dispatcher](size_t id) + { + //Create a configuration that connects to the test application. + auto config = Stormancer::Configuration::create(std::string(ServerEndpoint), std::string(Account), std::string(Application)); - //Add plugins required by the test. - config->addPlugin(new Stormancer::Users::UsersPlugin()); - config->addPlugin(new Stormancer::GameFinder::GameFinderPlugin()); - config->addPlugin(new Stormancer::Party::PartyPlugin()); - config->encryptionEnabled = true; + //Log in VS output window. + config->logger = std::make_shared(); + //Add plugins required by the test. + config->addPlugin(new Stormancer::Users::UsersPlugin()); + config->addPlugin(new Stormancer::GameFinder::GameFinderPlugin()); + config->addPlugin(new Stormancer::Party::PartyPlugin()); + config->encryptionEnabled = true; - //Use the dispatcher we created earlier to ensure all callbacks are run on the test main thread. - config->actionDispatcher = dispatcher; - return config; + //Use the dispatcher we created earlier to ensure all callbacks are run on the test main thread. + config->actionDispatcher = dispatcher; + return config; }); - - - - - auto t = CreateParty(0).then([]() - { - return BrowseParty(1); - }); + auto t = CreateParty(0).then([]() + { + return BrowseParty(1); + }); //loop until test is completed and run library events. while (!t.is_done()) @@ -158,14 +159,10 @@ TEST(Metagame, TestBrowseParty) { dispatcher->update(std::chrono::milliseconds(5)); std::this_thread::sleep_for(std::chrono::milliseconds(10)); } - + EXPECT_TRUE(t.get()); //We are connected to the game session, we can test the socket API. - - Stormancer::IClientFactory::ReleaseClient(0); Stormancer::IClientFactory::ReleaseClient(1); - - } \ No newline at end of file diff --git a/tests/Stormancer-Plugins-Tests-cpp/TestDevServer.cpp b/tests/Stormancer-Plugins-Tests-cpp/TestDevServer.cpp index 94c7c88b..a31f3cb8 100644 --- a/tests/Stormancer-Plugins-Tests-cpp/TestDevServer.cpp +++ b/tests/Stormancer-Plugins-Tests-cpp/TestDevServer.cpp @@ -13,7 +13,9 @@ #include "stormancer/IClientFactory.h" #include "stormancer/Logger/VisualStudioLogger.h" -static constexpr const char* ServerEndpoint = "http://localhost";//"http://gc3.stormancer.com"; +//static constexpr const char* ServerEndpoint = "http://localhost:8080"; +//static constexpr const char* ServerEndpoint = "http://gc3.stormancer.com"; +static constexpr const char* ServerEndpoint = "http://stormancer-1.stormancer.com:8081"; constexpr char* Account = "tests"; constexpr char* Application = "test-app"; @@ -21,48 +23,59 @@ static void log(std::shared_ptr client, Stormancer::LogLeve { client->dependencyResolver().resolve()->log(level, "gameplay.test-devserver", msg); } + struct GameCustomParameters { bool test; MSGPACK_DEFINE_MAP(test); }; + static pplx::task StartServerImpl(int id) { auto client = Stormancer::IClientFactory::GetClient(id); auto pool = client->dependencyResolver().resolve(); - - pool->setGetStatusCallback([]() { return Stormancer::ServerPools::Status::Ready; }); - return pool->waitGameSession().then([client](Stormancer::ServerPools::GameSessionStartupParameters p) - { - auto gs = client->dependencyResolver().resolve < Stormancer::GameSessions::GameSession>(); - return gs->connectToGameSession(p.gameSessionConnectionToken); - - }) - .then([client](pplx::task t) - { - auto gs = client->dependencyResolver().resolve < Stormancer::GameSessions::GameSession>(); - return gs->setPlayerReady(); - }) - .then([client](pplx::task t) + auto users = client->dependencyResolver().resolve(); + + pool->setGetStatusCallback([]() { - try + return Stormancer::ServerPools::Status::Ready; + }); + + return users->login() + .then([pool]() { - t.get(); - return true; - } - catch (std::exception& ex) + return pool->waitGameSession(); + }) + .then([client](Stormancer::ServerPools::GameSessionStartupParameters p) { - log(client, Stormancer::LogLevel::Error, ex.what()); - return false; - } + auto gs = client->dependencyResolver().resolve < Stormancer::GameSessions::GameSession>(); + return gs->connectToGameSession(p.gameSessionConnectionToken); - }); + }) + .then([client](pplx::task t) + { + auto gs = client->dependencyResolver().resolve < Stormancer::GameSessions::GameSession>(); + return gs->setPlayerReady(); + }) + .then([client](pplx::task t) + { + try + { + t.get(); + return true; + } + catch (std::exception& ex) + { + log(client, Stormancer::LogLevel::Error, ex.what()); + return false; + } + + }); } + static pplx::task JoinGameImpl(int id) { - - auto client = Stormancer::IClientFactory::GetClient(id); auto users = client->dependencyResolver().resolve(); @@ -71,7 +84,8 @@ static pplx::task JoinGameImpl(int id) //The get credentialsCallback provided is automatically called by the library whenever authentication is required (during connection/reconnection) // It returns a task to enable you to return credential asynchronously. // please note that if platform plugins are installed, they automatically provide credentials. - users->getCredentialsCallback = []() { + users->getCredentialsCallback = []() + { Stormancer::Users::AuthParameters authParameters; authParameters.type = "ephemeral"; return pplx::task_from_result(authParameters); @@ -83,14 +97,16 @@ static pplx::task JoinGameImpl(int id) //Create a task that will complete the next time a game is found. auto gameFoundTask = gameFinder->waitGameFound(); - - Stormancer::Party::PartyCreationOptions request; request.GameFinderName = "server-test"; //Name of the matchmaking, defined in Stormancer.Server.TestApp/TestPlugin.cs. //> host.AddGamefinder("matchmaking", "matchmaking"); - return party->createPartyIfNotJoined(request) + return users->login() + .then([party, request]() + { + return party->createPartyIfNotJoined(request); + }) .then([client]() { log(client, Stormancer::LogLevel::Debug, "connected to party"); @@ -100,20 +116,20 @@ static pplx::task JoinGameImpl(int id) //Matchmaking starts when all players in the party are ready. return party->updatePlayerStatus(Stormancer::Party::PartyUserStatus::Ready); }) - .then([gameFoundTask]() - { - //Wait game found. - return gameFoundTask; - }) + .then([gameFoundTask]() + { + //Wait game found. + return gameFoundTask; + }) .then([client](Stormancer::GameFinder::GameFoundEvent evt) { auto gameSessions = client->dependencyResolver().resolve(); return gameSessions->connectToGameSession(evt.data.connectionToken); }) - //Errors flow through continuations that take TResult instead of task as argument. - //We want to handle errors in the last continuation, so this one takes task. Inside we get the result of the task by calling task.get() - //inside a try clause. If an error occured .get() will throw. We return false (error). If it doesn't throw, everything succeeded. + //Errors flow through continuations that take TResult instead of task as argument. + //We want to handle errors in the last continuation, so this one takes task. Inside we get the result of the task by calling task.get() + //inside a try clause. If an error occured .get() will throw. We return false (error). If it doesn't throw, everything succeeded. .then([id, client](Stormancer::GameSessions::GameSessionConnectionParameters params) { @@ -177,7 +193,7 @@ TEST(Gameplay, TestDevServer) { config->addPlugin(new Stormancer::GameFinder::GameFinderPlugin()); config->addPlugin(new Stormancer::GameSessions::GameSessionsPlugin()); } - else if(id == 1) // Server + else if (id == 1) // Server { config->addPlugin(new Stormancer::Users::UsersPlugin()); config->addPlugin(new Stormancer::ServerPools::ServerPoolsPlugin()); diff --git a/tests/Stormancer-Plugins-Tests-cpp/TestDisableGameSessionDirectConnection.cpp b/tests/Stormancer-Plugins-Tests-cpp/TestDisableGameSessionDirectConnection.cpp index a015c95d..8594f989 100644 --- a/tests/Stormancer-Plugins-Tests-cpp/TestDisableGameSessionDirectConnection.cpp +++ b/tests/Stormancer-Plugins-Tests-cpp/TestDisableGameSessionDirectConnection.cpp @@ -11,11 +11,12 @@ #include "stormancer/IClientFactory.h" #include "stormancer/Logger/VisualStudioLogger.h" -constexpr char* ServerEndpoint = "http://localhost";//"http://gc3.stormancer.com"; +//static constexpr const char* ServerEndpoint = "http://localhost:8080"; +//static constexpr const char* ServerEndpoint = "http://gc3.stormancer.com"; +static constexpr const char* ServerEndpoint = "http://stormancer-1.stormancer.com:8081"; constexpr char* Account = "tests"; constexpr char* Application = "test-app"; - static void log(std::shared_ptr client, Stormancer::LogLevel level, std::string msg) { client->dependencyResolver().resolve()->log(level, "gameplay.disableGameSessionDirectConnection", msg); @@ -23,8 +24,6 @@ static void log(std::shared_ptr client, Stormancer::LogLeve static pplx::task JoinGameImpl(int id) { - - auto client = Stormancer::IClientFactory::GetClient(id); auto users = client->dependencyResolver().resolve(); @@ -33,7 +32,8 @@ static pplx::task JoinGameImpl(int id) //The get credentialsCallback provided is automatically called by the library whenever authentication is required (during connection/reconnection) // It returns a task to enable you to return credential asynchronously. // please note that if platform plugins are installed, they automatically provide credentials. - users->getCredentialsCallback = []() { + users->getCredentialsCallback = []() + { Stormancer::Users::AuthParameters authParameters; authParameters.type = "ephemeral"; return pplx::task_from_result(authParameters); @@ -45,14 +45,16 @@ static pplx::task JoinGameImpl(int id) //Create a task that will complete the next time a game is found. auto gameFoundTask = gameFinder->waitGameFound(); + return users->login() + .then([party]() + { + Stormancer::Party::PartyCreationOptions request; + request.GameFinderName = "disable-direct-connection-test"; + //Name of the matchmaking, defined in Stormancer.Server.TestApp/TestPlugin.cs. + //> host.AddGamefinder("matchmaking", "matchmaking"); - - Stormancer::Party::PartyCreationOptions request; - request.GameFinderName = "disable-direct-connection-test"; - //Name of the matchmaking, defined in Stormancer.Server.TestApp/TestPlugin.cs. - //> host.AddGamefinder("matchmaking", "matchmaking"); - - return party->createPartyIfNotJoined(request) + return party->createPartyIfNotJoined(request); + }) .then([client]() { log(client, Stormancer::LogLevel::Debug, "connected to party"); @@ -62,24 +64,22 @@ static pplx::task JoinGameImpl(int id) //Matchmaking starts when all players in the party are ready. return party->updatePlayerStatus(Stormancer::Party::PartyUserStatus::Ready); }) - .then([gameFoundTask]() - { - //Wait game found. - return gameFoundTask; - }) + .then([gameFoundTask]() + { + //Wait game found. + return gameFoundTask; + }) .then([client](Stormancer::GameFinder::GameFoundEvent evt) { auto gameSessions = client->dependencyResolver().resolve(); - return gameSessions->connectToGameSession(evt.data.connectionToken,"",false); + return gameSessions->connectToGameSession(evt.data.connectionToken, "", false); }) - //Errors flow through continuations that take TResult instead of task as argument. - //We want to handle errors in the last continuation, so this one takes task. Inside we get the result of the task by calling task.get() - //inside a try clause. If an error occured .get() will throw. We return false (error). If it doesn't throw, everything succeeded. + //Errors flow through continuations that take TResult instead of task as argument. + //We want to handle errors in the last continuation, so this one takes task. Inside we get the result of the task by calling task.get() + //inside a try clause. If an error occured .get() will throw. We return false (error). If it doesn't throw, everything succeeded. .then([id, client](Stormancer::GameSessions::GameSessionConnectionParameters params) { - - //P2P connection established. //In the host, this continuation is executed immediatly. //In clients this continuation is executed only if the host called gameSessions->setPlayerReady() (see below) @@ -101,51 +101,48 @@ static pplx::task JoinGameImpl(int id) auto gameSessions = client->dependencyResolver().resolve(); return gameSessions->setPlayerReady(); - }).then([client](pplx::task t) + }) + .then([client](pplx::task t) + { + //catch errors + try { - //catch errors - try - { - t.get(); - return true; - } - catch (std::exception& ex) - { - log(client, Stormancer::LogLevel::Error,ex.what()); - return false; - } - }); - - + t.get(); + return true; + } + catch (std::exception& ex) + { + log(client, Stormancer::LogLevel::Error, ex.what()); + return false; + } + }); } -TEST(Gameplay, TestDisableGameSessionDirectConnection) { - +TEST(Gameplay, TestDisableGameSessionDirectConnection) +{ //Create an action dispatcher to dispatch callbacks and continuation in the thread running the method. auto dispatcher = std::make_shared(); //Create a configurator used for all clients. - Stormancer::IClientFactory::SetDefaultConfigurator([dispatcher](size_t id) { - - //Create a configuration that connects to the test application. - auto config = Stormancer::Configuration::create(std::string(ServerEndpoint), std::string(Account), std::string(Application)); - - //Log in VS output window. - config->logger = std::make_shared(); - - //Add plugins required by the test. - config->addPlugin(new Stormancer::Users::UsersPlugin()); - config->addPlugin(new Stormancer::Party::PartyPlugin()); - config->addPlugin(new Stormancer::GameFinder::GameFinderPlugin()); - config->addPlugin(new Stormancer::GameSessions::GameSessionsPlugin()); - - //Use the dispatcher we created earlier to ensure all callbacks are run on the test main thread. - config->actionDispatcher = dispatcher; - return config; + Stormancer::IClientFactory::SetDefaultConfigurator([dispatcher](size_t id) + { + //Create a configuration that connects to the test application. + auto config = Stormancer::Configuration::create(std::string(ServerEndpoint), std::string(Account), std::string(Application)); + + //Log in VS output window. + config->logger = std::make_shared(); + + //Add plugins required by the test. + config->addPlugin(new Stormancer::Users::UsersPlugin()); + config->addPlugin(new Stormancer::Party::PartyPlugin()); + config->addPlugin(new Stormancer::GameFinder::GameFinderPlugin()); + config->addPlugin(new Stormancer::GameSessions::GameSessionsPlugin()); + + //Use the dispatcher we created earlier to ensure all callbacks are run on the test main thread. + config->actionDispatcher = dispatcher; + return config; }); - - std::vector> tasks; tasks.push_back(JoinGameImpl(0)); tasks.push_back(JoinGameImpl(1)); @@ -158,17 +155,13 @@ TEST(Gameplay, TestDisableGameSessionDirectConnection) { dispatcher->update(std::chrono::milliseconds(5)); std::this_thread::sleep_for(std::chrono::milliseconds(10)); } + for (auto t : tasks) { EXPECT_TRUE(t.get()); } //We are connected to the game session, we can test the socket API. - - - Stormancer::IClientFactory::ReleaseClient(0); Stormancer::IClientFactory::ReleaseClient(1); - - -} \ No newline at end of file +} diff --git a/tests/Stormancer-Plugins-Tests-cpp/TestFriendsBlock.cpp b/tests/Stormancer-Plugins-Tests-cpp/TestFriendsBlock.cpp index 021831df..29f5e884 100644 --- a/tests/Stormancer-Plugins-Tests-cpp/TestFriendsBlock.cpp +++ b/tests/Stormancer-Plugins-Tests-cpp/TestFriendsBlock.cpp @@ -9,7 +9,9 @@ #include "stormancer/IClientFactory.h" #include "stormancer/Logger/VisualStudioLogger.h" -static constexpr const char* ServerEndpoint = "http://localhost:80";//"http://gc3.stormancer.com"; +//static constexpr const char* ServerEndpoint = "http://localhost:8080"; +//static constexpr const char* ServerEndpoint = "http://gc3.stormancer.com"; +static constexpr const char* ServerEndpoint = "http://stormancer-1.stormancer.com:8081"; constexpr char* Account = "tests"; constexpr char* Application = "test-app"; diff --git a/tests/Stormancer-Plugins-Tests-cpp/TestParty.cpp b/tests/Stormancer-Plugins-Tests-cpp/TestParty.cpp index 60ae5539..fff4fc42 100644 --- a/tests/Stormancer-Plugins-Tests-cpp/TestParty.cpp +++ b/tests/Stormancer-Plugins-Tests-cpp/TestParty.cpp @@ -12,7 +12,9 @@ #include "stormancer/IClientFactory.h" #include "stormancer/Logger/VisualStudioLogger.h" -static constexpr const char* ServerEndpoint = "http://localhost:8080";//"http://gc3.stormancer.com"; +//static constexpr const char* ServerEndpoint = "http://localhost:8080"; +//static constexpr const char* ServerEndpoint = "http://gc3.stormancer.com"; +static constexpr const char* ServerEndpoint = "http://stormancer-1.stormancer.com:8081"; constexpr char* Account = "tests"; constexpr char* Application = "test-app"; diff --git a/tests/Stormancer-Plugins-Tests-cpp/TestSocketApi.cpp b/tests/Stormancer-Plugins-Tests-cpp/TestSocketApi.cpp index 75ca9919..778b23ce 100644 --- a/tests/Stormancer-Plugins-Tests-cpp/TestSocketApi.cpp +++ b/tests/Stormancer-Plugins-Tests-cpp/TestSocketApi.cpp @@ -6,13 +6,15 @@ #include "party/Party.hpp" #include "gameFinder/GameFinder.hpp" #include "gameSession/Gamesession.hpp" -#include "socket/socket.hpp" +#include "SocketApi/socket.hpp" #include "stormancer/IActionDispatcher.h" #include "stormancer/IClientFactory.h" #include "stormancer/Logger/VisualStudioLogger.h" -constexpr char* ServerEndpoint = "http://localhost";//"http://gc3.stormancer.com"; +//static constexpr const char* ServerEndpoint = "http://localhost:8080"; +//static constexpr const char* ServerEndpoint = "http://gc3.stormancer.com"; +static constexpr const char* ServerEndpoint = "http://stormancer-1.stormancer.com:8081"; constexpr char* Account = "tests"; constexpr char* Application = "test-app"; @@ -64,7 +66,7 @@ static void testSocketServer(std::string sceneId, pplx::cancellation_token cance while (!cancellationToken.is_canceled()) { auto result = socket->receive(sceneId, receiveBuffer, 10); - + if (result.success) { log(client, Stormancer::LogLevel::Info, "server.received: " + std::to_string(std::chrono::high_resolution_clock::now().time_since_epoch().count())); @@ -76,8 +78,6 @@ static void testSocketServer(std::string sceneId, pplx::cancellation_token cance static pplx::task JoinGameImpl(int id) { - - auto client = Stormancer::IClientFactory::GetClient(id); auto users = client->dependencyResolver().resolve(); @@ -86,7 +86,8 @@ static pplx::task JoinGameImpl(int id) //The get credentialsCallback provided is automatically called by the library whenever authentication is required (during connection/reconnection) // It returns a task to enable you to return credential asynchronously. // please note that if platform plugins are installed, they automatically provide credentials. - users->getCredentialsCallback = []() { + users->getCredentialsCallback = []() + { Stormancer::Users::AuthParameters authParameters; authParameters.type = "ephemeral"; return pplx::task_from_result(authParameters); @@ -98,14 +99,16 @@ static pplx::task JoinGameImpl(int id) //Create a task that will complete the next time a game is found. auto gameFoundTask = gameFinder->waitGameFound(); + return users->login() + .then([party]() + { + Stormancer::Party::PartyCreationOptions request; + request.GameFinderName = "replication-test"; + //Name of the matchmaking, defined in Stormancer.Server.TestApp/TestPlugin.cs. + //> host.AddGamefinder("matchmaking", "matchmaking"); - - Stormancer::Party::PartyCreationOptions request; - request.GameFinderName = "replication-test"; - //Name of the matchmaking, defined in Stormancer.Server.TestApp/TestPlugin.cs. - //> host.AddGamefinder("matchmaking", "matchmaking"); - - return party->createPartyIfNotJoined(request) + return party->createPartyIfNotJoined(request); + }) .then([client]() { log(client, Stormancer::LogLevel::Debug, "connected to party"); @@ -115,24 +118,24 @@ static pplx::task JoinGameImpl(int id) //Matchmaking starts when all players in the party are ready. return party->updatePlayerStatus(Stormancer::Party::PartyUserStatus::Ready); }) - .then([gameFoundTask]() - { - //Wait game found. - return gameFoundTask; - }) + .then([gameFoundTask]() + { + //Wait game found. + return gameFoundTask; + }) .then([client](Stormancer::GameFinder::GameFoundEvent evt) { auto gameSessions = client->dependencyResolver().resolve(); return gameSessions->connectToGameSession(evt.data.connectionToken); }) - //Errors flow through continuations that take TResult instead of task as argument. - //We want to handle errors in the last continuation, so this one takes task. Inside we get the result of the task by calling task.get() - //inside a try clause. If an error occured .get() will throw. We return false (error). If it doesn't throw, everything succeeded. + //Errors flow through continuations that take TResult instead of task as argument. + //We want to handle errors in the last continuation, so this one takes task. Inside we get the result of the task by calling task.get() + //inside a try clause. If an error occured .get() will throw. We return false (error). If it doesn't throw, everything succeeded. .then([id, client](Stormancer::GameSessions::GameSessionConnectionParameters params) { - + //P2P connection established. //In the host, this continuation is executed immediatly. //In clients this continuation is executed only if the host called gameSessions->setPlayerReady() (see below) @@ -141,8 +144,8 @@ static pplx::task JoinGameImpl(int id) pplx::create_task([params, client]() { auto gameSessions = client->dependencyResolver().resolve(); testSocketServer(gameSessions->scene()->id(), pplx::cancellation_token::none(), client); - - }); + + }); } else { @@ -154,7 +157,8 @@ static pplx::task JoinGameImpl(int id) auto gameSessions = client->dependencyResolver().resolve(); return gameSessions->setPlayerReady().then([params]() {return params; }); - }).then([client](Stormancer::GameSessions::GameSessionConnectionParameters params) + }) + .then([client](Stormancer::GameSessions::GameSessionConnectionParameters params) { if (!params.isHost) { @@ -168,53 +172,49 @@ static pplx::task JoinGameImpl(int id) return pplx::task_from_result(); } }) - .then([client](pplx::task t) - { - //catch errors - try - { - t.get(); - - return true; - } - catch (std::exception& ex) - { - log(client, Stormancer::LogLevel::Error, ex.what()); - return false; - } - }); - - + .then([client](pplx::task t) + { + //catch errors + try + { + t.get(); + + return true; + } + catch (std::exception& ex) + { + log(client, Stormancer::LogLevel::Error, ex.what()); + return false; + } + }); } -TEST(Gameplay, TestSocketApi) { - +TEST(Gameplay, TestSocketApi) +{ //Create an action dispatcher to dispatch callbacks and continuation in the thread running the method. auto dispatcher = std::make_shared(); //Create a configurator used for all clients. - Stormancer::IClientFactory::SetDefaultConfigurator([dispatcher](size_t id) { - - //Create a configuration that connects to the test application. - auto config = Stormancer::Configuration::create(std::string(ServerEndpoint), std::string(Account), std::string(Application)); - - //Log in VS output window. - config->logger = std::make_shared(); - - //Add plugins required by the test. - config->addPlugin(new Stormancer::Users::UsersPlugin()); - config->addPlugin(new Stormancer::Party::PartyPlugin()); - config->addPlugin(new Stormancer::GameFinder::GameFinderPlugin()); - config->addPlugin(new Stormancer::GameSessions::GameSessionsPlugin()); - config->addPlugin(new Stormancer::Socket::SocketApiPlugin()); - - //Use the dispatcher we created earlier to ensure all callbacks are run on the test main thread. - config->actionDispatcher = dispatcher; - return config; + Stormancer::IClientFactory::SetDefaultConfigurator([dispatcher](size_t id) + { + //Create a configuration that connects to the test application. + auto config = Stormancer::Configuration::create(std::string(ServerEndpoint), std::string(Account), std::string(Application)); + + //Log in VS output window. + config->logger = std::make_shared(); + + //Add plugins required by the test. + config->addPlugin(new Stormancer::Users::UsersPlugin()); + config->addPlugin(new Stormancer::Party::PartyPlugin()); + config->addPlugin(new Stormancer::GameFinder::GameFinderPlugin()); + config->addPlugin(new Stormancer::GameSessions::GameSessionsPlugin()); + config->addPlugin(new Stormancer::Socket::SocketApiPlugin()); + + //Use the dispatcher we created earlier to ensure all callbacks are run on the test main thread. + config->actionDispatcher = dispatcher; + return config; }); - - std::vector> tasks; tasks.push_back(JoinGameImpl(0)); tasks.push_back(JoinGameImpl(1)); @@ -234,10 +234,6 @@ TEST(Gameplay, TestSocketApi) { //We are connected to the game session, we can test the socket API. - - Stormancer::IClientFactory::ReleaseClient(0); Stormancer::IClientFactory::ReleaseClient(1); - - -} \ No newline at end of file +} diff --git a/tests/Stormancer-Plugins-Tests-cpp/TestTunnel.cpp b/tests/Stormancer-Plugins-Tests-cpp/TestTunnel.cpp index e685c30f..11611ea8 100644 --- a/tests/Stormancer-Plugins-Tests-cpp/TestTunnel.cpp +++ b/tests/Stormancer-Plugins-Tests-cpp/TestTunnel.cpp @@ -12,7 +12,9 @@ #include "stormancer/IClientFactory.h" #include "stormancer/Logger/VisualStudioLogger.h" -static constexpr const char* ServerEndpoint = "http://localhost:8080";//"http://gc3.stormancer.com"; +//static constexpr const char* ServerEndpoint = "http://localhost:8080"; +//static constexpr const char* ServerEndpoint = "http://gc3.stormancer.com"; +static constexpr const char* ServerEndpoint = "http://stormancer-1.stormancer.com:8081"; constexpr char* Account = "tests"; constexpr char* Application = "test-app"; diff --git a/tests/Stormancer.Plugins.Tests.ServerApp/Stormancer.Plugins.Tests.ServerApp.csproj b/tests/Stormancer.Plugins.Tests.ServerApp/Stormancer.Plugins.Tests.ServerApp.csproj index 1116ae83..c85f36f4 100644 --- a/tests/Stormancer.Plugins.Tests.ServerApp/Stormancer.Plugins.Tests.ServerApp.csproj +++ b/tests/Stormancer.Plugins.Tests.ServerApp/Stormancer.Plugins.Tests.ServerApp.csproj @@ -11,7 +11,7 @@ - + diff --git a/tests/server-profile/.config/dotnet-tools.json b/tests/server-profile/.config/dotnet-tools.json deleted file mode 100644 index 2b1e1f2e..00000000 --- a/tests/server-profile/.config/dotnet-tools.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "version": 1, - "isRoot": true, - "tools": { - "stormancer.cli": { - "version": "5.3.1", - "commands": [ - "stormancer" - ] - } - } -} \ No newline at end of file diff --git a/tests/server-profile/.gitignore b/tests/server-profile/.gitignore new file mode 100644 index 00000000..14b11206 --- /dev/null +++ b/tests/server-profile/.gitignore @@ -0,0 +1,5 @@ +!.gitignore +.config/* +.stormancer/* +bootstrapper.config.json +default.json diff --git a/tests/server-profile/bootstrapper.config.json b/tests/server-profile/bootstrapper.config.json deleted file mode 100644 index 93a2048a..00000000 --- a/tests/server-profile/bootstrapper.config.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "includePrereleases": false, - "packageSources": [ - "https://api.nuget.org/v3/index.json" - ], - "plugins": { - "Stormancer.Server.Node": "7.1.0.6", - "Stormancer.Logging.Nlog": "1.2.0.4", - "Stormancer.Management.Cli": "0.6.1" - } -} \ No newline at end of file diff --git a/tests/server-profile/config.json b/tests/server-profile/config.json index 0ee9be64..ca71f571 100644 --- a/tests/server-profile/config.json +++ b/tests/server-profile/config.json @@ -1,9 +1,26 @@ { - "dataProtection":{ - "gameServer":{ - "provider":"aes-gcm", - "key":"tests/test-secrets/gameServer", - "createKeyIfNotExists":true + "elasticsearch": { + "connectionPools": { + "default": { + "Sniffing": false, + "Endpoints": [ + "https://localhost:9200" + ], + "IgnoreCertificateErrors": true, + "Credentials": { + "Basic": { + "Login": "elastic", + "PasswordPath": "tests/secrets/elasticSearch_password" + } + } + } + } + }, + "dataProtection": { + "gameServer": { + "provider": "aes-gcm", + "key": "tests/test-secrets/gameServer", + "createKeyIfNotExists": true } } } \ No newline at end of file diff --git a/tests/server-profile/default.json b/tests/server-profile/default.json deleted file mode 100644 index 0797e3a9..00000000 --- a/tests/server-profile/default.json +++ /dev/null @@ -1,251 +0,0 @@ -{ - - "constants": { - "publicIp": "localhost", - "elasticHost": "localhost:9200", - "loadBalancedIp": "localhost", - "dataDirectory": "{workingDirectory}/data/{configName}", - "sharedDirectory": "{workingDirectory}/data/shared", - "cluster": "default", - "n2nPort": "40243", - "apiHttpPort": "80", - "apiHttpsPort": "443", - "adminApiHttpPort": "81", - "udpPort": "30100", - "tempDir": "{workingDirectory}/tmp/{configName}", - "localPackageSource": "{workingDirectory}/packages" - }, - "configs": [ - // Paths to protected files accessible only by the stormancer process. - //The content of these files is added to constants at runtime. - //"{dataDirectory}/secrets/passwords.json" - ], - "security": { - "privateKeyStores": [ - { - "path": "{dataDirectory}/secrets" - } - ] - }, - - "git": { - //Git home directory - "homeDirectory": "~/gitHome", - //Directory containing git - "path": "../../../Standalone/git", - //Storage provider used to store the application repositories. - "repositoriesDirectory": "repositories", - //Local temporary directory used to work on git repositories. - "workingDir": "{tempDir}/repositories" - }, - "api": { - //Config for the public API - "public": { - //Endpoint used for web server binding - "bindings": [ - { - "endpoint": "*:{apiHttpPort}" - } - //}, - - //{ - // "endpoint": [ "*:{apiHttpsPort}" ], - // "settings": { - // "https": "lettuceEncrypt" - // } - //} - ], - //Published endpoint (used by clients to connect to the server) - "published": [ - "http://{loadBalancedIp}:{apiHttpPort}" - //"https://{loadBalancedIp}:{apiHttpsPort}" - ] - }, - //Config for the admin API. - "admin": { - //Endpoint used for web server binding - "bindings": [ - { - "endpoint": "127.0.0.1:{adminApiHttpPort}" - } - ], - //Published endpoint (used by clients to connect to the server) - "published": [ - "http://127.0.0.1:{adminApiHttpPort}" - ] - } - - ////Private key used by the web server for HTTPS. - //"privateKey": { - // "path": "https.pem", - // "password": "{secrets-cluster-pk-password}" - //} - - }, - - "identity": { - //Name of the node. Automatically generated if not specified here. - //It's recommanded to have different names for each node when running distributed. - //"name": "test" - "roles": [ "apps", "data", "leader" ] - }, - //Contains the list of public endpoints to the node and their configuration. - "endpoints": { - "udp1": { - "type": "raknet", - "port": "{udpPort}", - "maxConnections": 65000, - "publicEndpoint": "{publicIp}:{udpPort}" - } - }, - "hosting": { - "packages": { - "applications": "{sharedDirectory}/apps", - //nuget sources used to locate hosts. - //ALWAYS PUT REMOTE SOURCES BEFORE LOCAL SOURCES - "hostSources": [ - "https://api.nuget.org/v3/index.json" - ], - //Sources used during dotnet restore for server applications. - //ALWAYS PUT REMOTE SOURCES BEFORE LOCAL SOURCES - "sources": [ - "https://api.nuget.org/v3/index.json" - //,"{localPackageSource}" - - ] - }, - "dataStorage": "{dataDirectory}/storage", - //Root directory where server applications are loaded. - //The directory of a specific app is : \\\ - "applicationInstallDirectory": "{tempDir}/hosting/apps/", - //Directory where application hosts are loaded. - "hostsDirectory": "{tempDir}/hosting/hosts/", - //Local package storage - "localPackageStorageDirectory": "{tempDir}/packages", - - //Set to true to launch the debugger whenever an host starts. Must be disabled in production. - "launchDebugger": false, - //Port range for application HTTP communications - "allowedPortsRange": "42000-42200", - - "gc": { - //Interval of time in seconds between two subsequent run of the server application GC. - "interval": 60, - //inactivity period in seconds before an application becomes eligible for GC. - "timeout": 600, - //When an app doesn't answers to requests, it is destroyed after this timeout expires (in second). - //Note that when debugging, dev should increase this value to prevent the app from being kill when breakpoints are hit. - "statusTimeout": 30 - } - }, - - - //Configuration for the geo IP plugin - "geoip": { - //Path to the geo ip db in the file system. - "db": "{dataDirectory}/geoip/GeoLite2-City.mmdb" - }, - - - "cluster": { - //Id of the cluster. Defaults to 'default' - "name": "{cluster}", - - //Does the cluster requires node authentication? If no, node 2 node communications are not encrypted, and federation is not possible. - //Setting to true requires configuring a private key. - "requireNodeAuthentication": false, - - "coordination": { - "type": "discovery", - "endpoints": [], - "electionTimeout": { - "min": 800, - "max": 1200 - - }, - "heartbeat": 500 - }, - //minimum number of votes required to elect a leader. - //configure this as more than half the number of nodes in the cluster to prevent split brain situations. - "minVotes": 1, - //Bindings for the cluster transport socket. - "endpoint": [ "*:{n2nPort}" ], - - //endpoint published to contact the node. The endpoint MUST be accessible from all nodes in the cluster. If not, connection edges establishment may fail. - "publishedEndpoint": "{publicIp}:{n2nPort}" - }, - - "federation": { - //Endpoint used by nodes of other clusters in the federation to connect to this node - //leave empty or set to null to prevent this node from accepting connections from nodes in other clusters. - "publicEndpoint": "{publicIp}:{n2nPort}", - "clusters": { - //List of endpoints to try to get metadata about the remote clusters - "endpoints": [ "http://{publicIp}:{adminApiHttpPort}" ], - //Paths containing the public keys authenticating each remote cluster ( - "certificateSources": [ - { - "path": "{dataDirectory}/certs" - } - ] - } - }, - - //nat traversal configuration (used to establish p2p communication between clients) - "p2p": { - //The number of p2p ping attempts that may be active at the same time between two peers. - "maxConcurrentPings": 8, - // - "enableRelay": true - }, - - "logging": { - "outputs": { - "nlog": { - "enabled": true - } - }, - "applications": { - "minLogLevel": "Info" //Min logging level for applications. Trace, Debug, Info, Warn, Error, Fatal - } - - }, - "tokens": { - "maxUserDataSize": 10240, - "randomAccount": { - "randomApp": { - "useNativeDateFormat": false // disable nativeDate format in tokens for randomAccount/randomApp - }, - "useNativeDateFormat": true // enable nativeDate format in tokens for app in randomAccount different from randomAccount/randomApp - }, - "useNativeDateFormat": false //// disable nativeDate format in all other accounts. - }, - - "plugins": { - "aws": { - "enabled": false - }, - "lettuceEncrypt": { - "enabled": false, - // Which API type to use LettuceEncrypt with. Due to a current limitation, it cannot be enabled for both public and admin APIs. - // Valid values are "public" and "admin". - "apiType": "public", - // Email for certificate renewal (required) - "email": "email@email.com", - // Domain name(s) to request certificates for - "domainNames": [ "{loadBalancedIp}" ], - // Use Let's Encrypt staging server for issuing certificate. true for testing ; false for prod - "useStagingServer": true, - // Directory to be used to save LettuceEncrypt data. Required. - "certificateDirectory": "{dataDirectory}/lettuceEncrypt", - // Show detailed LettuceEncrypt (and Kestrel) logs. - "showLogs": false - } - }, - "fileStorage": { - "appPackages": { - "type": "fileSystem", - "root": "{sharedDirectory}/apps" - } - } -} diff --git a/tests/server-profile/deploy-stormancer-dev.ps1 b/tests/server-profile/deploy-stormancer-dev.ps1 new file mode 100644 index 00000000..7d315fc6 --- /dev/null +++ b/tests/server-profile/deploy-stormancer-dev.ps1 @@ -0,0 +1,2 @@ +Write-Output "==== Deploy application ====" +dotnet tool run stormancer manage app deploy --app ".\stormancer-dev.profile.json" --create --configure --deploy diff --git a/tests/server-profile/init.ps1 b/tests/server-profile/init.ps1 new file mode 100644 index 00000000..66919f62 --- /dev/null +++ b/tests/server-profile/init.ps1 @@ -0,0 +1,63 @@ +$baseUri = "http://stormancer-1.stormancer.com:9080" +$deployConfigFile = "stormancer-dev.profile.json" +$secretsStoreId = "secrets"; + +function ensureSuccessStatusCode +{ + param ($response) + if (! (($response.StatusCode -ge 200) -and ($response.StatusCode -lt 300))) + { + Write-Output "Failed : ${response.StatusCode} ${response.StatusDescription}" + Write-Host $response + Exit + } + else + { + Write-Output $response.StatusDescription + } +} + +Write-Output "==== Create new tool manifest ====" +dotnet new tool-manifest + +Write-Output "==== Install Stormancer.CLI ====" +dotnet tool install Stormancer.CLI + +Write-Output "==== Install Stormancer new config ====" +dotnet tool run stormancer new config + +Write-Output "==== Install Stormancer plugins ====" +dotnet tool run stormancer plugins add --id Stormancer.Server.Node +dotnet tool run stormancer plugins add --id Stormancer.Logging.Nlog +dotnet tool run stormancer plugins add --id Stormancer.Management.CLI +dotnet tool run stormancer plugins add --id Stormancer.Elasticsearch +dotnet tool run stormancer plugins add --id Stormancer.Diagnostics + +Write-Output "==== Add Stormancer cluster ====" +dotnet tool run stormancer manage clusters add --endpoint "$baseUri" + +try +{ + Write-Output "==== Extract account name ====" + $envConfig = Get-Content "$deployConfigFile" | ConvertFrom-Json + $account = $envConfig.Account + $cluster = $envConfig.Cluster + Write-Output "Account = '$account'" + Write-Output "Cluster = '$cluster'" +} +catch +{ + Write-Output "Error: Can't read deployConfigFile '$deployConfigFile'" + return 1 +} + +Write-Output "==== Create account ====" +$response = Invoke-WebRequest -Method Put -Uri "$baseUri/_account/$account" -ContentType "application/json" -Body "{}" +ensureSuccessStatusCode($response) + +Write-Output "==== Create secrets store ====" +dotnet tool run stormancer manage secrets-store create --cluster $cluster --account $account --id $secretsStoreId + +Write-Output "==== Push secrets ====" +$response = Invoke-WebRequest -Method Put -Uri "$baseUri/_secrets/$account/$secretsStoreId/elasticSearch_password" -ContentType "text/plain" -InFile "$PSScriptRoot\secrets\elasticSearch_password.txt" +ensureSuccessStatusCode($response) diff --git a/tests/server-profile/secrets/.gitignore b/tests/server-profile/secrets/.gitignore new file mode 100644 index 00000000..d6b7ef32 --- /dev/null +++ b/tests/server-profile/secrets/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/tests/server-profile/stormancer-dev.profile.json b/tests/server-profile/stormancer-dev.profile.json new file mode 100644 index 00000000..c016f6d2 --- /dev/null +++ b/tests/server-profile/stormancer-dev.profile.json @@ -0,0 +1,13 @@ +{ + "Cluster": "stormancer-dev", + "Account": "tests", + "App": "test-app", + "Config": { + "Type": "file", + "Value": ".\\config.json" + }, + "Deployment": { + "Type": "directory", + "Value": "..\\Stormancer.Plugins.Tests.ServerApp\\" + } +} \ No newline at end of file