// Nakama Console App 2.cpp : This file contains the 'main' function. Program execution begins and ends there. // #include #include #include #include "nakama-cpp/Nakama.h" using namespace NAKAMA_NAMESPACE; using namespace std; class NakamaSessionManager { public: bool active = false; bool& SessionActive = active; //Make a bool for session active, make a pointer to that bool so that we can manipulate it in Main. //QUESTION: why do we need to use a pointer? why isn't "sessionname.active" good enough? protected: //Why protect the client and the session? NClientPtr _client; NSessionPtr _session; NRtClientPtr rtClient; NRtDefaultClientListener listener; public: //the Constructor NakamaSessionManager() { SessionActive = false; NClientParameters parameters; _client = createDefaultClient(parameters); } /* The Start Function. Restores a sessionToken if you have one otherwise defines Success and Error calbacks, then uses those callbacks to authenticate. Then sets up the RT Client and the Listener (QUESTION: what is the listener?) */ void start(const string& deviceId) { // to do: read session token from your storage string sessionToken; //if there is a Session token in storage, try to use it. if (!sessionToken.empty()) { // Lets check if we can restore a cached session. auto session = restoreSession(sessionToken); if (!session->isExpired()) { // Session was valid and is restored now. _session = session; SessionActive = true; return; } } /* Define Success and Error fucntions to use as arguments for "authenticateDevice" below. QUESTION: I do not understand this syntax. I also don't understand why we have to use a pointer to "session." */ auto successCallback = [this](NSessionPtr session) { _session = session; SessionActive = true; // to do: save session token in your storage std::cout << "session token: " << session->getAuthToken() << std::endl; cout << "GOT THE TOKEN!\n"; }; auto errorCallback = [](const NError& error) { //QUESTION: how do I access the actual Error message? std::cout << "Something went wrong."; }; /* Call the "authenticateDevice" function of the client object. Give a deviceID and instructions for success and erro. QUESTION: The definition of this function is just set to 0. What does the function actually do?! A tick is necessary before the successCallback operates. Where do I see the code that waits for the tick? */ _client->authenticateDevice(deviceId, "UserNameTest", opt::nullopt, {}, successCallback, errorCallback); Sleep(150); _client->tick(); /* Set up the realtime client and the listener. QUESTION: Is this necessary? https://heroiclabs.com/docs/nakama/concepts/authentication/#session https://heroiclabs.com/docs/nakama/client-libraries/cpp-client-guide/#realtime-client */ int port = 7352; // different port to the main API port bool createStatus = true; // if the server should show the user as online to others. // Set up the RealTime Client and listener rtClient = _client->createRtClient(); listener.setConnectCallback([]() { cout << "Socket connected." << endl; }); rtClient->setListener(&listener); rtClient->connect(_session, createStatus); } //the Tick Function void TheTick() { while (SessionActive) { _client->tick(); cout << "Tick\n"; // cout << "Session Active = " << SessionActive << "\n"; Sleep(150); } } /* And now begins the litany of useful functions */ // A function to get the User's Nakama ID void getUserID() { auto successCallback = [](const NAccount& account) { cout << "User's Nakama ID: " << account.user.id.c_str() << "\n"; }; _client->getAccount(_session, successCallback); }; // A function to get the User's Name void getUserName() { cout << "User's Name: " << _session->getUsername() << "\n"; }; //A function to create a match void createMatch() { rtClient->createMatch([](const NMatch& match) { std::cout << "Created Match with ID: " << match.matchId << std::endl; }); }; }; int main() { NLogger::initWithConsoleSink(NLogLevel::Debug); NakamaSessionManager MySession; MySession.start("1234567890"); //TOOD: Get the MacAddress as DeviceId MySession.getUserID(); MySession.getUserName(); //TOOD: Set your Own UserName thread Ticker(&NakamaSessionManager::TheTick, MySession); Sleep(600); MySession.createMatch(); Sleep(600); MySession.SessionActive = false; //after 4 ticks kill the thead. cout << "Then Session Active = " << MySession.SessionActive << "\n"; Ticker.join(); MySession.createMatch(); Sleep(600); cout << "Finished"; };