Custom Classes

Note

The following is an advanced feature and requires editing C++ code.

Relay messages take Strix Relay Args, but developers may want to define their own classes to be sent through Strix.

Custom classes can be sent through Strix functions, so long as they make use of the correct classes and macros. With a little work, it is possible to transform existing classes into Strix compatible classes for Relay functions to use.

A Strix Compatible Class

// Class must extend strix::net::object::Object.
class ChatMessage : public strix::net::object::Object
{
public:

    // The STRIX_CLASS macro takes the class and its superclass,
    // and additional macros.
    // STRIX_CLASS(ClassType, SuperClass)
    STRIX_CLASS(ChatMessage, Object)
    (

        // Defines the ID of this class. Should be unique. The Java style import path is used here.
        // STRIX_CLASS_ID(id)
        STRIX_CLASS_ID("jp.co.soft_gear.strix.server.core.message.ChatMessage")

        // STRIX_PROPERTY macros take the name of a member of the class.
        // These define these variables as class properties, which is important
        // for serialization in the network.
        // STRIX_PROPERTY(MemberName)
        STRIX_PROPERTY(sender)
        STRIX_PROPERTY(message)
    )

    // Getter and setter methods for the message information.
    void SetMessage(std::string msg)
    {
    message = msg;
    }

    std::string GetMessage()
    {
    return message;
    }

    void SetSender(std::string snd)
    {
    sender = snd;
    }

    std::string GetSender()
    {
    return sender;
    }

private:

    // Member variables, as used in the STRIX_PROPERTY macros above.
    std::string sender;
    std::string message;
};

The following changes are needed:

  1. All classes compatible with Strix should extend strix::net::object::Object, which is the base class representing an object in Strix.

  2. The STRIX_CLASS macro should be added inside the class definition, and inside this:

  3. The STRIX_CLASS_ID should be defined as a unique ID for this class.

  4. STRIX_PROPERTY macros should take the class’s member variables as arguments to register them as properties of this class.

One limitation is the fact that Strix can only serialize/deserialize simple types. For this custom class, the member variables are std::string, and this Strix can handle. To operate on other custom types without breaking them down further, see How to Serialize Custom Classes.

Sending Custom Class Messages

Strix compatible classes can be sent through Strix functions as normal:

RelayChatMessage(const UObject* WorldContextObject, int32 channelId, const FStrixRoomRelayDelegate& successCallback, const FStrixErrorCodeFailureDelegate& failureCallback)
{

    // Get the network facade.
    UStrixNetworkFacade* strixNetwork = UStrixNetworkFacade::GetInstance(WorldContextObject);

    // Get the room context.
    auto context = strixNetwork->GetRoomContextByChannelId(channelId);
    if (context)
    {

        // Make a custom message and set its values.
        auto chatMessage = std::make_shared<ChatMessage>();
        chatMessage->SetMessage("Hello World");
        chatMessage->SetSender("Me");

        // Send the room Relay message.
        context->SendRoomRelay(chatMessage,
            [=](strix::client::ingame::network::RoomRelayEventArgs args)
            {
                successCallback.ExecuteIfBound(channelId);
            },
            [failureCallback](strix::client::ingame::network::RoomContextFailureEventArgs args)
            {
                failureCallback.ExecuteIfBound(args.GetErrorCode(), StrixErrorCodeConverter::ConvertStrixErrorCategoryToUEEnum(args.GetErrorCategory()));
            }
        );
    }
    else
    {
        failureCallback.ExecuteIfBound(StrixUESDKErrorCode::RoomContextDoesNotExist, EStrixErrorCategory::StrixUESDK);
    }
}

Receiving Custom Class Messages

Likewise, the custom classes can be deserialized by the client in handler functions:

// Room Relay delegate. This is to delegate the handling of the message to a Blueprint.
DECLARE_DYNAMIC_DELEGATE_OneParam(FStrixRoomRelayNotificationDelegate, FString, Message);

void RegisterStrixChatNotificationHandler(const UObject * WorldContextObject, const FStrixRoomRelayNotificationDelegate& handler, int32 channelId)
{

    // Get the network facade.
    UStrixNetworkFacade* strixNetwork = UStrixNetworkFacade::GetInstance(WorldContextObject);

    // Get room context.
    auto context = strixNetwork->GetRoomContextByChannelId(channelId);
    if (context != nullptr)
    {

        // Get the match room client.
        auto matchRoomClient = context->GetMatchRoomClient();
        if (matchRoomClient)
        {

            // Add a handler function for when a Relay message is received.
            matchRoomClient->AddRoomRelayNotifiedHandler([=](strix::client::core::NotificationEventArgs<strix::client::room::message::RoomRelayNotificationPtr> args)
            {

                // Get the chat message from the notification data.
                auto message = std::static_pointer_cast<ChatMessage>(args.m_data->GetMessageToRelay());
                if (!message)
                {
                    return;
                }

                // Get its information, converting to FStrings.
                FString messageText = UTF8_TO_TCHAR(message->GetMessage().c_str());
                FString sender = UTF8_TO_TCHAR(message->GetSender().c_str());

                // Call handler with the message as the argument.
                if (args.m_data->GetRoomId() == matchRoomClient->GetRoomData()->GetRoom()->GetPrimaryKey())
                {
                    handler.ExecuteIfBound(sender + ": " + messageText);
                }
            });
        }
    }
}

Note

The STRIX_PROPERTY macro can only be used for serializable properties. For more on serialization and custom type serialization, see How to Serialize Custom Classes.