Kaiserludi admin


Last Active
Registered, Administrator
  • Re: Keep my player number after disconnection

    Interesting. That response seems to imply that UE4 uses widestrings not just inside the API and other code, but also as the format for transmitting the string over the network.

    This is different in Photon.
    Photon uses UTF16 (on Microsoft platforms) / UTF32 (on every other platform) encoded wide strings in the Client API, but UTF8 encoded narrow strings for the actual transmission over the network (Photon automatically converts all contained strings to and from UTF8 when serializing/deserializing data) as especially compared to UTF32 strings and with mainly Western characters UTF8 saves a lot (about 75% per character) of network traffic for strings. With East Asian (i.e. Chinese, Japanese and Korean) characters the difference naturally is a lot smaller, especially between UTF8 and UTF16, as most of those characters need 2bytes and can even take up to 5 bytes in UTF8.

    So why are we using wide string in the API, when we use UTF8 in the network anyway? Couldn't we then just use narrow strings everywhere ans get rid of those conversions?
    Well the main reasons against using UTF8 everywhere are a) that wide strings allow for much faster performance in practically all string operations, while the extra memory costs for storing the string variables are negligible (CPU cycles are expensive, RAM is cheap) and b) that on some platforms UTF8 support is (or was) rather limited.
  • Re: Implementing Photon Voice with c++

    Hi @jbelonalea.

    You may just want to download our Photon Voice package for Unity and implement it in a similar way in C++.
    The C# Voice Client uses Opus for the Audio encoding and Opus itself is written in C++, so that would be what we would also use in a C++ port of Photon Voice.

    You might also just contact us by email (https://www.photonengine.com/en-US/Contact) and discuss options.
  • Re: Keep my player number after disconnection

    Hi @jbelonalea.

    As UE4 on default uses wchar_t*, not char*, for the internal representation of FString, and JString also uses wchar_t* internally, the conversion between JString and FString is very straightforward and does not involve any UTF8 conversion at all.

    However you should get into the habit of not using "string", but instead use L"string", to get rid of a lot of silent implicit conversions.

    Furthermore instead of
    trsData.put<const char*, const char*>("aname", actorName.UTF8Representation().cstr());
    you should simply write
    trsData.put(L"aname", actorName);
    The first variant involves 1 explicit conversion to UTF8 and 2 implicit ones from UTF8, while the second one involves no conversion at all and also makes the code a lot shorter and simpler.

    FString aname(ValueObject<JString>(ValueObject<const char*>(custom_event.getValue("aname"))).getDataCopy().UTF8Representation().cstr());
    can be simplified to
    FString aname(ValueObject<JString>(ValueObject<JString>(custom_event.getValue("aname"))).getDataCopy().cstr();
    and the same holds true for all the other samples.

    Please also read this post for more information about this topic:

    I have just updated all my string conversion related posts in this thread and removed the misleading information that was written under the impression that FString would use char*.
  • Re: Keep my player number after disconnection

    Let's think about what's actually happening here:
    - sLog is a JString
    - you convert that into a UTF8String with JString::UTF8Representation()
    - then you grab the char* representation of that one with UTF8String::cstr()
    - and construct an FString from it with FString::FString() (which implies a conversion back from UTF8 into the original UTF16/UTF32 format, which both, JString and FString use)
    - just to grab the wchar_t* representation of that one with FString::operator*()

    So the whole procedure is pointless and you can remove it as JString::cstr() returns a const reference to it's internal buffer that already is a wchar_t* in the first place.

    Just replace the "%s" with "%ls". The former tells the function to expect a narrow string (char*), so when you parse a wide string (wchar_t*) instead it still interprets it as a narrow one and that is where you junk output characters come from. The latter however tells it to expect a wide string, so it would output junk when you actually pass in a narrow string, but it interprets your input correctly when you pass in a wide string.

    The following will work just fine without any conversions to or from UTF8:
    void NetworkLogic::writeLog(const JString& sLog)
        UE_LOG(LogNetwork, Warning, TEXT("<NetworkLogic>: %ls"), sLog.cstr());
  • Re: How Do I know MasterClient is Change ? Like OnMasterClientSwitched()

    Hi @Owen.

    Switching the master client status through the API is not currently supported in the C++ clients.
    If you need this, then you could implement it by extending LoadBalancing-cpp accordingly to your requirements, as the master client is a feature that is entirely implemented on the Client side, so that no server side modifications are necessary.

    There is no callback for a master client switch. However the master client only is switched when the previous master client leaves the room.
    In case that any client leaves the room the other clients get informed about that in their Listener::leaveRoomeventAction() callbacks.
    So inside you implementation of that callback you could just read out the return value of LoadBalancing::Client::getCurrentlyJoinedRoom()::getMasterClientID() to get the up to date master client ID. If you have stored a previous return value of that function from the same room then you can compare it with the new value to find out if the ID has changed or is still the same. If it has changed, then the master client has switched to the client, to which that new ID belongs, otherwise that client already has been the master client before and still is it.