diff --git a/lib/EventAPI-JS.d.ts b/lib/EventAPI-JS.d.ts index 1b669a1..b8654bc 100644 --- a/lib/EventAPI-JS.d.ts +++ b/lib/EventAPI-JS.d.ts @@ -13,7 +13,7 @@ declare class Event { ) => boolean | void ): boolean; - /** 客户端登录后事件 */ + /** 客户端登录后事件(不可以拦截) */ static listen( /** 事件名 */ event: "onClientLogin", @@ -27,7 +27,7 @@ declare class Event { serverXuid: string, /** 玩家在客户端的xuid */ clientXuid: string - ) => bool + ) => void ): boolean; /** 天气改变事件事件 */ diff --git a/lib/EventAPI-JS.js b/lib/EventAPI-JS.js index 3fd454c..bddf72f 100644 --- a/lib/EventAPI-JS.js +++ b/lib/EventAPI-JS.js @@ -1,11 +1,11 @@ /** 事件创建函数 @type {function(string,string):boolean} */ -const CallEvent = ll.import("GMLIB_API", "callCustomEvent"); +const CallEvent = ll.import("GMLIB_Event_API", "callCustomEvent"); +/** 获取事件ID函数 @type {function():string} */ +const getNextEventId = ll.import("GMLIB_Event_API", "getNextScriptEventId"); /** 事件类 */ class Event { - constructor() { - throw new Error("Static class cannot be instantiated"); - } + constructor() { throw new Error("Static class cannot be instantiated"); } /** * 监听事件 @@ -14,17 +14,15 @@ class Event { * @returns {boolean} 是否创建成功 */ static listen(event, callback) { - let eventId = "GMLIB_Event_" + Math.random().toString(16).slice(2); + let eventId = getNextEventId(); ll.export(callback, event, eventId); let result = CallEvent(event, eventId); if (!result) { - logger.error(`Cannot listen event "${event}"!`); - logger.error(`Event "${event}" No Found!`); + logger.error(`Cannot listen event "${event}" !`); + logger.error(`GMLIB Script Event "${event}" does not exist !`); } return result; } } -module.exports = { - Event -}; \ No newline at end of file +module.exports = {Event}; \ No newline at end of file diff --git a/src/EventAPI.cpp b/src/EventAPI.cpp index 09fead1..9821080 100644 --- a/src/EventAPI.cpp +++ b/src/EventAPI.cpp @@ -1,38 +1,63 @@ #include "Global.h" using namespace ll::hash_utils; +class LegacyScriptEventManager { +private: + int64 mNextEventId = 0; + std::unordered_map mEventListeners; + +public: + LegacyScriptEventManager() {}; + ~LegacyScriptEventManager() {}; + + std::string getNextEventId() { + mNextEventId++; + return std::to_string(mNextEventId); + } + + void emplaceListener(std::string const& scriptEventId, ll::event::ListenerPtr listenerPtr) { + mEventListeners[scriptEventId] = listenerPtr; + } + + void removeListener(std::string const& scriptEventId) { + ll::event::EventBus::getInstance().removeListener(mEventListeners[scriptEventId]); + mEventListeners.erase(scriptEventId); + } + + static std::unique_ptr& getInstance() { + static std::unique_ptr instance; + return instance; + } +}; + #define REGISTER_EVENT_LISTEN(eventType, callFunction, eventParams, cancelFunction, otherFunction) \ - if (eventListeners.contains(eventName + "_" + eventId)) \ - eventBus.removeListener(eventListeners.at(eventName + "_" + eventId)); \ - eventListeners[eventName + "_" + eventId] = \ - eventBus.emplaceListener([eventName, eventId, &eventBus](eventType& ev) -> void { \ + eventManager->emplaceListener( \ + eventId, \ + eventBus.emplaceListener([eventName, eventId, &eventBus, &eventManager](eventType& ev) -> void { \ if (!RemoteCall::hasFunc(eventName, eventId)) { \ - eventBus.removeListener(eventListeners.at(eventName + "_" + eventId)); \ - eventListeners.erase(eventName + "_" + eventId); \ + eventManager->removeListener(eventId); \ return; \ } \ bool result = true; \ try { \ otherFunction; \ result = RemoteCall::importAs(eventName, eventId) eventParams; \ - } catch (std::exception & e) { \ - if (std::string(e.what()) != "bad variant access") { \ - logger.error("Exception in event listener: {0}", e.what()); \ - logger.error("Event: {0}, Id: {1}", eventName, eventId); \ - } \ - } \ + } catch (...) {} \ if (!result) cancelFunction; \ - }); \ + }) \ + ); \ return true; -std::unordered_map eventListeners; - void Export_Event_API() { - auto& eventBus = ll::event::EventBus::getInstance(); + RemoteCall::exportAs("GMLIB_Event_API", "getNextScriptEventId", []() -> std::string { + return LegacyScriptEventManager::getInstance()->getNextEventId(); + }); + auto& eventBus = ll::event::EventBus::getInstance(); + auto& eventManager = LegacyScriptEventManager::getInstance(); RemoteCall::exportAs( - "GMLIB_API", + "GMLIB_Event_API", "callCustomEvent", - [&eventBus](std::string const& eventName, std::string const& eventId) -> bool { + [&eventBus, &eventManager](std::string const& eventName, std::string const& eventId) -> bool { if (!RemoteCall::hasFunc(eventName, eventId)) return false; switch (doHash(eventName)) { case doHash("onClientLogin"): { @@ -43,7 +68,7 @@ void Export_Event_API() { std::string const& serverXuid, std::string const& clientXuid), (ev.getRealName(), ev.getUuid().asString(), ev.getServerAuthXuid(), ev.getClientAuthXuid()), - ev.disConnectClient(), + logger.error("Event \"onClientLogin\" cannot be intercepted"), ); } case doHash("onWeatherChange"): {