OpenStarbound / OpenStarbound

393 stars 47 forks source link

Add chat.setMessageHandler #130

Open KrashV opened 1 month ago

KrashV commented 1 month ago

A new callback for chat would be super helpful to replace the old SE version. Basically:

void chat.setMessageHandler(LuaFunction handler)

Messages of the specified message type received by this script context will call the specified function. The first two arguments passed to the handler function will be the String messageName and a bool indicating whether the message is from a local entity, followed by any arguments sent with the message.

On the received message in chat the specified function will be called. The only argument passed to the handler function is the Json representation of ChatReceivedMessage.

The handling would be really close to MessageHandler already implemented, but instead of having a map of messages it should invoke all the stored luafunctions in the map / array, since several mods could subscripe to receive the messages

KrashV commented 1 month ago

Basically, something like this

template <typename Base>
LuaChatMessageHandlingComponent<Base>::LuaChatMessageHandlingComponent() {
  LuaCallbacks scriptCallbacks;
  scriptCallbacks.registerCallback("setHandler", [this](Maybe<LuaFunction> handler) {
    ChatMessageHandler handlerInfo = {};

    if (handler) {
      handlerInfo.function.emplace(handler.take());
      m_chatMessageHandlers.append(handlerInfo);
    }
  });

  Base::addCallbacks("chat", std::move(scriptCallbacks));
}

template <typename Base>
Maybe<Json> LuaChatMessageHandlingComponent<Base>::handleMessage(
  JsonArray const& args) {
  if (!Base::initialized())
    return {};

  for (auto handler : m_chatMessageHandlers) {
    try {
      return handler->function->template invoke<Json>(luaUnpack(args));
    } catch (LuaException const& e) {
      Logger::error(
        "Exception while invoking lua chat message handler. {}", outputException(e, true));
      Base::setError(String(printException(e, false)));
    }
  }
  return {};
}