From ea9934f315e7524eec8269580725d25163fcee6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=90=E6=B2=90=E5=91=80?= <163636894+zimuya4153@users.noreply.github.com> Date: Mon, 24 Jun 2024 02:13:25 +0800 Subject: [PATCH 01/37] 2024-06-24 2:13 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加jsdoc注释和d.ts补全文件 - 修改getBlockRuntimeId接口,使其支持填写特殊值 - 添加getBlockLightEmission,getGameRules,applyEnchant,removeEnchants,hasEnchant,getEnchantLevel,getEnchantNameAndLevel接口 - 导出事件onEntityChangeDimAfter,DragonRespawn,ProjectileTryCreate,ProjectileCreate --- lib/BEPlaceholderAPI-JS.d.ts | 67 ++ lib/BEPlaceholderAPI-JS.js | 69 +- lib/EventAPI-JS.d.ts | 194 +++++ lib/EventAPI-JS.js | 13 + lib/GMLIB_API-JS.d.ts | 1140 ++++++++++++++++++++++++++++ lib/GMLIB_API-JS.js | 1377 +++++++++++++++++++++++++++++++--- src/CompatibilityApi.cpp | 71 +- src/EventAPI.cpp | 400 +++++----- 8 files changed, 3031 insertions(+), 300 deletions(-) create mode 100644 lib/BEPlaceholderAPI-JS.d.ts create mode 100644 lib/EventAPI-JS.d.ts create mode 100644 lib/GMLIB_API-JS.d.ts diff --git a/lib/BEPlaceholderAPI-JS.d.ts b/lib/BEPlaceholderAPI-JS.d.ts new file mode 100644 index 0000000..0328a22 --- /dev/null +++ b/lib/BEPlaceholderAPI-JS.d.ts @@ -0,0 +1,67 @@ +declare class PAPI { + /** 注册一个玩家PAPI变量 */ + static registerPlayerPlaceholder( + /** PAPI调用函数 */ + func: ( + /** 玩家对象 */ + player: Player + ) => string, + /** 插件名字 */ + pluginsName: string, + /** PAPI变量 */ + PAPIName: string + ): boolean; + + /** 注册一个服务器PAPI变量 */ + static registerServerPlaceholder( + /** PAPI调用函数 */ + func: () => string, + /** 插件名字 */ + pluginsName: string, + /** PAPI变量 */ + PAPIName: string + ): boolean; + + /** 注册一个静态PAPI变量 */ + static registerStaticPlaceholder( + /** PAPI调用函数 */ + func: () => string, + /** 插件名字 */ + pluginsName: string, + /** PAPI变量 */ + PAPIName: string, + /** 更新时间 */ + UpdateInterval: number + ): boolean; + + /** 获取一个服务器变量的值 */ + static getValue( + /** PAPI名 */ + key: string + ): string; + + /** 获取一个玩家变量的值 */ + static getValueByPlayer( + /** PAPI名 */ + key: string, + /** 玩家对象 */ + pl: Player + ): string; + + /** 翻译带PAPI变量的字符串 */ + static translateString( + /** 要翻译的字符串 */ + str: string, + /** 玩家对象 */ + pl: Player | undefined + ): string; + + /** 注销一个PAPI变量 */ + static unRegisterPlaceholder( + /** PAPI名 */ + str: string + ): boolean; + + /** 获取所有已注册的PAPI变量 */ + static getAllPAPI(): string[]; +} diff --git a/lib/BEPlaceholderAPI-JS.js b/lib/BEPlaceholderAPI-JS.js index 50ba212..6d5af74 100644 --- a/lib/BEPlaceholderAPI-JS.js +++ b/lib/BEPlaceholderAPI-JS.js @@ -1,47 +1,101 @@ const PlaceholderAPI = { + /** 获取一个服务器变量的值 @type {function(string):string} */ getValueAPI: ll.import("BEPlaceholderAPI", "GetValue"), + /** 获取一个玩家变量的值 @type {function(string,Player):string} */ getValueByPlayerAPI: ll.import("BEPlaceholderAPI", "GetValueWithPlayer"), + /** 注册一个玩家变量 @type {function(string,string,string):boolean} */ registerPlayerPlaceholderAPI: ll.import("BEPlaceholderAPI", "registerPlayerPlaceholder"), + /** 注册一个服务器变量 @type {function(string,string,string):boolean} */ registerServerPlaceholderAPI: ll.import("BEPlaceholderAPI", "registerServerPlaceholder"), + /** 注册一个静态变量 @type {function(string,string,string,number):boolean} */ registerStaticPlaceholderAPI: ll.import("BEPlaceholderAPI", "registerStaticPlaceholder"), + /** 翻译包含PAPI服务器变量的字符串 @type {function(string):string} */ translateStringAPI: ll.import("BEPlaceholderAPI", "translateString"), + /** 翻译包含PAPI玩家变量的字符串 @type {function(string,Player):string} */ translateStringWithPlayerAPI: ll.import("BEPlaceholderAPI", "translateStringWithPlayer"), + /** 注销PAPI变量 @type {function(string):boolean} */ unRegisterPlaceholderAPI: ll.import("BEPlaceholderAPI", "unRegisterPlaceholder"), + /** 获取所有已注册的PAPI变量 @type {function():Array.} */ getAllPAPI: ll.import("BEPlaceholderAPI", "getAllPAPI") } -Function.prototype.getName = function () { - return this.name || this.toString().match(/function\s*([^(]*)\(/)[1] +Function.prototype.getName = +/** + * 获取函数名字 + * @returns {string} + */ +function () { + return this.name || this.toString().match(/function\s*([^(]*)\(/)[1] || Math.ceil(Math.random() * 1000000).toString(16); } +/** PAPI变量类 */ class PAPI { constructor() { throw new Error("Static class cannot be instantiated"); } + /** + * 注册一个玩家PAPI变量 + * @param {function} func 变量调用的函数 + * @param {string} PluginName 插件名字 + * @param {string} PAPIName PAPI变量名 + * @returns {boolean} 是否注册成功 + */ static registerPlayerPlaceholder(func, PluginName, PAPIName) { ll.export(func, PluginName, func.getName()); return PlaceholderAPI.registerPlayerPlaceholderAPI(PluginName, func.getName(), PAPIName); } + /** + * 注册一个服务器PAPI变量 + * @param {function} func 变量调用的函数 + * @param {string} PluginName 插件名字 + * @param {string} PAPIName PAPI变量名 + * @returns {boolean} 是否注册成功 + */ static registerServerPlaceholder(func, PluginName, PAPIName) { ll.export(func, PluginName, func.getName()); return PlaceholderAPI.registerServerPlaceholderAPI(PluginName, func.getName(), PAPIName); } + /** + * 注册一个静态PAPI变量 + * @param {function} func 变量调用的函数 + * @param {string} PluginName 插件名字 + * @param {string} PAPIName PAPI变量名 + * @param {number} [UpdateInterval=50] 更新间隔 + * @returns {boolean} 是否注册成功 + */ static registerStaticPlaceholder(func, PluginName, PAPIName, UpdateInterval = 50) { ll.export(func, PluginName, func.getName()); return PlaceholderAPI.registerStaticPlaceholderAPI(PluginName, func.getName(), PAPIName, UpdateInterval); } + /** + * 获取一个服务器变量的值 + * @param {string} key PAPI变量名 + * @returns {string} 值 + */ static getValue(key) { return PlaceholderAPI.getValueAPI(key); } - + + /** + * 获取一个玩家变量的值 + * @param {string} key PAPI变量名 + * @param {Player} pl 玩家对象 + * @returns {string} 值 + */ static getValueByPlayer(key, pl) { return PlaceholderAPI.getValueByPlayerAPI(key, pl); } + /** + * 翻译带PAPI变量的字符串 + * @param {string} str 字符串 + * @param {Player} pl 玩家对象 + * @returns {string} 翻译结果 + */ static translateString(str, pl = null) { if (pl) { return PlaceholderAPI.translateStringWithPlayerAPI(str, pl); @@ -49,10 +103,19 @@ class PAPI { return PlaceholderAPI.translateStringAPI(str); } + /** + * 注销一个PAPI变量 + * @param {string} str PAPI变量名 + * @returns {boolean} 是否注销成功 + */ static unRegisterPlaceholder(str) { return PlaceholderAPI.unRegisterPlaceholderAPI(str); } + /** + * 获取所有已注册的PAPI变量 + * @returns {Array.} 已注册的PAPI变量数组 + */ static getAllPAPI() { return PlaceholderAPI.getAllPAPI(); } diff --git a/lib/EventAPI-JS.d.ts b/lib/EventAPI-JS.d.ts new file mode 100644 index 0000000..54af930 --- /dev/null +++ b/lib/EventAPI-JS.d.ts @@ -0,0 +1,194 @@ +/// + +/** 事件监听接口 */ +declare class Event2 { + /** 生物捡起物品 */ + static listen( + /** 事件名 */ + event: "onMobDie", + /** 监听函数 */ + listener: ( + /** 尝试捡起物品的实体对象 */ + entity: Entity, + /** 掉落物实体对象 */ + itemEntity: Entity + ) => boolean | void + ): boolean; + + /** 客户端登录后事件(不可以拦截) */ + static listen( + /** 事件名 */ + event: "onClientLogin", + /** 监听函数 */ + listener: ( + /** 玩家的游戏名字 */ + realName: string, + /** 玩家的uuid */ + uuid: string, + /** 玩家在服务端的xuid */ + serverXuid: string, + /** 玩家在客户端的xuid */ + clientXuid: string + ) => void + ): boolean; + + /** 天气改变事件事件 */ + static listen( + /** 事件名 */ + event: "onWeatherChange", + /** 监听函数 */ + listener: ( + /** 雷暴天气等级 */ + lightningLevel: number, + /** 雨天天气等级 */ + rainLevel: number, + /** 雷暴持续时间(刻) */ + lightningLastTick: number, + /** 雨天持续时间(刻) */ + rainingLastTick: number + ) => boolean | void + ): boolean; + + /** 掉落物尝试生成 */ + static listen( + event: "onItemTrySpawn", + listener: ( + /** 物品对象 */ + item: Item, + /** 尝试生成的坐标对象 */ + pos: FloatPos, + /** 创建掉落物的实体对象 */ + spawnerEntity: Entity + ) => boolean | void + ): boolean; + + /** 掉落物生成完毕(不可以拦截) */ + static listen( + /** 事件名 */ + event: "onItemTrySpawn", + /** 回调函数 */ + listener: ( + /** 物品对象 */ + item: Item, + /** 掉落物实体对象 */ + entity: Entity, + /** 实体生成的坐标 */ + pos: FloatPos, + /** 创建掉落物的实体对象 */ + spawnerEntity: Entity + ) => void + ): boolean; + + /** 实体切换维度 */ + static listen( + /** 事件名 */ + event: "onEntityChangeDim", + /** 回调函数 */ + listener: ( + /** 切换维度的实体对象 */ + entity: Entity, + /** 前往到的维度ID */ + dimid: number + ) => boolean | void + ): boolean; + + /** 实体切换维度后(不可拦截) */ + static listen( + /** 事件名 */ + event: "onEntityChangeDimAfter", + /** 回调函数 */ + listener: ( + /** 切换维度的实体对象 */ + entity: Entity, + /** 前往到的维度ID */ + fromDimid: number + ) => void + ): boolean; + + /** 玩家下床 */ + static listen( + /** 事件名 */ + event: "onLeaveBed", + /** 回调函数 */ + listener: ( + /** 下床的玩家对象 */ + player: Player + ) => boolean | void + ): boolean; + + /** 触发死亡信息(不可以拦截) */ + static listen( + /** 事件名 */ + event: "onDeathMessage", + /** 回调函数 */ + listener: ( + /** 死亡信息键名 */ + deathMsgKey: string, + /** 死亡信息翻译参数 */ + deathMsgParams: Array., + /** 死亡实体的实体对象 */ + entity: Entity + ) => void + ): boolean; + + /** 实体受伤后事件 */ + static listen( + /** 事件名 */ + event: "onMobHurted", + /** 回调函数 */ + listener: ( + /** 受伤的实体对象 */ + entity: Entity, + /** 造成伤害的实体对象 */ + source: Entity, + /** 伤害值 */ + damage: number, + /** 伤害类型 */ + cause: number + ) => void + ): boolean; + + /** 末影人搬起方块 */ + static listen( + /** 事件名 */ + event: "onEndermanTake", + /** 回调函数 */ + listener: ( + /** 末影人实体对象 */ + entity: Entity + ) => boolean | void + ): boolean; + + /** 末影龙重生事件 */ + static listen( + /** 事件名 */ + event: "DragonRespawn", + /** 回调函数 */ + listener: ( + /** 末影龙重生后的UniqueID */ + uniqueID: number + ) => boolean | void + ): boolean; + + /** 弹射物实体尝试创建 */ + static listen( + /** 事件名 */ + event: "ProjectileTryCreate", + /** 回调函数 */ + listener: ( + /** 弹射物实体对象 */ + entity: Entity + ) => boolean | void + ): boolean; + + /** 弹射物实体成功后(不可拦截) */ + static listen( + /** 事件名 */ + event: "ProjectileCreate", + /** 回调函数 */ + listener: ( + /** 弹射物实体对象 */ + entity: Entity + ) => void + ): boolean; +} diff --git a/lib/EventAPI-JS.js b/lib/EventAPI-JS.js index 0fc9189..7e2c7ee 100644 --- a/lib/EventAPI-JS.js +++ b/lib/EventAPI-JS.js @@ -1,17 +1,30 @@ +/** 事件创建函数 @type {function(string,string):boolean} */ const CallEvent = ll.import("GMLIB_API", "callCustomEvent"); +/** 事件ID @type {number} */ let NextEventId = 0; +/** + * 获取事件ID标识名 + * @returns {string} 事件ID标识名 + */ function getNextEventId() { NextEventId++; return "GMLIB_Event_" + NextEventId; } +/** 事件类 */ class Event { constructor() { throw new Error("Static class cannot be instantiated"); } + /** + * 监听事件 + * @param {string} event 事件名称 + * @param {function} callback 回调 + * @returns {boolean} 是否创建成功 + */ static listen(event, callback) { let eventId = getNextEventId(); ll.export(callback, event, eventId); diff --git a/lib/GMLIB_API-JS.d.ts b/lib/GMLIB_API-JS.d.ts new file mode 100644 index 0000000..20963e8 --- /dev/null +++ b/lib/GMLIB_API-JS.d.ts @@ -0,0 +1,1140 @@ +/** 静态悬浮字类 */ +declare class StaticFloatingText { + constructor( + /** 生成的坐标 */ + pos: FloatPos, + /** 显示的文本 */ + text: string, + /** 是否启用papi变量 */ + papi: boolean | undefined + ); + + /** 发送悬浮字给玩家 */ + sendToClient( + /** 要发送的玩家对象 */ + player: Player + ): boolean; + + /** 发送悬浮字给所有玩家 */ + sendToClients(): boolean; + + /** 删除玩家的悬浮字 */ + removeFromClient( + /** 要删除的玩家的玩家对象 */ + player: Player + ): boolean; + + /** 删除所有玩家悬浮字 */ + removeFromClients(): boolean; + + /** 更新玩家的悬浮字 */ + updateClient( + player: Player + ): boolean; + + /** 更新所有玩家的悬浮字 */ + updateClients(): boolean; + + /** 获取悬浮字的RuntimeId */ + getRuntimeId(): number; + + /** 获取悬浮字显示的文本 */ + getText(): string; + + /** 设置悬浮字显示的文本 */ + setText( + /** 要显示的文本 */ + text: string + ): void; + + /** 更新所有玩家的悬浮字 */ + update(): boolean; + + /** 更新悬浮字文本 */ + updateText( + /** 要显示的文本 */ + text: string + ): boolean; + + /** 获取悬浮字的坐标 */ + getPos(): FloatPos; + + /** 删除悬浮字 */ + destroy(): boolean + + /** 根据RuntimeId获取静态悬浮字 */ + static getFloatingText( + /** 悬浮字的RuntimeId */ + runtimeId: number + ): StaticFloatingText | null; + + /** 获取所有静态悬浮字 */ + static getAllFloatingTexts(): Array; +} + +/** 动态悬浮字类 */ +declare class DynamicFloatingText extends StaticFloatingText { + constructor( + /** 生成的坐标 */ + pos: FloatPos, + /** 显示的文本 */ + text: string, + /** 更新频率(秒) */ + updateRate: number | undefined, + /** 是否使用PAPI变量 */ + papi: boolean | undefined + ); + + /** 获取悬浮字更新频率 */ + getUpdateRate(): number + + /** 设置悬浮字更新频率 */ + setUpdateRate( + updateRate: number | undefined + ): void; + + /** 开始更新悬浮字 */ + startUpdate(): boolean; + + /** 停止更新悬浮字 */ + stopUpdate(): boolean; + + /** 删除悬浮字 */ + destroy(): boolean; + + /** 根据RuntimeId获取动态悬浮字 */ + static getFloatingText( + /** 悬浮字的RuntimeId */ + runtimeId: number + ): StaticFloatingText | null; + + /** 获取所有动态悬浮字 */ + static getAllFloatingTexts(): Array; +} + +/** 基础游戏API类 */ +declare class Minecraft { + private constructor(); + + /** 获取服务器平均tps */ + static getServerAverageTps(): number; + + /** 获取服务器当前tps */ + static getServerCurrentTps(): number; + + /** 获取服务器mspt */ + static getServerMspt(): number; + + /** 获取所有玩家uuid */ + static getAllPlayerUuids(): Array; + + /** 获取玩家NBT */ + static getPlayerNbt( + /** 玩家uuid */ + uuid: string + ): NbtCompound; + + /** 写入玩家NBT */ + static setPlayerNbt( + /** 玩家uuid */ + uuid: string, + /** 要设置的NBT数据 */ + nbt: NbtCompound, + /** 不存在是否创建 */ + forceCreate: boolean | undefined + ): boolean; + + /** 覆盖玩家NBT的特定Tags */ + static setPlayerNbtTags( + /** 玩家uuid */ + uuid: string, + /** 要设置的NBT数据 */ + nbt: NbtCompound, + /** 要覆盖的NBT标签 */ + tags: string + ): boolean; + + /** 删除玩家NBT */ + static deletePlayerNbt( + /** 玩家uuid */ + uuid: string, + ): boolean; + + /** 获取玩家坐标 */ + static getPlayerPosition( + /** 玩家uuid */ + uuid: string + ): IntPos | null; + + /** 设置玩家坐标 */ + static setPlayerPosition( + /** 玩家uuid */ + uuid: string, + /** 玩家坐标 */ + pos: IntPos + ): boolean; + + /** 获取世界出生点 */ + static getWorldSpawn(): IntPos; + + /** 设置世界出生点 */ + static setWorldSpawn( + /** 要设置的出生点坐标对象 */ + pos: IntPos + ): void; + + /** 启用教育版内容 */ + static setEducationFeatureEnabled(): void; + + /** 注册Ability命令 */ + static registerAbilityCommand(): void; + + /** 启用Xbox成就 */ + static setEnableAchievement(): void; + + /** 信任所有玩家皮肤 */ + static setForceTrustSkins(): void; + + /** 启用资源包双端共存 */ + static enableCoResourcePack(): void; + + /** 获取存档名称 */ + static getWorldName(): string; + + /** 设置存档名称 */ + static setWorldName( + name: string + ): boolean; + + /** 设置假种子 */ + static setFakeSeed( + /** 要设置的假种子 */ + seed: number | undefined + ): void; + + /** 启用错误方块清理 */ + static setUnknownBlockCleaner(): void; + + /** 强制生成实体 */ + static spawnEntity( + /** 生成坐标 */ + pos: FloatPos, + /** 实体命名空间 */ + name: string + ): Entity; + + /** 射弹投射物 */ + static shootProjectile( + /** 实体对象 */ + entity: Entity, + /** 投射物命名空间 */ + proj: string, + /** 速度 */ + speed: number, + /** 偏移量 */ + offset: number + ): boolean; + + /** 投掷实体 */ + static throwEntity( + /** 实体对象 */ + entity: Entity, + /** 被投掷的实体 */ + proj: Entity, + /** 速度 */ + speed: number, + /** 偏移量 */ + offset: number + ): boolean; + + /** 获取服务器使用的语言 */ + static getServerLanguage(): string; + + /** 设置服务器使用的语言 */ + static setServerLanguage( + language: string + ): boolean; + + /** 设置资源包路径 */ + static setCustomPackPath( + /** 要设置的路径 */ + path: string + ): void; + + /** 翻译资源包文本 */ + static resourcePackTranslate( + /** 键名 */ + key: string, + /** 参数 */ + params: string[] | undefined + ): string; + + /** 根据uuid获取玩家对象 */ + static getPlayerFromUuid( + uuid: string + ): Player; + + /** 根据UniqueId获取玩家对象 */ + static getPlayerFromUniqueId( + uniqueId: string + ): Player; + + /** 根据UniqueId获取实体对象 */ + static getEntityFromUniqueId( + uniqueId: string + ): Entity; + + /** 获取方块runtimeId */ + static getBlockRuntimeId( + /** 方块命名空间 */ + block: string, + /** 方块的特殊值 */ + legacyData: Number | undefined + ): number; + + /** 添加虚假列表玩家 */ + static addFakeList( + /** 虚假玩家的名字 */ + name: string, + /** 虚假玩家的xuid */ + xuid: string + ): boolean; + + /** 移除虚假列表玩家 */ + static removeFakeList( + /** 虚假的玩家名字或xuid */ + nameOrXuid: string + ): boolean; + + /** 移除所有虚假列表玩家 */ + static removeAllFakeLists(): boolean; + + /** 启用I18n修复 */ + static setFixI18nEnabled(): void; + + /** 保存NBT至文件 */ + static saveNbtToFile( + /** 文件路径 */ + path: string, + /** NBT对象 */ + nbt: NbtCompound, + /** 是否写入为二进制 */ + isBinary: boolean | undefined + ): boolean; + + /** 从文件读取NBT */ + static readNbtFromFile( + /** 文件路径 */ + path: string, + /** 是否以二进制方式读取 */ + isBinary: boolean | undefined + ): NbtCompound; + + /** 根据命名空间获取翻译键名 */ + static getBlockTranslateKeyFromName( + /** 方块命名空间 */ + name: string + ): string; + + /** 获取存档种子号 */ + static getLevelSeed(): string; + + /** 获取方块亮度 */ + static getBlockLightEmission( + /** 方块的命名空间 */ + block: string, + /** 方块的特殊值 */ + legacyData: number + ): number; + + /** 获取游戏规则列表 */ + static getGameRules(): { Name: string; Value: boolean | number; }[] +} + +/** 合成表类 */ +declare class Recipes { + private constructor(); + + /** 注销合成表 */ + static unregisterRecipe( + /** 合成表唯一标识符 */ + recipeId: string + ): boolean; + + /** 注册切石机合成表 */ + static registerStoneCutterRecipe( + /** 合成表唯一标识符 */ + recipeId: string, + /** 输入物品 */ + inputName: string, + /** 输入物品额外数据 */ + inputAux: number, + /** 合成结果 */ + outputName: string, + /** 合成结果额外数据 */ + outputAux: number, + /** 合成数量 */ + outputCount: number + ): boolean; + + /** 注册锻造纹饰合成表 */ + static registerSmithingTrimRecipe( + /** 合成表唯一标识符 */ + recipeId: string, + /** 锻造模板 */ + template: string, + /** 基础材料 */ + base: string, + /** 纹饰材料 */ + addition: string + ): boolean; + + /** 注册锻造配方合成表 */ + static registerSmithingTransformRecipe( + /** 合成表唯一标识符 */ + recipeId: string, + /** 锻造模板 */ + template: string, + /** 基础材料 */ + base: string, + /** 升级材料 */ + addition: string, + /** 合成结果 */ + result: string + ): boolean; + + /** 注册酿造容器表 */ + static registerBrewingContainerRecipe( + /** 合成表唯一标识符 */ + recipeId: string, + /** 输入物品 */ + input: string, + /** 合成结果 */ + output: string, + /** 酿造物品 */ + reagent: string + ): boolean; + + /** 注册酿造混合表 */ + static registerBrewingMixRecipe( + /** 合成表唯一标识符 */ + recipeId: string, + /** 输入物品 */ + input: string, + /** 合成结果 */ + output: string, + /** 酿造物品 */ + reagent: string + ): boolean; + + /** 注册熔炼合成表 */ + static registerFurnaceRecipe( + /** 合成表唯一标识符 */ + recipeId: string, + /** 输入物品 */ + input: string, + /** 合成结果 */ + output: string, + /** 材料的标签数组 */ + tags: ("furnace" | "blast_furnace" | "smoker" | "campfire" | "soul_campfire")[] | undefined + ): boolean; + + /** 注册有序合成表 */ + static registerShapedRecipe( + /** 合成表唯一标识符 */ + recipeId: string, + /** 合成表摆放方式,数组元素为字符串 */ + shape: [string, string, string], + /** 材料数组 */ + ingredients: string[], + /** 合成结果 */ + result: string, + /** 合成结果的数量 */ + count: number | undefined, + /** 解锁条件(也可以填物品命名空间) */ + unlock: "AlwaysUnlocked" | "PlayerHasManyItems" | "PlayerInWater" | "None" | undefined + ): boolean; + + /** 注册无序合成表 */ + static registerShapelessRecipe( + /** 合成表唯一标识符 */ + recipeId: string, + /** 合成材料 */ + ingredients: string[], + /** 合成结果 */ + result: string, + /** 合成结果的数量 */ + count: number | undefined, + /** 解锁条件(也可以填物品命名空间) */ + unlock: "AlwaysUnlocked" | "PlayerHasManyItems" | "PlayerInWater" | "None" | undefined + ): boolean; +} + +/** 实验性功能类 */ +declare class Experiments { + private constructor(); + + /** 获取所有实验的id */ + static getAllExperimentIds(): number[]; + + /** 获取实验性功能文本的键名 */ + static getExperimentTranslateKey( + /** 实验性功能的id */ + id: number + ): string; + + /** 获取实验性功能启用状态 */ + static getExperimentEnabled( + /** 实验性功能的id */ + id: number + ): boolean; + + /** 设置实验性功能启用状态 */ + static setExperimentEnabled( + /** 实验性功能的id */ + id: number, + /** 实验性功能是否开启 */ + value: boolean | undefined + ): void; + + /** 设置实验性依赖 */ + static registerExperimentsRequire( + /** 实验性功能的id */ + id: number, + ): void +} + +/** 计分板类 */ +declare class Scoreboard { + private constructor(); + + /** 获取所有跟踪实体 */ + static getAllTrackedEntities(): string[]; + + /** 获取所有跟踪的玩家 */ + static getAllTrackedPlayers(): string[]; + + /** 获取所有跟踪的字符串 */ + static getAllTrackedFakePlayers(): string[]; + + /** 获取所有跟踪目标 */ + static getAllTrackedTargets(): ({ Type: "Player"; Uuid: string; } | { Type: "FakePlayer"; Name: string; } | { Type: "Entity"; UniqueId: string; })[] + + /** 创建计分板 */ + static addObjective( + /** 计分板名字 */ + name: string, + /** 显示名称 */ + displayName: string, + ): boolean; + + /** 移除计分板 */ + static removeObjective( + /** 计分板名字 */ + name: string + ): boolean; + + /** 获取所有计分板名字 */ + static getAllObjectives(): string[]; + + /** 获取计分板显示名称 */ + static getDisplayName( + /** 计分板名字 */ + objective: string + ): string; + + /** 设置计分板显示名称 */ + static setDisplayName( + /** 计分板名字 */ + objective: string, + /** 显示名称 */ + displayName: string + ): boolean; + + /** 设置计分板显示 */ + static setDisplay( + /** 计分板名字 */ + objective: string, + /** 显示位置 */ + slot: "sidebar" | "list" | "belowName", + /** 排序方式 */ + order: 0 | 1 + ): void; + + /** 清除计分板显示 */ + static clearDisplay( + /** 计分板名字 */ + objective: string + ): void; + + /** 获取玩家在计分板中的值 */ + static getPlayerScore( + /** 玩家的uuid */ + uuid: string, + /** 计分板名字 */ + objective: string + ): number | null; + + /** 增加玩家在计分板中的值 */ + static addPlayerScore( + /** 玩家的uuid */ + uuid: string, + /** 计分板名字 */ + objective: string, + /** 增加的值 */ + value: number + ): boolean; + + /** 减少玩家在计分板中的值 */ + static reducePlayerScore( + /** 玩家的uuid */ + uuid: string, + /** 计分板名字 */ + objective: string, + /** 减少的值 */ + value: number + ): boolean; + + /** 设置玩家在计分板中的值 */ + static setPlayerScore( + /** 玩家的uuid */ + uuid: string, + /** 计分板名字 */ + objective: string, + /** 设置的值 */ + value: number + ): boolean; + + /** 重载玩家在计分板中的数据 */ + static resetPlayerScore( + /** 玩家的uuid */ + uuid: string, + /** 计分板名字 */ + objective: string + ): boolean; + + /** 重置玩家所有计分板的数据 */ + static resetPlayerScores( + /** 玩家的uuid */ + uuid: string + ): boolean; + + /** 获取字符串在计分板中的值 */ + static getFakePlayerScore( + /** 字符串名字 */ + name: string, + /** 计分板名字 */ + objective: string + ): number | null; + + /** 增加字符串在计分板中的值 */ + static addFakePlayerScore( + /** 字符串名字 */ + name: string, + /** 计分板名字 */ + objective: string, + /** 增加的值 */ + value: number + ): boolean; + + /** 减少字符串在计分板中的值 */ + static reduceFakePlayerScore( + /** 字符串名字 */ + name: string, + /** 计分板名字 */ + objective: string, + /** 减少的值 */ + value: number + ): boolean; + + /** 设置字符串在计分板中的值 */ + static setFakePlayerScore( + /** 字符串名字 */ + name: string, + /** 计分板名字 */ + objective: string, + /** 设置的值 */ + value: number + ): boolean; + + /** 重载字符串在计分板中的数据 */ + static resetFakePlayerScore( + /** 字符串名字 */ + name: string, + /** 计分板名字 */ + objective: string + ): boolean; + + /** 重载字符串所有计分板数据 */ + static resetAllFakePlayerScores( + /** 字符串名字 */ + name: string + ): boolean; + + /** 获取实体在计分板中的值 */ + static getEntityScore( + /** 实体的uniqueId */ + uniqueId: string, + /** 计分板名字 */ + objective: string + ): number | null; + + /** 增加实体在计分板中的值 */ + static addEntityScore( + /** 实体的uniqueId */ + uniqueId: string, + /** 计分板名字 */ + objective: string, + /** 增加的值 */ + value: number + ): boolean; + + /** 减少实体在计分板中的值 */ + static reduceEntityScore( + /** 实体的uniqueId */ + uniqueId: string, + /** 计分板名字 */ + objective: string, + /** 减少的值 */ + value: number + ): boolean; + + /** 设置实体在计分板中的值 */ + static setEntityScore( + /** 实体的uniqueId */ + uniqueId: string, + /** 计分板名字 */ + objective: string, + /** 设置的值 */ + value: number + ): boolean; + + /** 重载实体在计分板中的数据 */ + static resetEntityScore( + /** 实体的uniqueId */ + uniqueId: string, + /** 计分板名字 */ + objective: string + ): boolean; + + /** 重载实体所有计分板数据 */ + static resetAllEntityScores( + /** 实体的uniqueId */ + uniqueId: string + ): boolean; +} + +/** 仿LSE的JsonConfigFile类 */ +declare class JsonConfig { + constructor( + /** 文件路径 */ + path: string, + /** 默认数据 */ + defaultData: object | undefined + ); + + /** 初始化文件 */ + init(): void; + + /** 保存文件 */ + save( + /** 缩进 */ + format: number | undefined + ): void; + + /** 获取所有数据 */ + getData(): object; + + /** 读取数据 */ + get( + /** 键名 */ + key: string, + /** 不存在返回值 */ + defaultValue: any + ): any; + + /** 设置数据 */ + set( + /** 键名 */ + key: string, + /** 值 */ + value: any + ): void; + + /** 删除数据 */ + delete( + /** 键名 */ + key: string + ): void; +} + +declare class JsonLanguage extends JsonConfig { + /** 创建或打开一个 Json 语言文件 */ + constructor( + /** 文件路径 */ + path: string, + /** 默认数据 */ + defaultData: object | undefined + ); + + /** 翻译键名 */ + translate( + /** 键名 */ + key: string, + /** 替换参数 */ + data: string[] + ): string; +} + +declare class JsonI18n { + /** 加载翻译数据目录 */ + constructor( + /** 目录 */ + path: string, + /** 默认语言 */ + localLangCode: string | undefined + ); + + /** 加载所有语言 */ + loadAllLanguage(): void; + + /** 加载语言 */ + loadLanguage( + /** 语言标识符 */ + langCode: string, + /** 默认数据 */ + defaultData: object | undefined + ): void; + + /** 设置语言 */ + chooseLanguage( + /** 语言标识符 */ + langCode: string + ): void; + + /** 设置默认语言 */ + setDefaultLanguage( + /** 语言标识符 */ + langCode: string + ): void; + + /** 翻译键名 */ + translate( + /** 键名 */ + key: string, + /** 替换参数 */ + data: string[], + /** 语言标识符 */ + langCode: string | undefined + ): string; +} + +/** 版本类 */ +declare class Version { + /** 创建版本对象 */ + constructor( + /** 主版本号 */ + major: number, + /** 次版本号 */ + minor: number, + /** 修订版本号 */ + revision: number, + ); + + /** 转换成字符串 */ + toString( + /** 是否添加前缀"v" */ + prefix: boolean | undefined + ): string; + + /** 转换成数组 */ + toArray(): [number, number, number]; + + /** 转换成数字 */ + valueOf(): number; + + /** 从字符串中创建版本对象 */ + static fromString( + /** 字符串 */ + version: string + ): Version; + + /** 从数组中创建版本对象 */ + static fromArray( + /** 数组 */ + version: [number, number, number] + ): Version; + + /** 检测LRCA版本是否大于或等于此版本 */ + static isPluginVersionMatched( + /** 比较版本号 */ + version: Version + ); + + /** 获取LRCA版本对象 */ + static getLrcaVersion(): Version; + + /** 获取GMLIB版本对象 */ + static getGmlibVersion(): Version; +} + +declare class I18nAPI { + private constructor(); + + /** 获取键翻译 */ + static get( + /** 键名 */ + key: string, + /** 翻译参数 */ + params: string[] | undefined, + /** 语言标识符 */ + langCode: string | undefined + ): string; + + /** 获取键翻译 */ + static translate( + /** 键名 */ + key: string, + /** 翻译参数 */ + params: string[] | undefined, + /** 语言标识符 */ + langCode: string | undefined + ): string; + + /** 获取支持的语言标识符 */ + static getSupportedLanguages(): string[]; + + /** 获取资源包默认语言 */ + static getCurrentLanguage(): string; + + /** 设置资源包默认语言 */ + static chooseLanguage( + /** 要设置的语言标识符 */ + language: string + ): void; + + /** 加载语言数据 */ + static loadLanguage( + /** 语言数据 */ + code: string, + /** 语言标识符 */ + language: string + ): void; + + /** 更新或创建语言文件 */ + static updateOrCreateLanguageFile( + /** 语言数据 */ + code: string, + /** 语言标识符 */ + language: string, + /** 文件路径 */ + path: string + ): void; + + /** 加载语言目录 */ + static loadLanguageDirectory( + /** 语言数据目录 */ + path: string + ): void; +} + +declare class UserCache { + private constructor(); + + /** 根据uuid查xuid */ + static getXuidByUuid( + /** uuid */ + uuid: string + ): string; + + /** 根据xuid查uuid */ + static getUuidByXuid( + /** xuid */ + xuid: string + ): string; + + /** 根据xuid查玩家名 */ + static getNameByUuid( + /** xuid */ + xuid: string + ): string; + + /** 根据xuid查玩家名 */ + static getNameByXuid( + /** xuid */ + xuid: string + ): string; + + /** 根据玩家名查xuid */ + static getXuidByName( + /** 玩家名 */ + name: string + ): string; + + /** 根据玩家名查uuid */ + static getUuidByName( + /** 玩家名 */ + name: string + ): string; + + /** 获取玩家信息 */ + static getPlayerInfo( + /** 玩家名 或 xuid 或 uuid */ + playerIdentifier: string + ): { Xuid: String, Uuid: string, Name: string } | null; + + /** 获取所有玩家信息 */ + static getAllPlayerInfo(): { Xuid: String; Uuid: string; Name: string; }[] +} + +interface Player { + /** (GMLIB)转换成实体对象 */ + toEntity(): Entity; + + /** (GMLIB)获取玩家重生坐标 */ + getSpawnPoint(): IntPos; + + /** (GMLIB)设置玩家重生坐标 */ + setSpawnPoint( + /** 要设置的坐标对象 */ + pos: IntPos + ): void; + + /** (GMLIB)清除玩家重生点 */ + clearSpawnPoint(): void; +} + +interface Entity { + /** (GMLIB)射弹投射物 */ + shootProjectile( + /** 投射物命名空间 */ + proj: string, + /** 速度 */ + speed: number | undefined, + /** 偏移量 */ + offset: number | undefined + ): boolean; + + /** (GMLIB)投掷实体 */ + throwEntity( + /** 投掷的实体对象 */ + proj: Entity, + /** 速度 */ + speed: number | undefined, + /** 偏移量 */ + offset: number | undefined + ): boolean; + + /** (GMLIB)获取实体翻译键名 */ + getTranslateKey(): string; + + /** (GMLIB)获取实体名字翻译 */ + getTranslateName( + /** 要翻译的语言 */ + langCode: string + ): string; + + /** (GMLIB)使玩家攻击实体 */ + attack( + /** 攻击的实体对象 */ + entity: Entity + ): boolean; + + /** (GMLIB) */ + pullInEntity( + /** 实体对象 */ + entity: Entity + ): boolean; +} + +interface Block { + /** (GMLIB)获取方块翻译键名 */ + getTranslateKey(): string; + + /** (GMLIB)获取方块名字翻译 */ + getTranslateName( + /** 要翻译的语言 */ + langCode: string + ): string; + + /** (GMLIB)获取方块硬度 */ + getBlockDestroySpeed(): number; + + /** (GMLIB)使方块被玩家挖掘 */ + playerDestroy( + /** 挖掘的玩家对象 */ + player: Player + ): void; + + /** (GMLIB) */ + canDropWithAnyTool(): boolean; + + /** (GMLIB)方块是否不需要工具采集 */ + isAlwaysDestroyable(): boolean; + + /** (GMLIB) */ + playerWillDestroy( + /** 挖掘的玩家对象 */ + player: Player + ): boolean; +} + +interface Item { + /** (GMLIB)获取方块翻译键名 */ + getTranslateKey(): string; + + /** (GMLIB)获取方块名字翻译 */ + getTranslateName( + /** 要翻译的语言 */ + langCode: string + ): string; + + /** (GMLIB)获取物品挖掘方块速度 */ + getDestroyBlockSpeed( + /** 挖掘的方块对象 */ + block: Block + ): number; + + /** (GMLIB)物品冒险模式下是否可以挖掘方块 */ + canDestroy( + /** 挖掘的方块对象 */ + block: Block + ): boolean; + + /** (GMLIB)物品是否能破坏方块 */ + canDestroyInCreative(): boolean; + + /** (GMLIB)物品是否可以采集方块 */ + canDestroySpecial( + /** 挖掘的方块对象 */ + block: Block + ): boolean; + + /** 获取物品可以拥有的附魔 */ + getLegalEnchants(): number[] + + /** 添加附魔 */ + applyEnchant( + /** 附魔ID */ + id: number, + /** 附魔等级 */ + level: number, + /** 允许非原版附魔 */ + allowNonVanilla: boolean | null + ): boolean; + + /** 删除所有附魔 */ + removeEnchants(): void; + + /** 判断是否拥有附魔 */ + hasEnchant( + /** 附魔ID */ + id: number + ): boolean; + + /** 获取附魔等级 */ + getEnchantLevel( + /** 附魔ID */ + id: number + ): number; +} \ No newline at end of file diff --git a/lib/GMLIB_API-JS.js b/lib/GMLIB_API-JS.js index 4abe833..2d8b90a 100644 --- a/lib/GMLIB_API-JS.js +++ b/lib/GMLIB_API-JS.js @@ -1,139 +1,296 @@ +/** LRCA导出接口 */ const GMLIB_API = { + /** 创建悬浮字 @type {function(FloatPos,string,boolean):number} */ createFloatingText: ll.import("GMLIB_API", "createFloatingText"), + /** 删除悬浮字 @type {function(number):boolean} */ deleteFloatingText: ll.import("GMLIB_API", "deleteFloatingText"), + /** 设置悬浮字文本 @type {function(number,string):boolean} */ setFloatingTextData: ll.import("GMLIB_API", "setFloatingTextData"), + /** 发送悬浮字给玩家 @type {function(number,Player):boolean} */ sendFloatingTextToPlayer: ll.import("GMLIB_API", "sendFloatingTextToPlayer"), + /** 发送悬浮字给所有玩家 @type {function(number):boolean} */ sendFloatingText: ll.import("GMLIB_API", "sendFloatingText"), + /** 删除玩家的悬浮字 @type {function(number,Player):boolean} */ removeFloatingTextFromPlayer: ll.import("GMLIB_API", "removeFloatingTextFromPlayer"), + /** 删除所有玩家悬浮字 @type {function(number):boolean} */ removeFloatingText: ll.import("GMLIB_API", "removeFloatingText"), + /** 更新玩家的悬浮字 @type {function(number,Player):boolean} */ updateClientFloatingTextData: ll.import("GMLIB_API", "updateClientFloatingTextData"), + /** 更新所有玩家的悬浮字 @type {function(number):boolean} */ updateAllClientsFloatingTextData: ll.import("GMLIB_API", "updateAllClientsFloatingTextData"), + /** 获取服务器Mspt @type {function():number} */ getServerMspt: ll.import("GMLIB_API", "getServerMspt"), + /** 获取服务器当前tps @type {function():number} */ getServerCurrentTps: ll.import("GMLIB_API", "getServerCurrentTps"), + /** 获取服务器平均tps @type {function():number} */ getServerAverageTps: ll.import("GMLIB_API", "getServerAverageTps"), + /** 获取存档内所有玩家的uuid @type {function():Array} */ getAllPlayerUuids: ll.import("GMLIB_API", "getAllPlayerUuids"), + /** 获取玩家NBT @type {function(string):NbtCompound} */ getPlayerNbt: ll.import("GMLIB_API", "getPlayerNbt"), + /** 设置玩家NBT @type {function(string,NbtCompound,boolean):boolean} */ setPlayerNbt: ll.import("GMLIB_API", "setPlayerNbt"), + /** 覆盖玩家的特定nbtTags @type {function(string,NbtCompound,string):boolean} */ setPlayerNbtTags: ll.import("GMLIB_API", "setPlayerNbtTags"), + /** 删除玩家所有的NBT @type {function(string):boolean} */ deletePlayerNbt: ll.import("GMLIB_API", "deletePlayerNbt"), + /** 使用特定语言翻译资源包文本 @type {function(string,Array.,string):string} */ resourcePackTranslate: ll.import("GMLIB_API", "resourcePackTranslate"), + /** 使用默认语言翻译资源包文本 @type {function(string,Array.):string} */ resourcePackDefaultTranslate: ll.import("GMLIB_API", "resourcePackDefaultTranslate"), + /** 获取资源包默认语言 @type {function():string} */ getResourcePackI18nLanguage: ll.import("GMLIB_API", "getResourcePackI18nLanguage"), + /** 设置资源包默认语言 @type {function(string):void} */ chooseResourcePackI18nLanguage: ll.import("GMLIB_API", "chooseResourcePackI18nLanguage"), + /** 启用教育版内容 @type {function():void} */ setEducationFeatureEnabled: ll.import("GMLib_ServerAPI", "setEducationFeatureEnabled"), + /** 注册Ability命令 @type {function():void} */ registerAbilityCommand: ll.import("GMLib_ServerAPI", "registerAbilityCommand"), + /** 启用Xbox成就 @type {function():void} */ setEnableAchievement: ll.import("GMLib_ServerAPI", "setEnableAchievement"), + /** 信任所有玩家皮肤 @type {function():void} */ setForceTrustSkins: ll.import("GMLib_ServerAPI", "setForceTrustSkins"), + /** 资源包双端共存 @type {function():void} */ enableCoResourcePack: ll.import("GMLib_ServerAPI", "enableCoResourcePack"), + /** 获取存档名字 @type {function():string} */ getLevelName: ll.import("GMLib_ServerAPI", "getLevelName"), + /** 设置存档名字 @type {function(string):boolean} */ setLevelName: ll.import("GMLib_ServerAPI", "setLevelName"), + /** 设置假种子 @type {function(number):void} */ setFakeSeed: ll.import("GMLib_ServerAPI", "setFakeSeed"), + /** 强制生成实体 @type {function(FloatPos,string):Entity} */ spawnEntity: ll.import("GMLib_ServerAPI", "spawnEntity"), + /** 射弹投射物 @type {function(Entity,string,number,number):boolean} */ shootProjectile: ll.import("GMLib_ServerAPI", "shootProjectile"), + /** 投掷实体 @type {function(Entity,Entity,number,number):boolean} */ throwEntity: ll.import("GMLib_ServerAPI", "throwEntity"), + /** 根据玩家对象获取实体对象 @type {function(Player):Entity} */ PlayerToEntity: ll.import("GMLib_ServerAPI", "PlayerToEntity"), + /** 启用错误方块清理 @type {function():void} */ setUnknownBlockCleaner: ll.import("GMLib_ModAPI", "setUnknownBlockCleaner"), + /** 获取实验性功能ID列表 @type {function():Array} */ getAllExperiments: ll.import("GMLIB_API", "getAllExperiments"), + /** 获取实验性功能文本的键名 @type {function(number):string} */ getExperimentTranslateKey: ll.import("GMLIB_API", "getExperimentTranslateKey"), + /** 获取实验性功能启用状态 @type {function(number):boolean} */ getExperimentEnabled: ll.import("GMLib_ModAPI", "getExperimentEnabled"), + /** 设置实验性功能启用状态 @type {function(number,boolean):void} */ setExperimentEnabled: ll.import("GMLib_ModAPI", "setExperimentEnabled"), + /** 注销合成表 @type {function(string):boolean} */ unregisterRecipe: ll.import("GMLIB_API", "unregisterRecipe"), + /** 设置实验性依赖 @type {function(number):void} */ registerExperimentsRequire: ll.import("GMLib_ModAPI", "registerExperimentsRequire"), + /** 注册切石机合成表 @type {function(string,string,number,string,number,number):boolean} */ registerStoneCutterRecipe: ll.import("GMLib_ModAPI", "registerStoneCutterRecipe"), + /** 注册锻造纹饰合成表 @type {function(string,string,string,string):boolean} */ registerSmithingTrimRecipe: ll.import("GMLib_ModAPI", "registerSmithingTrimRecipe"), + /** 注册锻造配方合成表 @type {function(string,string,string,string):boolean} */ registerSmithingTransformRecipe: ll.import("GMLib_ModAPI", "registerSmithingTransformRecipe"), + /** 注册酿造容器表 @type {function(string,string,string,string):boolean} */ registerBrewingContainerRecipe: ll.import("GMLib_ModAPI", "registerBrewingContainerRecipe"), + /** 注册酿造混合表 @type {function(string,string,string,string):boolean} */ registerBrewingMixRecipe: ll.import("GMLib_ModAPI", "registerBrewingMixRecipe"), + /** 注册熔炼合成表 @type {function(string,string,string,Array.):boolean} */ registerFurnaceRecipe: ll.import("GMLib_ModAPI", "registerFurnaceRecipe"), + /** 注册有序合成表 @type {function(string,Array.,Array.,string,number,string)} */ registerShapedRecipe: ll.import("GMLib_ModAPI", "registerShapedRecipe"), + /** 注册无序合成表 @type {function(string,Array.,Array.,string,number,string)} */ registerShapelessRecipe: ll.import("GMLib_ModAPI", "registerShapelessRecipe"), + /** 检测LRCA版本是否大于或等于此版本 @type {function(number,number,number):boolean} */ isVersionMatched: ll.import("GMLIB_API", "isVersionMatched"), + /** 获取LRCA版本 @type {function():string} */ getVersion_LRCA: ll.import("GMLIB_API", "getVersion_LRCA"), + /** 获取GMLIB版本 @type {function():string} */ getVersion_GMLIB: ll.import("GMLIB_API", "getVersion_GMLIB"), + /** 获取玩家坐标 @type {function(string):IntPos} */ getPlayerPosition: ll.import("GMLIB_API", "getPlayerPosition"), + /** 设置玩家坐标 @type {function(string,IntPos):boolean} */ setPlayerPosition: ll.import("GMLIB_API", "setPlayerPosition"), + /** 玩家是否存在于计分板 @type {function(string,string):boolean} */ playerHasScore: ll.import("GMLIB_API", "playerHasScore"), + /** 获取玩家在计分板中的值 @type {function(string,string):number} */ getPlayerScore: ll.import("GMLIB_API", "getPlayerScore"), + /** 增加玩家在计分板中的值 @type {function(string,string,number):boolean} */ addPlayerScore: ll.import("GMLIB_API", "addPlayerScore"), + /** 减少玩家在计分板中的值 @type {function(string,string,number):boolean} */ reducePlayerScore: ll.import("GMLIB_API", "reducePlayerScore"), + /** 设置玩家在计分板中的值 @type {function(string,string,number):boolean} */ setPlayerScore: ll.import("GMLIB_API", "setPlayerScore"), + /** 重置玩家在计分板中的数据 @type {function(string,string):boolean} */ resetPlayerScore: ll.import("GMLIB_API", "resetPlayerScore"), + /** 重置玩家所有的计分板数据 @type {function(string):boolean} */ resetPlayerScores: ll.import("GMLIB_API", "resetPlayerScores"), + /** 实体是否存在于计分板中 @type {function(string,string):boolean} */ entityHasScore: ll.import("GMLIB_API", "entityHasScore"), + /** 获取实体在计分板中的值 @type {function(string,string):number} */ getEntityScore: ll.import("GMLIB_API", "getEntityScore"), + /** 增加实体在计分板中的值 @type {function(string,string,number):boolean} */ addEntityScore: ll.import("GMLIB_API", "addEntityScore"), + /** 减少实体在计分板中的值 @type {function(string,string,number):boolean} */ reduceEntityScore: ll.import("GMLIB_API", "reduceEntityScore"), + /** 设置实体在计分板中的值 @type {function(string,string,number):boolean} */ setEntityScore: ll.import("GMLIB_API", "setEntityScore"), + /** 重置实体在计分板中的数据 @type {function(string,string):boolean} */ resetEntityScore: ll.import("GMLIB_API", "resetEntityScore"), + /** 重置实体所有的计分板数据 @type {function(string):boolean} */ resetEntityScores: ll.import("GMLIB_API", "resetEntityScores"), + /** 字符串是否存在于计分板 @type {function(string,string):boolean} */ fakePlayerHasScore: ll.import("GMLIB_API", "fakePlayerHasScore"), + /** 获取字符串在计分板中的值 @type {function(string,string):number} */ getFakePlayerScore: ll.import("GMLIB_API", "getFakePlayerScore"), + /** 增加字符串在计分板中的值 @type {function(string,string,number):boolean} */ addFakePlayerScore: ll.import("GMLIB_API", "addFakePlayerScore"), + /** 减少字符串在计分板中的值 @type {function(string,string,number):boolean} */ reduceFakePlayerScore: ll.import("GMLIB_API", "reduceFakePlayerScore"), + /** 设置字符串在计分板中的值 @type {function(string,string,number):boolean} */ setFakePlayerScore: ll.import("GMLIB_API", "setFakePlayerScore"), + /** 重置字符串在计分板中的数据 @type {function(string,string):boolean} */ resetFakePlayerScore: ll.import("GMLIB_API", "resetFakePlayerScore"), + /** 重置字符串所有的计分板数据 @type {function(string):boolean} */ resetFakePlayerScores: ll.import("GMLIB_API", "resetFakePlayerScores"), + /** 创建计分板 @type {function(string):boolean} */ addObjective: ll.import("GMLIB_API", "addObjective"), + /** 创建带有显示名称的计分板 @type {function(string,string):boolean} */ addObjectiveWithDisplayName: ll.import("GMLIB_API", "addObjectiveWithDisplayName"), + /** 获取计分板显示名字 @type {function(string):string} */ getDisplayName: ll.import("GMLIB_API", "getDisplayName"), + /** 设置计分板显示名字 @type {function(string,string):boolean} */ setDisplayName: ll.import("GMLIB_API", "setDisplayName"), + /** 删除计分板 @type {function(string):boolean} */ removeObjective: ll.import("GMLIB_API", "removeObjective"), + /** 设置计分板显示 @type {function(string,"list"|"sidebar"|"belowname",0|1):void} */ setDisplayObjective: ll.import("GMLIB_API", "setDisplayObjective"), + /** 清除计分板显示 @type {function("list"|"sidebar"|"belowname"):void} */ clearDisplayObjective: ll.import("GMLIB_API", "clearDisplayObjective"), + /** 获取所有计分板 @type {function():Array.} */ getAllObjectives: ll.import("GMLIB_API", "getAllObjectives"), + /** 获取所有跟踪目标 @type {function():Array.<{"Type":"Player","Uuid":string}|{"Type":"FakePlayer","Name":string}|{"Type":"Entity","UniqueId":string}>} */ getAllTrackedTargets: ll.import("GMLIB_API", "getAllTrackedTargets"), + /** 获取所有跟踪玩家 @type {function():Array.} */ getAllScoreboardPlayers: ll.import("GMLIB_API", "getAllScoreboardPlayers"), + /** 获取所有跟踪字符串 @type {function():Array.} */ getAllScoreboardFakePlayers: ll.import("GMLIB_API", "getAllScoreboardFakePlayers"), + /** 获取所有跟踪实体 @type {function():Array.} */ getAllScoreboardEntities: ll.import("GMLIB_API", "getAllScoreboardEntities"), + /** 根据uuid获取玩家对象 @type {function(string):Player} */ getPlayerFromUuid: ll.import("GMLIB_API", "getPlayerFromUuid"), + /** 根据UniqueId获取玩家对象 @type {function(string):Player} */ getPlayerFromUniqueId: ll.import("GMLIB_API", "getPlayerFromUniqueId"), + /** 根据UniqueId获取实体对象 @type {function(string):Entity} */ getEntityFromUniqueId: ll.import("GMLIB_API", "getEntityFromUniqueId"), + /** 获取世界出生点 @type {function():IntPos} */ getWorldSpawn: ll.import("GMLIB_API", "getWorldSpawn"), + /** 设置世界出生点 @type {function(IntPos):void} */ setWorldSpawn: ll.import("GMLIB_API", "setWorldSpawn"), + /** 获取玩家重生点 @type {function(Player):IntPos} */ getPlayerSpawnPoint: ll.import("GMLIB_API", "getPlayerSpawnPoint"), + /** 设置玩家重生点 @type {function(Player,IntPos):void} */ setPlayerSpawnPoint: ll.import("GMLIB_API", "setPlayerSpawnPoint"), + /** 清除玩家重生点 @type {function(Player):void} */ clearPlayerSpawnPoint: ll.import("GMLIB_API", "clearPlayerSpawnPoint"), + /** 设置资源包路径 @type {function(string):void} */ setCustomPackPath: ll.import("GMLIB_API", "setCustomPackPath"), + /** 获取支持的语言标识符 @type {function():Array.} */ getSupportedLanguages: ll.import("GMLIB_API", "getSupportedLanguages"), + /** 加载语言翻译 @type {function(string,string):void} */ loadLanguage: ll.import("GMLIB_API", "loadLanguage"), + /** 更新或创建语言文件 @type {function(string,string,string):void} */ updateOrCreateLanguageFile: ll.import("GMLIB_API", "updateOrCreateLanguageFile"), + /** 加载语言文件目录 @type {function(string):void} */ loadLanguagePath: ll.import("GMLIB_API", "loadLanguagePath"), + /** 合并json @type {function(string,string):string} */ mergePatchJson: ll.import("GMLIB_API", "mergePatchJson"), + /** 根据uuid获取xuid @type {function(string):string} */ getXuidByUuid: ll.import("GMLIB_API", "getXuidByUuid"), + /** 根据uuid获取名字 @type {function(string):string} */ getNameByUuid: ll.import("GMLIB_API", "getNameByUuid"), + /** 根据xuid获取uuid @type {function(string):string} */ getUuidByXuid: ll.import("GMLIB_API", "getUuidByXuid"), + /** 根据xuid获取名字 @type {function(string):string} */ getNameByXuid: ll.import("GMLIB_API", "getNameByXuid"), + /** 根据名字获取xuid @type {function(string):string} */ getXuidByName: ll.import("GMLIB_API", "getXuidByName"), + /** 根据名字获取uuid @type {function(string):string} */ getUuidByName: ll.import("GMLIB_API", "getUuidByName"), + /** 获取所有已记录的玩家信息 @type {function():Array.<{"Uuid":string,"Xuid":string,"Name":string}>} */ getAllPlayerInfo: ll.import("GMLIB_API", "getAllPlayerInfo"), + /** 获取方块RuntimeId @type {function(string,number):number} */ getBlockRuntimeId: ll.import("GMLIB_API", "getBlockRuntimeId"), + /** 添加虚假列表玩家 @type {function(string,string):boolean} */ addFakeList: ll.import("GMLIB_API", "addFakeList"), + /** 删除虚假列表玩家 @type {function(string):boolean} */ removeFakeList: ll.import("GMLIB_API", "removeFakeList"), + /** 删除所有虚假列表玩家 @type {function():void} */ removeAllFakeLists: ll.import("GMLIB_API", "removeAllFakeList"), + /** 启用I18n修复 @type {function():void} */ setFixI18nEnabled: ll.import("GMLib_ModAPI", "setFixI18nEnabled"), + /** 获取方块翻译键名 @type {function(Block):string} */ getBlockTranslateKey: ll.import("GMLIB_API", "getBlockTranslateKey"), + /** 获取物品翻译键名 @type {function(Item):string} */ getItemTranslateKey: ll.import("GMLIB_API", "getItemTranslateKey"), + /** 获取实体翻译键名 @type {function(Entity):string} */ getEntityTranslateKey: ll.import("GMLIB_API", "getEntityTranslateKey"), + /** 从文件中读取NBT @type {function(string,boolean):NbtCompound} */ readNbtFromFile: ll.import("GMLIB_API", "readNbtFromFile"), + /** 保存NBT至文件 @type {function(string,NbtCompound,boolean):void} */ saveNbtToFile: ll.import("GMLIB_API", "saveNbtToFile"), + /** 获取方块硬度 @type {function(Block):number} */ getBlockDestroySpeed: ll.import("GMLIB_API", "getBlockDestroySpeed"), + /** 获取物品挖掘方块速度 @type {function(Item,Block):number} */ getDestroyBlockSpeed: ll.import("GMLIB_API", "getDestroyBlockSpeed"), + /** 使玩家挖掘方块 @type {function(Block,IntPos,Player):void} */ playerDestroyBlock: ll.import("GMLIB_API", "playerDestroyBlock"), + /** 物品冒险模式下是否可以挖掘方块 @type {function(Item,Block):boolean} */ itemCanDestroyBlock: ll.import("GMLIB_API", "itemCanDestroyBlock"), + /** 物品是否能破坏方块 @type {function(Item):boolean} */ itemCanDestroyInCreative: ll.import("GMLIB_API", "itemCanDestroyInCreative"), + /** 物品是否可以采集方块 @type {function(Item,Block):boolean} */ itemCanDestroySpecial: ll.import("GMLIB_API", "itemCanDestroySpecial"), + /** @type {function(Block):boolean} */ blockCanDropWithAnyTool: ll.import("GMLIB_API", "blockCanDropWithAnyTool"), + /** 方块是否不需要工具采集 @type {function(Block):boolean} */ blockIsAlwaysDestroyable: ll.import("GMLIB_API", "blockIsAlwaysDestroyable"), + /** @type {function(Block,Player,IntPos):boolean} */ blockPlayerWillDestroy: ll.import("GMLIB_API", "blockPlayerWillDestroy"), + /** 使玩家攻击实体 @type {function(Entity,Player):boolean} */ playerAttack: ll.import("GMLIB_API", "playerAttack"), + /** @type {function(Player,Entity):boolean} */ playerPullInEntity: ll.import("GMLIB_API", "playerPullInEntity"), - getBlockTranslateKeyFromName: ll.import("GMLIB_API", "getBlockTranslateKeyFromName") + /** 根据命令空间获取翻译键名 @type {function(string):string} */ + getBlockTranslateKeyFromName: ll.import("GMLIB_API", "getBlockTranslateKeyFromName"), + /** 获取存档种子号 @type {function():string} */ + getLevelSeed: ll.import("GMLib_ServerAPI", "getLevelSeed"), + /** 获取方块亮度 @type {function(string,number):number} */ + getBlockLightEmission: ll.import("GMLIB_API", "getBlockLightEmission"), + /** 获取游戏规则列表 @type {function():Array.<{Name:string,Value:string,Type:"Bool"|"Float"|"Int"}>} */ + getGameRules: ll.import("GMLIB_API", "getGameRules"), + /** 获取物品可以拥有的附魔 @type {function(Item):Array.} */ + getLegalEnchants: ll.import("GMLIB_API", "getLegalEnchants"), + /** 给物品添加附魔 @type {function(Item,number,number,boolean):boolean} */ + applyEnchant: ll.import("GMLIB_API", "applyEnchant"), + /** 删除物品所有附魔 @type {function(Item):void} */ + removeEnchants: ll.import("GMLIB_API", "removeEnchants"), + /** 判断物品是否拥有附魔 @type {function(Item,number):boolean} */ + hasEnchant: ll.import("GMLIB_API", "hasEnchant"), + /** 获取附魔等级 @type {function(Item,number):number} */ + getEnchantLevel: ll.import("GMLIB_API", "getEnchantLevel"), + /** 获取附魔名字 @type {function(number,number):number} */ + getEnchantNameAndLevel: ll.import("GMLIB_API", "getEnchantNameAndLevel") } +/** 静态悬浮字类列表 @type {Map} */ const mStaticFloatingTextMap = new Map(); +/** 动态悬浮字类列表 @type {Map} */ const mDynamicFloatingTextMap = new Map(); +/** 静态悬浮字类 */ class StaticFloatingText { + /** + * 构造函数 + * @param {FloatPos} pos 要生成的坐标 + * @param {string} text 悬浮字文本 + * @param {boolean?} [papi=true] 是否使用PAPI变量 + */ constructor(pos, text, papi = true) { this.mPosition = pos; this.mText = text; @@ -142,61 +299,122 @@ class StaticFloatingText { mStaticFloatingTextMap.set(this.mRuntimeId, this); } + /** + * 发送悬浮字给玩家 + * @param {Player} player 玩家对象 + * @returns {boolean} 是否成功发送 + */ sendToClient(player) { return GMLIB_API.sendFloatingTextToPlayer(this.mRuntimeId, player); } + /** + * 发送悬浮字给所有玩家 + * @returns {boolean} 是否成功发送 + */ sendToClients() { return GMLIB_API.sendFloatingText(this.mRuntimeId); } + /** + * 删除玩家的悬浮字 + * @param {Player} player 玩家对象 + * @returns {boolean} 是否成功删除 + */ removeFromClient(player) { return GMLIB_API.removeFloatingTextFromPlayer(this.mRuntimeId, player); } + /** + * 删除所有玩家悬浮字 + * @returns {boolean} 是否成功删除 + */ removeFromClients() { return GMLIB_API.removeFloatingText(this.mRuntimeId); } + /** + * 更新玩家的悬浮字 + * @param {Player} player 玩家对象 + * @returns {boolean} 是否成功更新 + */ updateClient(player) { return GMLIB_API.updateClientFloatingTextData(this.mRuntimeId, player); } + /** + * 更新所有玩家的悬浮字 + * @returns {boolean} 是否成功更新 + */ updateClients() { return GMLIB_API.updateAllClientsFloatingTextData(this.mRuntimeId); } + /** + * 获取悬浮字的RuntimeId + * @returns {number} 悬浮字的RuntimeId + */ getRuntimeId() { return this.mRuntimeId; } + /** + * 获取悬浮字显示的文本 + * @returns {IntPos} 悬浮字显示的文本 + */ getText() { return this.mText; } + /** + * 设置悬浮字显示的文本 + * @param {string} newText 要显示的文本 + */ setText(newText) { this.mText = newText; } + /** + * 更新所有玩家的悬浮字 + * @returns {boolean} 是否成功更新 + */ update() { GMLIB_API.setFloatingTextData(this.mRuntimeId, this.mText); return this.updateClients(); } + /** + * 更新悬浮字文本 + * @param {string} newText 要显示的文本 + * @returns {boolean} 是否成功更新 + */ updateText(newText) { this.setText(newText); return this.update(); } + /** + * 获取悬浮字的坐标 + * @returns {FlatPos} 悬浮字的坐标 + */ getPos() { return this.mPosition; } + /** + * 删除悬浮字 + * @returns {boolean} 是否成功删除 + */ destroy() { mStaticFloatingTextMap.delete(this.mRuntimeId); return GMLIB_API.deleteFloatingText(this.mRuntimeId); } + /** + * 根据RuntimeId获取静态悬浮字 + * @param {number} runtimeId 悬浮字的RuntimeId + * @returns {StaticFloatingText|null} 悬浮字对象 + */ static getFloatingText(runtimeId) { if (mStaticFloatingTextMap.has(runtimeId)) { return mStaticFloatingTextMap.get(runtimeId); @@ -204,6 +422,10 @@ class StaticFloatingText { return null; } + /** + * 获取所有静态悬浮字 + * @returns {Array} 所有悬浮字对象 + */ static getAllFloatingTexts() { let result = []; mStaticFloatingTextMap.forEach((ft) => { @@ -213,7 +435,15 @@ class StaticFloatingText { } } +/** 动态悬浮字类 */ class DynamicFloatingText extends StaticFloatingText { + /** + * 创建一个动态悬浮字 + * @param {FlatPos} pos 悬浮字的坐标 + * @param {string} text 悬浮字显示的文本 + * @param {number} [updateRate=1] 更新频率(秒) + * @param {boolean} [papi=true] 是否使用PAPI变量 + */ constructor(pos, text, updateRate = 1, papi = true) { this.mPosition = pos; this.mText = text; @@ -225,16 +455,28 @@ class DynamicFloatingText extends StaticFloatingText { this.startUpdate(); } + /** + * 获取悬浮字更新频率 + * @returns {number} 更新频率,单位为秒 + */ getUpdateRate() { return this.mUpdateRate; } + /** + * 设置悬浮字更新频率 + * @param {number} updateRate 更新频率,单位为秒 + */ setUpdateRate(updateRate = 1) { this.stopUpdate(); this.mUpdateRate = updateRate; this.startUpdate(); } + /** + * 开始更新悬浮字 + * @returns {boolean} 是否成功开始更新 + */ startUpdate() { if (this.mTaskId == null) { this.mTaskId = setInterval(() => { @@ -245,6 +487,10 @@ class DynamicFloatingText extends StaticFloatingText { return false; } + /** + * 停止更新悬浮字 + * @returns {boolean} 是否成功停止更新 + */ stopUpdate() { if (this.mTaskId) { clearInterval(this.mTaskId); @@ -254,11 +500,20 @@ class DynamicFloatingText extends StaticFloatingText { return false; } + /** + * 删除悬浮字 + * @returns {boolean} 是否成功删除 + */ destroy() { mDynamicFloatingTextMap.delete(this.mRuntimeId); return GMLIB_API.deleteFloatingText(this.mRuntimeId); } + /** + * 根据runtimeId获取动态悬浮字对象 + * @param {number} runtimeId 悬浮字的RuntimeId + * @returns {DynamicFloatingText} 悬浮字对象 + */ static getFloatingText(runtimeId) { if (mDynamicFloatingTextMap.has(runtimeId)) { return mDynamicFloatingTextMap.get(runtimeId); @@ -266,6 +521,10 @@ class DynamicFloatingText extends StaticFloatingText { return null; } + /** + * 获取所有动态悬浮字 + * @returns {Array} 所有悬浮字对象 + */ static getAllFloatingTexts() { let result = []; mDynamicFloatingTextMap.forEach((ft) => { @@ -275,43 +534,89 @@ class DynamicFloatingText extends StaticFloatingText { } } +/** 基础游戏API类 */ class Minecraft { constructor() { throw new Error("Static class cannot be instantiated"); } + /** + * 获取服务器平均tps + * @returns {number} 服务器平均tps + */ static getServerAverageTps() { return GMLIB_API.getServerAverageTps(); } + /** + * 获取服务器当前tps + * @returns {number} 服务器当前tps + */ static getServerCurrentTps() { return GMLIB_API.getServerCurrentTps(); } + /** + * 获取服务器mspt + * @returns {number} 服务器mspt + */ static getServerMspt() { return GMLIB_API.getServerMspt(); } + /** + * 获取所有玩家uuid + * @returns {Array} 所有玩家uuid + */ static getAllPlayerUuids() { return GMLIB_API.getAllPlayerUuids(); } + /** + * 获取玩家NBT + * @param {string} uuid 玩家的uuid + * @returns {NbtCompound} 玩家的NBT + */ static getPlayerNbt(uuid) { return GMLIB_API.getPlayerNbt(uuid); } + /** + * 写入玩家NBT + * @param {string} uuid 玩家的uuid + * @param {NbtCompound} nbt 要写入的NBT + * @param {boolean?} [forceCreate=true] 不存在是否创建 + * @returns {boolean} 是否成功写入NBT + */ static setPlayerNbt(uuid, nbt, forceCreate = true) { return GMLIB_API.setPlayerNbt(uuid, nbt, forceCreate); } + /** + * 覆盖玩家NBT的特定Tags + * @param {string} uuid 玩家的uuid + * @param {NbtCompound} nbt 要写入的NBT + * @param {string} tags 要覆盖的NBT标签 + * @returns {boolean} 是否成功写入NBT + */ static setPlayerNbtTags(uuid, nbt, tags) { return GMLIB_API.setPlayerNbtTags(uuid, nbt, tags); } + /** + * 删除玩家NBT + * @param {string} uuid 玩家的uuid + * @returns {boolean} 是否成功删除NBT + */ static deletePlayerNbt(uuid) { return GMLIB_API.deletePlayerNbt(uuid); } + /** + * 获取玩家坐标 + * @param {string} uuid 玩家的uuid + * @returns {IntPos|null} 玩家坐标 + */ static getPlayerPosition(uuid) { let pos = GMLIB_API.getPlayerPosition(uuid); if (pos.dimid == -1) { @@ -320,204 +625,508 @@ class Minecraft { return pos; } + /** + * 设置玩家坐标 + * @param {string} uuid 玩家的uuid + * @param {IntPos} pos 要设置的坐标 + * @returns {boolean} 是否成功设置玩家坐标 + */ static setPlayerPosition(uuid, pos) { return GMLIB_API.setPlayerPosition(uuid, pos); } + /** + * 获取世界出生点 + * @returns {IntPos} 世界坐标 + */ static getWorldSpawn() { return GMLIB_API.getWorldSpawn(); } + /** + * 设置世界出生点 + * @param {IntPos} pos 要设置的出生点坐标 + */ static setWorldSpawn(pos) { - return GMLIB_API.setWorldSpawn(pos); + GMLIB_API.setWorldSpawn(pos); } + /** + * 启用教育版内容 + */ static setEducationFeatureEnabled() { - return GMLIB_API.setEducationFeatureEnabled(); + GMLIB_API.setEducationFeatureEnabled(); } + /** + * 注册Ability命令 + */ static registerAbilityCommand() { - return GMLIB_API.registerAbilityCommand(); + GMLIB_API.registerAbilityCommand(); } + /** + * 启用Xbox成就 + */ static setEnableAchievement() { - return GMLIB_API.setEnableAchievement(); + GMLIB_API.setEnableAchievement(); } + /** + * 信任所有玩家皮肤 + */ static setForceTrustSkins() { - return GMLIB_API.setForceTrustSkins(); + GMLIB_API.setForceTrustSkins(); } + /** + * 启用资源包双端共存 + */ static enableCoResourcePack() { - return GMLIB_API.enableCoResourcePack(); + GMLIB_API.enableCoResourcePack(); } + /** + * 获取存档名称 + * @returns {string} 世界名称 + */ static getWorldName() { return GMLIB_API.getLevelName(); } + /** + * 设置存档名称 + * @param {string} name 世界名称 + * @returns {boolean} 是否成功设置世界名称 + */ static setWorldName(name) { return GMLIB_API.setLevelName(name); } + /** + * 设置假种子 + * @param {Number?} [seed=114514] seed 要设置的假种子 + */ static setFakeSeed(seed = 114514) { - return GMLIB_API.setFakeSeed(seed); + GMLIB_API.setFakeSeed(seed); } + /** + * 启用错误方块清理 + */ static setUnknownBlockCleaner() { - return GMLIB_API.setUnknownBlockCleaner(); + GMLIB_API.setUnknownBlockCleaner(); } + /** + * 强制生成实体 + * @param {FloatPos} pos 要生成的坐标 + * @param {string} name 实体命名空间 + * @returns {boolean} 是否成功生成实体 + */ static spawnEntity(pos, name) { return GMLIB_API.spawnEntity(pos, name); } + /** + * 射弹投射物 + * @param {Entity} entity 实体对象 + * @param {string} proj 投射物命名空间 + * @param {number} [speed=2] 速度 + * @param {number} [offset=3] 偏移量 + * @returns {boolean} 是否成功投射投射物 + */ static shootProjectile(entity, proj, speed = 2, offset = 3) { return GMLIB_API.shootProjectile(entity, proj, speed, offset); } + /** + * 投掷实体 + * @param {Entity} entity 实体对象 + * @param {Entity} proj 被投掷的实体 + * @param {number} [speed=2] 速度 + * @param {number} [offset=3] 偏移量 + * @returns {boolean} 是否成功投射投射物 + */ static throwEntity(entity, proj, speed = 2, offset = 3) { return GMLIB_API.throwEntity(entity, proj, speed = 2, offset = 3); } + /** + * 获取服务器使用的语言 + * @returns {string} 服务器使用的语言 + */ static getServerLanguage() { return I18nAPI.getCurrentLanguage(); } + /** + * 设置服务器使用的语言 + * @param {string} language 语言标识符 + * @returns {boolean} 是否成功设置服务器使用的语言 + */ static setServerLanguage(language) { return I18nAPI.chooseLanguage(language); } + /** + * 设置资源包路径 + * @param {string} path 资源包路径 + * @returns {boolean} 是否成功设置资源包路径 + */ static setCustomPackPath(path) { GMLIB_API.setCustomPackPath(path); } + /** + * 翻译资源包文本 + * @param {string} key 键名 + * @param {Array.} params 翻译参数 + * @returns {string} 翻译后的文本 + */ static resourcePackTranslate(key, params = []) { return I18nAPI.get(key, params); } + /** + * 根据uuid获取玩家对象 + * @param {string} uuid 玩家的uuid + * @returns {Player} 玩家对象 + */ static getPlayerFromUuid(uuid) { return GMLIB_API.getPlayerFromUuid(uuid); } + /** + * 根据UniqueId获取玩家对象 + * @param {string} uniqueId 玩家的UniqueId + * @returns {Player} 玩家对象 + */ static getPlayerFromUniqueId(uniqueId) { return GMLIB_API.getPlayerFromUniqueId(uniqueId); } + /** + * 根据UniqueId获取实体对象 + * @param {string} uniqueId 实体的UniqueId + * @returns {Entity} 实体对象 + */ static getEntityFromUniqueId(uniqueId) { - return GMLIB_API.getFromUniqueId(uniqueId); + return GMLIB_API.getEntityFromUniqueId(uniqueId); } - static getBlockRuntimeId(block) { - return GMLIB_API.getBlockRuntimeId(block); + /** + * 获取方块runtimeId + * @param {string} block 方块命名空间 + * @param {number} [legacyData=0] 方块的特殊值 + * @returns {number} 方块的runtimeId + */ + static getBlockRuntimeId(block, legacyData = 0) { + return GMLIB_API.getBlockRuntimeId(block, legacyData); } + /** + * 添加虚假列表玩家 + * @param {string} name 虚假玩家的名字 + * @param {string} xuid 虚假玩家的xuid + * @returns {boolean} 是否成功添加 + */ static addFakeList(name, xuid) { return GMLIB_API.addFakeList(name, xuid); } + /** + * 移除虚假列表玩家 + * @param {string} nameOrXuid 虚假的玩家名字或xuid + * @returns {boolean} 是否成功移除 + */ static removeFakeList(nameOrXuid) { return GMLIB_API.removeFakeList(nameOrXuid); } + /** + * 移除所有虚假列表玩家 + * @returns {boolean} 是否成功移除 + */ static removeAllFakeLists() { return GMLIB_API.removeAllFakeLists(); } + /** + * 启用I18n修复 + */ static setFixI18nEnabled() { GMLIB_API.setFixI18nEnabled(); } + /** + * 保存NBT至文件 + * @param {string} path 文件路径 + * @param {NbtCompound} nbt NBT对象 + * @param {boolean} [isBinary=true] 是否为写入为二进制文件 + * @returns + */ static saveNbtToFile(path, nbt, isBinary = true) { return GMLIB_API.saveNbtToFile(path, nbt, isBinary); } + /** + * 从文件读取NBT + * @param {string} path 文件路径 + * @param {boolean} [isBinary=true] 是否为读取为二进制文件 + * @returns {NbtCompound} NBT对象 + */ static readNbtFromFile(path, isBinary = true) { return GMLIB_API.readNbtFromFile(path, isBinary); } + /** + * 根据命名空间获取翻译键名 + * @param {string} name 方块的命名空间 + * @returns {string} 方块的翻译键名 + */ static getBlockTranslateKeyFromName(name) { return GMLIB_API.getBlockTranslateKeyFromName(name); } + + /** + * 获取存档种子号 + */ + static getLevelSeed() { + return GMLIB_API.getLevelSeed(); + } + + /** + * 获取方块亮度 + * @param {string} block 方块的命名空间 + * @param {number} [legacyData=0] 方块的特殊值 + * @returns {number} 方块的亮度(-1为不存在) + */ + static getBlockLightEmission(block, legacyData = 0) { + return GMLIB_API.getBlockLightEmission(block, legacyData) + } + + /** + * 获取游戏规则列表 + * @returns {Array.<{Name:string,Value:boolean|number}>} + */ + static getGameRules() { + const gameRules = GMLIB_API.getGameRules(); + let result = []; + for (const gameRule of gameRules) { + if (gameRule.Type === "Bool") { + result.push({ + "Name": gameRule.Name, + "Value": gameRule.Value == "1" ? true : false + }); + } else { + result.push({ + "Name": gameRule.Name, + "Value": JSON.parse(gameRule.Value) + }); + } + } + return result; + } + + /** + * 获取附魔名字和等级 + * @param {number} id 附魔ID + * @param {number} level 附魔等级 + * @returns {string} 文本 + */ + static getEnchantNameAndLevel(id, level) { + return GMLIB_API.getEnchantNameAndLevel(id, level); + } } +/** 合成表类 */ class Recipes { constructor() { throw new Error("Static class cannot be instantiated"); } + /** + * 注销合成表 + * @param {string} recipeId 合成表唯一标识符 + * @returns {boolean} 是否注销成功 + */ static unregisterRecipe(recipeId) { return GMLIB_API.unregisterRecipe(recipeId); } + /** + * 注册切石机合成表 + * @param {string} recipeId 合成表唯一标识符 + * @param {string} inputName 输入物品 + * @param {number} inputAux 输入物品额外数据 + * @param {string} outputName 合成结果 + * @param {number} outputAux 合成结果额外数据 + * @param {number} outputCount 合成结果数量 + * @returns {boolean} 是否注册成功 + */ static registerStoneCutterRecipe(recipeId, inputName, inputAux, outputName, outputAux, outputCount) { return GMLIB_API.registerStoneCutterRecipe(recipeId, inputName, inputAux, outputName, outputAux, outputCount); } + /** + * 注册锻造纹饰合成表 + * @param {string} recipeId 合成表唯一标识符 + * @param {string} template 锻造模板 + * @param {string} base 基础材料 + * @param {string} addition 纹饰材料 + * @returns {boolean} 是否注册成功 + */ static registerSmithingTrimRecipe(recipeId, template, base, addition) { return GMLIB_API.registerSmithingTrimRecipe(recipeId, template, base, addition); } + /** + * 注册锻造配方合成表 + * @param {string} recipeId 合成表唯一标识符 + * @param {string} template 锻造模板 + * @param {string} base 基础物品 + * @param {string} addition 升级材料 + * @param {string} result 合成结果 + * @returns {boolean} 是否注册成功 + */ static registerSmithingTransformRecipe(recipeId, template, base, addition, result) { return GMLIB_API.registerSmithingTransformRecipe(recipeId, template, base, addition, result); } + /** + * 注册酿造容器表 + * @param {string} recipeId 合成表唯一标识符 + * @param {string} input 输入物品 + * @param {string} output 合成结果 + * @param {string} reagent 酿造物品 + * @returns {boolean} 是否注册成功 + */ static registerBrewingContainerRecipe(recipeId, input, output, reagent) { return GMLIB_API.registerBrewingContainerRecipe(recipeId, input, output, reagent); } + /** + * 注册酿造混合表 + * @param {string} recipeId 合成表唯一标识 + * @param {string} input 输入物品(必须是原版药水物品id) + * @param {string} output 合成结果(必须是原版药水物品id) + * @param {string} reagent 酿造物品 + * @returns {boolean} 是否注册成功 + */ static registerBrewingMixRecipe(recipeId, input, output, reagent) { return GMLIB_API.registerBrewingMixRecipe(recipeId, input, output, reagent); } - // tags ["furnace", "blast_furnace", "smoker", "campfire", "soul_campfire"] + /** + * 注册熔炼合成表 + * @param {string} recipeId 合成表唯一标识 + * @param {string} input 输入材料 + * @param {string} output 合成结果 + * @param {Array.<"furnace"|"blast_furnace"|"smoker"|"campfire"|"soul_campfire">} [tags=["furnace"]] 材料的标签数组 + * @returns {boolean} 是否注册成功 + */ static registerFurnaceRecipe(recipeId, input, output, tags = ["furnace"]) { return GMLIB_API.registerFurnaceRecipe(recipeId, input, output, tags); } - // unlock : "AlwaysUnlocked", "PlayerHasManyItems", "PlayerInWater", "None", Item ID + /** + * 注册有序合成表 + * @param {string} recipeId 合成表唯一标识 + * @param {[string,string,string]} shape 合成表摆放方式,数组元素为字符串 + * @param {Array.} ingredients 材料数组 + * @param {string} result 合成结果 + * @param {string} [count=1] 合成结果的数量 + * @param {"AlwaysUnlocked"|"PlayerHasManyItems"|"PlayerInWater"|"None"} [unlock=AlwaysUnlocked] 解锁条件(也可以填物品命名空间) + * @returns {boolean} 是否注册成功 + */ static registerShapedRecipe(recipeId, shape, ingredients, result, count = 1, unlock = "AlwaysUnlocked") { return GMLIB_API.registerShapedRecipe(recipeId, shape, ingredients, result, count, unlock); } + /** + * 注册无序合成表 + * @param {string} recipeId 合成表唯一标识 + * @param {Array.} ingredients 合成材料 + * @param {string} result 合成结果 + * @param {number} [count=1] 合成数量 + * @param {"AlwaysUnlocked"|"PlayerHasManyItems"|"PlayerInWater"|"None"} [unlock=AlwaysUnlocked] 解锁条件(也可以填物品命名空间) + * @returns {boolean} 是否注册成功 + */ static registerShapelessRecipe(recipeId, ingredients, result, count = 1, unlock = "AlwaysUnlocked") { return GMLIB_API.registerShapelessRecipe(recipeId, ingredients, result, count, unlock); } } +/** 实验性功能类 */ class Experiments { constructor() { throw new Error("Static class cannot be instantiated"); } + /** + * 获取所有实验的id + * @returns {Array.} 所有实验的id + */ static getAllExperimentIds() { return GMLIB_API.getAllExperiments(); } - + /** + * 获取实验性功能文本的键名 + * @param {number} id 实验性功能的id + * @returns {string} 实验性功能文本的键名 + */ static getExperimentTranslateKey(id) { return GMLIB_API.getExperimentTranslateKey(id); } + /** + * 获取实验性功能启用状态 + * @param {number} id 实验性功能的id + * @returns {boolean} 实验性功能是否开启 + */ static getExperimentEnabled(id) { return GMLIB_API.getExperimentEnabled(id); } + /** + * 设置实验性功能启用状态 + * @param {number} id 实验性功能的id + * @param {boolean?} [value=true] 实验性功能是否开启 + */ static setExperimentEnabled(id, value = true) { - return GMLIB_API.setExperimentEnabled(id, value); + GMLIB_API.setExperimentEnabled(id, value); } + /** + * 设置实验性依赖 + * @param {number} id 实验性功能的id + */ static registerExperimentsRequire(id) { - return GMLIB_API.registerExperimentsRequire(id); + GMLIB_API.registerExperimentsRequire(id); } } +/** 版本类 */ class Version { + /** + * 创建版本对象 + * @param {number} major 主版本号 + * @param {number} minor 次版本号 + * @param {number} patch 修订版本号 + * @constructor + */ constructor(major, minor, patch) { this.mMajor = major; this.mMinor = minor; this.mPatch = patch; } + /** + * 转换成字符串 + * @param {boolean} [prefix=true] 是否添加前缀"v" + * @returns {string} 版本字符串 + */ toString(prefix = true) { let result = `${this.mMajor}.${this.mMinor}.${this.mPatch}`; if (prefix) { @@ -526,16 +1135,29 @@ class Version { return result; } + /** + * 转换成数组 + * @returns {[number,number,number]} 版本数组 + */ toArray() { return [this.mMajor, this.mMinor, this.mPatch]; } + /** + * 转换成数字 + * @returns {number} 版本数字 + */ valueOf() { return 100000000 * this.mMajor + 10000 * this.mMinor + this.mPatch; } + /** + * 从字符串中创建版本对象 + * @param {string} version 版本号字符串 + * @returns {Version|null} 版本对象 + */ static fromString(string) { - if (typeof string === 'string' || string instanceof String) { + if (typeof string === "string" || string instanceof String) { let pattern = /^v?\d+\.\d+\.\d+$/; if (pattern.test(string)) { let regex = /\d+/g; @@ -547,6 +1169,11 @@ class Version { return null; } + /** + * 从数组中创建版本对象 + * @param {[number,number,number]} array 版本号数组 + * @returns {Version|null} 版本对象 + */ static fromArray(array) { if (Array.isArray(array) && array.length == 3) { let isNumber = array.every(element => typeof element == "number"); @@ -557,42 +1184,76 @@ class Version { return null; } + /** + * 检测LRCA版本是否大于或等于此版本 + * @param {Version} version 版本对象 + * @returns {boolean} 检测结果 + */ static isPluginVersionMatched(version) { return GMLIB_API.isVersionMatched(version.mMajor, version.mMinor, version.mPatch); } + /** + * 获取LRCA版本号对象 + * @returns {Version} 版本对象 + */ static getLrcaVersion() { return Version.fromString(GMLIB_API.getVersion_LRCA()); } + /** + * 获取GMLIB版本号对象 + * @returns {Version} 版本对象 + */ static getGmlibVersion() { return Version.fromString(GMLIB_API.getVersion_GMLIB()); } } +/** 计分板类 */ class Scoreboard { constructor() { throw new Error("Static class cannot be instantiated"); } - // Targets + /** + * 获取所有跟踪实体 + * @returns {Array.} 所有跟踪实体 + */ static getAllTrackedEntities() { return GMLIB_API.getAllScoreboardEntities(); } + /** + * 获取所有跟踪玩家 + * @returns {Array.} 所有跟踪玩家 + */ static getAllTrackedPlayers() { return GMLIB_API.getAllScoreboardPlayers(); } + /** + * 获取所有跟踪字符串 + * @returns {Array.} 所有跟踪字符串 + */ static getAllTrackedFakePlayers() { return GMLIB_API.getAllScoreboardFakePlayers(); } + /** + * 获取所有跟踪目标 + * @returns {Array.<{"Type":"Player","Uuid":string}|{"Type":"FakePlayer","Name":string}|{"Type":"Entity","UniqueId":string}>} 所有跟踪目标 + */ static getAllTrackedTargets() { return GMLIB_API.getAllTrackedTargets(); } - // Objectives + /** + * 创建计分板 + * @param {string} name 计分板名字 + * @param {string?} [displayName=""] 显示名称 + * @returns {boolean} 是否创建成功 + */ static addObjective(name, displayName = "") { if (displayName == "") { return GMLIB_API.addObjective(name); @@ -600,31 +1261,66 @@ class Scoreboard { return GMLIB_API.addObjectiveWithDisplayName(name, displayName); } + /** + * 移除计分板 + * @param {string} name 计分板名字 + * @returns {boolean} 是否移除成功 + */ static removeObjective(name) { return GMLIB_API.removeObjective(name); } + /** + * 获取所有计分板名字 + * @returns {Array.} 所有计分板名字列表 + */ static getAllObjectives() { return GMLIB_API.getAllObjectives(); } + /** + * 获取计分板显示名称 + * @param {string} objective 计分板名字 + * @returns {string} 计分板显示名称 + */ static getDisplayName(objective) { return GMLIB_API.getDisplayName(objective); } + /** + * 设置计分板显示名称 + * @param {string} objective 计分板名字 + * @param {string} displayName 显示名称 + * @returns {boolean} 是否设置成功 + */ static setDisplayName(objective, displayName) { return GMLIB_API.setDisplayName(objective, displayName); } + /** + * 设置计分板显示 + * @param {string} objective 计分板名称 + * @param {"list" | "sidebar" | "belowname"} slot 显示位置 + * @param {0|1?} [order=0] 排序方式 + */ static setDisplay(objective, slot, order = 0) { GMLIB_API.setDisplayObjective(objective, slot, order); } + /** + * 清除计分板显示 + * @param {"list" | "sidebar" | "belowname"} slot 清除的显示位置 + */ static clearDisplay(slot) { GMLIB_API.clearDisplayObjective(slot); } - // Player Score + /** + * 获取玩家在计分板中的值 + * @param {string} uuid 玩家的uuid + * @param {string} objective 计分板名称 + * @returns {number?} 计分板值 + */ static getPlayerScore(uuid, objective) { if (GMLIB_API.playerHasScore(uuid, objective)) { return GMLIB_API.getPlayerScore(uuid, objective); @@ -632,27 +1328,64 @@ class Scoreboard { return null; } + /** + * 增加玩家在计分板中的值 + * @param {string} uuid 玩家的uuid + * @param {string} objective 计分板名称 + * @param {number} value 增加的值 + * @returns {boolean} 是否增加成功 + */ static addPlayerScore(uuid, objective, value) { return GMLIB_API.addPlayerScore(uuid, objective, value); } + /** + * 减少玩家在计分板中的值 + * @param {string} uuid 玩家的uuid + * @param {string} objective 计分板名称 + * @param {number} value 减少的值 + * @returns {boolean} 是否减少成功 + */ static reducePlayerScore(uuid, objective, value) { return GMLIB_API.reducePlayerScore(uuid, objective, value); } + /** + * 设置玩家在计分板中的值 + * @param {string} uuid 玩家的uuid + * @param {string} objective 计分板名称 + * @param {number} value 设置的值 + * @returns {boolean} 是否设置成功 + */ static setPlayerScore(uuid, objective, value) { return GMLIB_API.setPlayerScore(uuid, objective, value); } + /** + * 重置玩家在计分板中的数据 + * @param {string} uuid 玩家的uuid + * @param {string} objective 计分板名称 + * @returns {boolean} 是否重置成功 + */ static resetPlayerScore(uuid, objective) { return GMLIB_API.resetPlayerScore(uuid, objective); } + /** + * 重置玩家所有的计分板数据 + * @param {string} uuid 玩家的uuid + * @returns {boolean} 是否重置成功 + */ static resetPlayerScores(uuid) { return GMLIB_API.resetPlayerScores(uuid); } - // FakePlayer Score + /** + * 获取字符串在计分板中的值 + * @param {string} name 字符串名称 + * @param {string} objective 计分板名称 + * @returns {number?} 计分板值 + */ static getFakePlayerScore(name, objective) { if (GMLIB_API.fakePlayerHasScore(name, objective)) { return GMLIB_API.getFakePlayerScore(name, objective); @@ -660,27 +1393,64 @@ class Scoreboard { return null; } + /** + * 增加字符串在计分板中的值 + * @param {string} name 字符串名称 + * @param {string} objective 计分板名称 + * @param {number} value 增加的值 + * @returns {boolean} 是否增加成功 + */ static addFakePlayerScore(name, objective, value) { return GMLIB_API.addFakePlayerScore(name, objective, value); } + /** + * 减少字符串在计分板中的值 + * @param {string} name 字符串名称 + * @param {string} objective 计分板名称 + * @param {number} value 减少的值 + * @returns {boolean} 是否减少成功 + */ static reduceFakePlayerScore(name, objective, value) { return GMLIB_API.reduceFakePlayerScore(name, objective, value); } + /** + * 设置字符串在计分板中的值 + * @param {string} name 字符串名称 + * @param {string} objective 计分板名称 + * @param {number} value 设置的值 + * @returns {boolean} 是否设置成功 + */ static setFakePlayerScore(name, objective, value) { return GMLIB_API.setFakePlayerScore(name, objective, value); } + /** + * 重置字符串在计分板中的数据 + * @param {string} name 字符串名称 + * @param {string} objective 计分板名称 + * @returns {boolean} 是否重置成功 + */ static resetFakePlayerScore(name, objective) { return GMLIB_API.resetFakePlayerScore(name, objective); } + /** + * 重置字符串所有的计分板数据 + * @param {string} name 字符串 + * @returns {boolean} 是否重置成功 + */ static resetFakePlayerScores(name) { return GMLIB_API.resetFakePlayerScores(name); } - // Entity Score + /** + * 获取实体在计分板中的值 + * @param {string} uniqueId 实体的uniqueId + * @param {string} objective 计分板名称 + * @returns {number?} 计分板值 + */ static getEntityScore(uniqueId, objective) { if (GMLIB_API.entityHasScore(uniqueId, objective)) { return GMLIB_API.getEntityScore(uniqueId, objective); @@ -688,35 +1458,76 @@ class Scoreboard { return null; } + /** + * 增加实体在计分板中的值 + * @param {string} uniqueId 实体的uniqueId + * @param {string} objective 计分板名称 + * @param {number} value 增加的值 + * @returns {boolean} 是否增加成功 + */ static addEntityScore(uniqueId, objective, value) { return GMLIB_API.addEntityScore(uniqueId, objective, value); } + /** + * 减少实体在计分板中的值 + * @param {string} uniqueId 实体的uniqueId + * @param {string} objective 计分板名称 + * @param {number} value 减少的值 + * @returns {boolean} 是否减少成功 + */ static reduceEntityScore(uniqueId, objective, value) { return GMLIB_API.reduceEntityScore(uniqueId, objective, value); } + /** + * 设置实体在计分板中的值 + * @param {string} uniqueId 实体的uniqueId + * @param {string} objective 计分板名称 + * @param {number} value 设置的值 + * @returns {boolean} 是否设置成功 + */ static setEntityScore(uniqueId, objective, value) { return GMLIB_API.setEntityScore(uniqueId, objective, value); } + /** + * 重置实体的计分板数据 + * @param {string} uniqueId 实体的uniqueId + * @param {string} objective 计分板名称 + * @returns {boolean} 是否重置成功 + */ static resetEntityScore(uniqueId, objective) { return GMLIB_API.resetEntityScore(uniqueId, objective); } + /** + * 重置实体的所有计分板数据 + * @param {string} uniqueId 实体的uniqueId + * @returns {boolean} 是否重置成功 + */ static resetEntityScores(uniqueId) { return GMLIB_API.resetEntityScores(uniqueId); } - } +/** 仿LSE的JsonConfigFile类 */ class JsonConfig { + /** + * 创建或打开一个 Json 配置文件 + * @param {string} path Json文件的路径 + * @param {object} defultValue 默认数据 + * @constructor + */ constructor(path, defultValue = {}) { this.mData = defultValue; this.mPath = path; this.init(); } + /** + * 初始化Json文件 + */ init() { if (File.exists(this.mPath)) { let existDataStr = File.readFrom(this.mPath); @@ -732,15 +1543,29 @@ class JsonConfig { this.save(); } + /** + * 保存Json文件 + * @param {number} [format=4] 缩进长度 + */ save(format = 4) { let dataStr = JSON.stringify(this.mData, null, format); File.writeTo(this.mPath, dataStr); } + /** + * 获取所有数据 + * @returns {object} 数据 + */ getData() { return this.mData; } + /** + * 读取数据 + * @param {string} key 键名 + * @param {any?} [defultValue=undefined] 不存在时返回值 + * @returns {any} 数据 + */ get(key, defultValue = undefined) { let result = this.getData()[key]; if (!result && defultValue != undefined) { @@ -750,22 +1575,46 @@ class JsonConfig { return result; } + /** + * 设置数据 + * @param {string} key 键名 + * @param {any} value 值 + */ set(key, value) { this.getData()[key] = value; this.save(); } + /** + * 删除数据 + * @param {string} key 键名 + */ delete(key) { delete this.getData()[key]; this.save(); } } +/** + * JSON版语言类 + */ class JsonLanguage extends JsonConfig { + /** + * 创建或打开一个 Json 语言文件 + * @param {string} path Json文件的路径 + * @param {object} defultValue 默认值 + * @constructor + */ constructor(path, defultValue = {}) { super(path, defultValue); } + /** + * 翻译键名 + * @param {string} key 键名 + * @param {Array.} data 翻译参数 + * @returns {string} 翻译结果 + */ translate(key, data = []) { let result = this.get(key); if (result == null) { @@ -773,13 +1622,19 @@ class JsonLanguage extends JsonConfig { } data.forEach((val, index) => { let old = `{${index + 1}}`; - result = result.split(old).join(val); + result = result.split(old).join(val?.toString() ?? ""); }); return result; } } +/** JSON版I18n类 */ class JsonI18n { + /** + * 加载翻译数据目录 + * @param {string} path 目录 + * @param {string?} [localLangCode="en_US"] 默认语言 + */ constructor(path, localLangCode = "en_US") { if (!path.endsWith("/") && !path.endsWith("\\")) { path = path + "/"; @@ -791,6 +1646,9 @@ class JsonI18n { this.loadAllLanguages(); } + /** + * 加载所有语言 + */ loadAllLanguages() { let exist_list = File.getFilesList(this.mPath); exist_list.forEach((name) => { @@ -801,6 +1659,11 @@ class JsonI18n { }); } + /** + * 加载语言 + * @param {string} langCode 语言标识符 + * @param {any?} [defaultData={}] 默认数据 + */ loadLanguage(langCode, defaultData = {}) { let langPath = this.mPath; langPath = langPath + langCode + ".json"; @@ -808,14 +1671,29 @@ class JsonI18n { this.mAllLanguages[langCode] = language; } + /** + * 设置语言 + * @param {string} langCode 语言标识符 + */ chooseLanguage(langCode) { this.mLangCode = langCode; } + /** + * 设置默认语言 + * @param {string} langCode 语言标识符 + */ setDefaultLanguage(langCode) { this.mDefaultLangCode = langCode; } + /** + * 翻译键名 + * @param {string} key 键名 + * @param {Array.?} [data=[]] 翻译参数 + * @param {string?} [langCode=this.mLangCode] 翻译语言 + * @returns {string} 翻译结果 + */ translate(key, data = [], langCode = this.mLangCode) { let language = this.mAllLanguages[langCode]; let result = language.translate(key, data); @@ -829,186 +1707,443 @@ class JsonI18n { } }; +/** I18nAPI类 */ class I18nAPI { constructor() { throw new Error("Static class cannot be instantiated"); } + /** + * 获取键翻译 + * @param {string} key 键名 + * @param {Array.?} params 翻译参数 + * @param {string?} langCode 要翻译的语言 + * @returns {string} 翻译结果 + */ static get(key, params = [], langCode = undefined) { - let data = []; - params.forEach((param) => { - data.push(param); - }); + const data = params.map(item => item?.toString() || ""); if (langCode) { return GMLIB_API.resourcePackTranslate(key, data, langCode); } return GMLIB_API.resourcePackDefaultTranslate(key, data); } + /** + * 获取键翻译 + * @param {string} key 键名 + * @param {Array.?} params 翻译参数 + * @param {string?} langCode 要翻译的语言 + * @returns {string} 翻译结果 + */ static translate(key, params = [], langCode = undefined) { return I18nAPI.get(key, params, langCode); } + /** + * 获取支持的语言标识符 + * @returns {Array.} 语言标识符数组 + */ static getSupportedLanguages() { return GMLIB_API.getSupportedLanguages(); } + /** + * 获取资源包默认语言 + * @returns {string} 语言标识符 + */ static getCurrentLanguage() { - return GMLIB_API.getResourcePackI18nLanguage(language); + return GMLIB_API.getResourcePackI18nLanguage(); } + /** + * 设置资源包默认语言 + * @param {string} language 语言标识符 + */ static chooseLanguage(language) { GMLIB_API.chooseResourcePackI18nLanguage(language); } + /** + * 加载语言数据 + * @param {string} code 语言数据 + * @param {string} language 语言标识符 + */ static loadLanguage(code, language) { GMLIB_API.loadLanguage(code, language); } + /** + * 更新或创建语言文件 + * @param {string} code 语言数据 + * @param {strring} lang 语言标识符 + * @param {string} path 文件路径 + */ static updateOrCreateLanguageFile(code, lang, path) { GMLIB_API.updateOrCreateLanguageFile(code, lang, path); } + /** + * 加载语言目录 + * @param {string} path 文件夹路径 + */ static loadLanguageDirectory(path) { GMLIB_API.loadLanguagePath(path); } }; +/** 玩家数据库API类 */ class UserCache { constructor() { throw new Error("Static class cannot be instantiated"); } + /** + * 根据uuid获取xuid + * @param {string} uuid 玩家uuid + * @returns {string?} xuid + */ static getXuidByUuid(uuid) { let result = GMLIB_API.getXuidByUuid(uuid); return result == "" ? null : result; } + /** + * 根据xuid获取uuid + * @param {string} xuid 玩家xuid + * @returns {string?} uuid + */ static getUuidByXuid(xuid) { let result = GMLIB_API.getUuidByXuid(xuid); return result == "" ? null : result; } + /** + * 根据xuid获取玩家名称 + * @param {string} xuid 玩家xuid + * @returns {string?} 玩家名称 + */ static getNameByUuid(uuid) { let result = GMLIB_API.getNameByUuid(uuid); return result == "" ? null : result; } + /** + * 根据xuid获取玩家名称 + * @param {string} xuid 玩家uuid + * @returns {string?} 玩家名称 + */ static getNameByXuid(xuid) { let result = GMLIB_API.getNameByXuid(xuid); return result == "" ? null : result; } + /** + * 根据名称获取xuid + * @param {string} name 玩家名称 + * @returns {string?} 玩家的xuid + */ static getXuidByName(name) { let result = GMLIB_API.getXuidByName(name); return result == "" ? null : result; } + /** + * 根据名称获取uuid + * @param {string} name 玩家名称 + * @returns {string?} 玩家的uuid + */ static getUuidByName(name) { let result = GMLIB_API.getUuidByName(name); return result == "" ? null : result; } + /** + * 获取玩家信息 + * @param {string} playerIdentifier 玩家的 xuid 或 uuid 或 名称 + * @returns {{Xuid: String, Uuid: string, Name: string}?} 玩家信息 + */ static getPlayerInfo(playerIdentifier) { return GMLIB_API.getAllPlayerInfo().find(Info => Object.keys(Info).some(InfoKey => Info[InfoKey] === playerIdentifier)); } + /** + * 获取所有玩家信息 + * @returns {Array.<{Xuid: String, Uuid: string, Name: string}>} 包含所有玩家信息的数组 + */ static getAllPlayerInfo() { return GMLIB_API.getAllPlayerInfo(); } }; -LLSE_Player.prototype.toEntity = function () { - return GMLIB_API.PlayerToEntity(this); -} - -LLSE_Player.prototype.getSpawnPoint = function () { - return GMLIB_API.getPlayerSpawnPoint(this); -} - -LLSE_Player.prototype.setSpawnPoint = function (pos) { - return GMLIB_API.setPlayerSpawnPoint(this, pos); -} - -LLSE_Player.prototype.clearSpawnPoint = function () { - return GMLIB_API.clearPlayerSpawnPoint(this); -} - -LLSE_Entity.prototype.shootProjectile = function (proj, speed = 2, offset = 3) { - return GMLIB_API.shootProjectile(this, proj, speed, offset); -} - -LLSE_Entity.prototype.throwEntity = function (proj, speed = 2, offset = 3) { - return GMLIB_API.throwEntity(this, proj, speed, offset); -} - -LLSE_Entity.prototype.getTranslateKey = function () { - return GMLIB_API.getEntityTranslateKey(this); -} - -LLSE_Entity.prototype.getTranslateName = function (language) { - return I18nAPI.get(this.getTranslateKey(), [], language); -} - -LLSE_Block.prototype.getTranslateKey = function () { - return GMLIB_API.getBlockTranslateKey(this); -} - -LLSE_Block.prototype.getTranslateName = function (language) { - return I18nAPI.get(this.getTranslateKey(), [], language); -} - -LLSE_Item.prototype.getTranslateKey = function () { - return GMLIB_API.getItemTranslateKey(this); -} - -LLSE_Item.prototype.getTranslateName = function (language) { - return I18nAPI.get(this.getTranslateKey(), [], language); -} - -LLSE_Block.prototype.getBlockDestroySpeed = function () { - return GMLIB_API.getBlockDestroySpeed(this); -} - -LLSE_Item.prototype.getDestroyBlockSpeed = function (block) { - return GMLIB_API.getDestroyBlockSpeed(this, block); -} - -LLSE_Block.prototype.playerDestroy = function (player) { - GMLIB_API.playerDestroyBlock(this, this.pos, player); -} - -LLSE_Item.prototype.canDestroy = function (block) { - return GMLIB_API.itemCanDestroyBlock(this, block); -} - -LLSE_Item.prototype.canDestroyInCreative = function () { - return GMLIB_API.itemCanDestroyInCreative(this); -} - -LLSE_Item.prototype.canDestroySpecial = function (block) { - return GMLIB_API.itemCanDestroySpecial(this, block); -} - -LLSE_Block.prototype.canDropWithAnyTool = function () { - return GMLIB_API.blockCanDropWithAnyTool(this); -} - -LLSE_Block.prototype.isAlwaysDestroyable = function () { - return GMLIB_API.blockIsAlwaysDestroyable(this); -} - -LLSE_Block.prototype.playerWillDestroy = function (player) { - return GMLIB_API.blockPlayerWillDestroy(this, player, this.pos); -} - -LLSE_Player.prototype.attack = function (entity) { - return GMLIB_API.playerAttack(this, entity); -} - -LLSE_Player.prototype.pullInEntity = function (entity) { - return GMLIB_API.playerPullInEntity(this, entity); -} +LLSE_Player.prototype.toEntity = + /** + * 获取实体对象 + * @returns {Entity} 实体对象 + */ + function () { + return GMLIB_API.PlayerToEntity(this); + } + +LLSE_Player.prototype.getSpawnPoint = + /** + * 获取玩家重生坐标 + * @returns {IntPos} 重生坐标对象 + */ + function () { + return GMLIB_API.getPlayerSpawnPoint(this); + } + +LLSE_Player.prototype.setSpawnPoint = + /** + * 设置玩家重生坐标 + * @param {IntPos} pos 坐标对象 + */ + function (pos) { + GMLIB_API.setPlayerSpawnPoint(this, pos); + } + +LLSE_Player.prototype.clearSpawnPoint = + /** + * 清除玩家重生点 + */ + function () { + GMLIB_API.clearPlayerSpawnPoint(this); + } + +LLSE_Entity.prototype.shootProjectile = + /** + * 射弹投射物 + * @param {string} proj 投射物命名空间 + * @param {number} [speed=2] 速度 + * @param {number} [offset=3] 偏移量 + * @returns {boolean} 是射弹投射物 + */ + function (proj, speed = 2, offset = 3) { + return GMLIB_API.shootProjectile(this, proj, speed, offset); + } + +LLSE_Entity.prototype.throwEntity = + /** + * 投掷实体 + * @param {Entity} proj 投掷的实体对象 + * @param {number} [speed=2] 速度 + * @param {number} [offset=3] 偏移量 + * @returns {boolean} 是否投掷成功 + */ + function (proj, speed = 2, offset = 3) { + return GMLIB_API.throwEntity(this, proj, speed, offset); + } + +LLSE_Entity.prototype.getTranslateKey = + /** + * 获取实体翻译键名 + * @returns {string} 翻译键名 + */ + function () { + return GMLIB_API.getEntityTranslateKey(this); + } + +LLSE_Entity.prototype.getTranslateName = + /** + * 获取实体名字翻译 + * @param {string} language 语言标识符 + * @returns {string} 翻译名称 + */ + function (language) { + return I18nAPI.get(this.getTranslateKey(), [], language); + } + +LLSE_Block.prototype.getTranslateKey = + /** + * 获取方块翻译键名 + * @returns {string} 翻译键名 + */ + function () { + return GMLIB_API.getBlockTranslateKey(this); + } + +LLSE_Block.prototype.getTranslateName = + /** + * 获取方块翻译 + * @param {string} language 语言标识符 + * @returns {string} 翻译名称 + */ + function (language) { + return I18nAPI.get(this.getTranslateKey(), [], language); + } + +LLSE_Item.prototype.getTranslateKey = + /** + * 获取物品翻译键名 + * @returns {string} 翻译键名 + */ + function () { + return GMLIB_API.getItemTranslateKey(this); + } + +LLSE_Item.prototype.getTranslateName = + /** + * 获取物品翻译 + * @param {string} language 语言标识符 + * @returns {string} 翻译名称 + */ + function (language) { + return I18nAPI.get(this.getTranslateKey(), [], language); + } + +LLSE_Block.prototype.getBlockDestroySpeed = + /** + * 获取方块硬度 + * @returns {number} 硬度 + */ + function () { + return GMLIB_API.getBlockDestroySpeed(this); + } + +LLSE_Item.prototype.getDestroyBlockSpeed = + /** + * 获取物品挖掘方块速度 + * @param {Block} block 方块对象 + * @returns {number} 挖掘速度 + */ + function (block) { + return GMLIB_API.getDestroyBlockSpeed(this, block); + } + +LLSE_Block.prototype.playerDestroy = + /** + * 使方块被玩家挖掘 + * @param {Player} player 玩家对象 + */ + function (player) { + GMLIB_API.playerDestroyBlock(this, this.pos, player); + } + +LLSE_Item.prototype.canDestroy = + /** + * 物品冒险模式下是否可以挖掘方块 + * @param {Block} block 方块对象 + * @returns {boolean} 物品冒险模式下是否可以挖掘方块 + */ + function (block) { + return GMLIB_API.itemCanDestroyBlock(this, block); + } + +LLSE_Item.prototype.canDestroyInCreative = + /** + * 物品是否能破坏方块 + * @returns {boolean} 是否能破坏方块 + */ + function () { + return GMLIB_API.itemCanDestroyInCreative(this); + } + +LLSE_Item.prototype.canDestroySpecial = + /** + * 物品是否可以采集方块 + * @param {Block} block 方块对象 + * @returns {boolean} 是否可以采集方块 + */ + function (block) { + return GMLIB_API.itemCanDestroySpecial(this, block); + } + +LLSE_Block.prototype.canDropWithAnyTool = + /** + * + * @returns {boolean} + */ + function () { + return GMLIB_API.blockCanDropWithAnyTool(this); + } + +LLSE_Block.prototype.isAlwaysDestroyable = + /** + * 方块是否不需要工具采集 + * @returns {boolean} 方块是否不需要工具采集 + */ + function () { + return GMLIB_API.blockIsAlwaysDestroyable(this); + } + +LLSE_Block.prototype.playerWillDestroy = + /** + * + * @param {Player} player 玩家对象 + * @returns {boolean} + */ + function (player) { + return GMLIB_API.blockPlayerWillDestroy(this, player, this.pos); + } + +LLSE_Player.prototype.attack = + /** + * 使玩家攻击实体 + * @param {Entity} entity 实体对象 + * @returns {boolean} + */ + function (entity) { + return GMLIB_API.playerAttack(this, entity); + } + +LLSE_Player.prototype.pullInEntity = + /** + * + * @param {Entity} entity 实体对象 + * @returns {boolean} + */ + function (entity) { + return GMLIB_API.playerPullInEntity(this, entity); + } + +LLSE_Item.prototype.getLegalEnchants = + /** + * 获取物品可以拥有的合法附魔 + * @returns {Array.} 附魔ID列表 + */ + function () { + return GMLIB_API.getLegalEnchants(this); + } + +LLSE_Item.prototype.applyEnchant = + /** + * 添加附魔 + * @param {number} id 附魔ID + * @param {number} level 等级 + * @param {boolean} allowNonVanilla 允许非原版附魔 + * @returns {boolean} 是否附魔成功 + */ + function (id, level, allowNonVanilla = true) { + return GMLIB_API.applyEnchant(this, id, level, allowNonVanilla); + } + +LLSE_Item.prototype.removeEnchants = + /** + * 删除所有附魔 + */ + function () { + GMLIB_API.removeEnchants(this); + } + +LLSE_Item.prototype.hasEnchant = + /** + * 判断是否拥有附魔 + * @param {number} id 附魔ID + * @returns {boolean} 是否拥有附魔 + */ + function (id) { + return GMLIB_API.hasEnchant(this, id); + } + +LLSE_Item.prototype.getEnchantLevel = + /** + * 获取附魔等级 + * @param {number} id 附魔ID + * @returns {number} 附魔等级 + */ + function (id) { + return GMLIB_API.getEnchantLevel(this, id); + } module.exports = { StaticFloatingText, diff --git a/src/CompatibilityApi.cpp b/src/CompatibilityApi.cpp index e1bed12..b02f3c0 100644 --- a/src/CompatibilityApi.cpp +++ b/src/CompatibilityApi.cpp @@ -599,8 +599,8 @@ void Export_Compatibility_API() { return result; } ); - RemoteCall::exportAs("GMLIB_API", "getBlockRuntimeId", [](std::string const& blockName) -> uint { - if (auto block = Block::tryGetFromRegistry(blockName)) { + RemoteCall::exportAs("GMLIB_API", "getBlockRuntimeId", [](std::string const& blockName, short legacyData) -> uint { + if (auto block = Block::tryGetFromRegistry(blockName, legacyData)) { return block->getRuntimeId(); } return 0; @@ -648,7 +648,10 @@ void Export_Compatibility_API() { return item->canDestroy(block); }); RemoteCall::exportAs("GMLIB_API", "itemCanDestroyInCreative", [](ItemStack const* item) -> bool { - return item->getItem()->canDestroyInCreative(); + if (auto itemDef = item->getItem()) { + return itemDef->canDestroyInCreative(); + } + return false; }); RemoteCall::exportAs("GMLIB_API", "itemCanDestroySpecial", [](ItemStack const* item, Block const* block) -> bool { return item->canDestroySpecial(*block); @@ -678,4 +681,66 @@ void Export_Compatibility_API() { } return "tile.unknown.name"; }); + RemoteCall::exportAs( + "GMLIB_API", + "getBlockLightEmission", + [](std::string const& blockName, short legacyData) -> char { + if (auto block = Block::tryGetFromRegistry(blockName, legacyData)) { + return (char)block->getLightEmission().value; + } + return -1; + } + ); + RemoteCall::exportAs( + "GMLIB_API", + "getGameRules", + []() -> std::vector> { + auto gameRules = ll::service::getLevel()->getGameRules().getRules(); + std::vector> result; + for (auto& gameRule : gameRules) { + std::unordered_map data; + data["Name"] = gameRule.getName(); + switch (gameRule.getType()) { + case GameRule::Type::Bool: + data["Type"] = "Bool"; + data["Value"] = std::to_string(gameRule.getBool()); + break; + case GameRule::Type::Float: + data["Type"] = "Float"; + data["Value"] = std::to_string(gameRule.getFloat()); + break; + case GameRule::Type::Int: + data["Type"] = "Int"; + data["Value"] = std::to_string(gameRule.getInt()); + break; + case GameRule::Type::Invalid: + break; + } + result.push_back(data); + } + return result; + } + ); + RemoteCall::exportAs("GMLIB_API", "getLegalEnchants", [](ItemStack const* item) -> std::vector { + return EnchantUtils::getLegalEnchants(item->getItem()); + }); + RemoteCall::exportAs( + "GMLIB_API", + "applyEnchant", + [](ItemStack const* item, int id, int level, bool allowNonVanilla) -> bool { + return EnchantUtils::applyEnchant((ItemStackBase&)*item, (Enchant::Type)id, level, allowNonVanilla); + } + ); + RemoteCall::exportAs("GMLIB_API", "removeEnchants", [](ItemStack const* item) -> void { + EnchantUtils::removeEnchants((ItemStack&)*item); + }); + RemoteCall::exportAs("GMLIB_API", "hasEnchant", [](ItemStack const* item, int id) -> bool { + return EnchantUtils::hasEnchant((Enchant::Type)id, (ItemStackBase&)*item); + }); + RemoteCall::exportAs("GMLIB_API", "getEnchantLevel", [](ItemStack const* item, int id) -> int { + return EnchantUtils::getEnchantLevel((Enchant::Type)id, (ItemStackBase&)*item); + }); + RemoteCall::exportAs("GMLIB_API", "getEnchantNameAndLevel", [](int id, int level) -> std::string { + return EnchantUtils::getEnchantNameAndLevel((Enchant::Type)id, level); + }); } \ No newline at end of file diff --git a/src/EventAPI.cpp b/src/EventAPI.cpp index d0ea282..bfa03d2 100644 --- a/src/EventAPI.cpp +++ b/src/EventAPI.cpp @@ -7,195 +7,249 @@ void Export_Event_API() { "GMLIB_API", "callCustomEvent", [eventBus](std::string const& eventName, std::string const& eventId) -> bool { - if (RemoteCall::hasFunc(eventName, eventId)) { - switch (doHash(eventName)) { - case doHash("onClientLogin"): { - auto Call = RemoteCall::importAs(eventName, eventId); - eventBus->emplaceListener( - [Call](Event::PacketEvent::ClientLoginAfterEvent& ev) { - try { - Call( - ev.getRealName(), - ev.getUuid().asString(), - ev.getServerAuthXuid(), - ev.getClientAuthXuid() - ); - } catch (...) {} - } - ); - return true; - } - case doHash("onWeatherChange"): { - auto Call = - RemoteCall::importAs( - eventName, - eventId - ); - eventBus->emplaceListener( - [Call](Event::LevelEvent::WeatherUpdateBeforeEvent& ev) { - bool result = true; - try { - result = Call( - ev.getLightningLevel(), - ev.getRainLevel(), - ev.getLightningLastTick(), - ev.getRainingLastTick() - ); - } catch (...) {} - if (!result) { - ev.cancel(); - } - } + if (!RemoteCall::hasFunc(eventName, eventId)) return false; + switch (doHash(eventName)) { + case doHash("onClientLogin"): { + auto Call = RemoteCall::importAs(eventName, eventId); + eventBus->emplaceListener( + [Call](Event::PacketEvent::ClientLoginAfterEvent& ev) { + try { + Call( + ev.getRealName(), + ev.getUuid().asString(), + ev.getServerAuthXuid(), + ev.getClientAuthXuid() + ); + } catch (...) {} + } + ); + return true; + } + case doHash("onWeatherChange"): { + auto Call = + RemoteCall::importAs( + eventName, + eventId ); - return true; - } - case doHash("onMobPick"): { - auto Call = RemoteCall::importAs(eventName, eventId); - eventBus->emplaceListener( - [Call](Event::EntityEvent::MobPickupItemBeforeEvent& ev) { - bool result = true; - try { - result = Call(&ev.self(), (Actor*)&ev.getItemActor()); - } catch (...) {} - if (!result) { - ev.cancel(); - } + eventBus->emplaceListener( + [Call](Event::LevelEvent::WeatherUpdateBeforeEvent& ev) { + bool result = true; + try { + result = Call( + ev.getLightningLevel(), + ev.getRainLevel(), + ev.getLightningLastTick(), + ev.getRainingLastTick() + ); + } catch (...) {} + if (!result) { + ev.cancel(); } - ); - return true; - } - case doHash("onItemTrySpawn"): { - auto Call = RemoteCall::importAs< - bool(const ItemStack* item, std::pair position, Actor* spawner)>(eventName, eventId); - eventBus->emplaceListener( - [Call](Event::EntityEvent::ItemActorSpawnBeforeEvent& ev) { - auto pos = ev.getPosition(); - auto dimid = ev.getBlockSource().getDimensionId().id; - std::pair lsePos = {pos, dimid}; - bool result = true; - try { - result = Call(&ev.getItem(), lsePos, ev.getSpawner()); - } catch (...) {} - if (!result) { - ev.cancel(); - } + } + ); + return true; + } + case doHash("onMobPick"): { + auto Call = RemoteCall::importAs(eventName, eventId); + eventBus->emplaceListener( + [Call](Event::EntityEvent::MobPickupItemBeforeEvent& ev) { + bool result = true; + try { + result = Call(&ev.self(), (Actor*)&ev.getItemActor()); + } catch (...) {} + if (!result) { + ev.cancel(); } - ); - return true; - } - case doHash("onItemSpawned"): { - auto Call = RemoteCall::importAs< - bool(const ItemStack* item, Actor* itemActor, std::pair position, Actor* spawner)>( + } + ); + return true; + } + case doHash("onItemTrySpawn"): { + auto Call = + RemoteCall::importAs position, Actor* spawner)>( eventName, eventId ); - eventBus->emplaceListener( - [Call](Event::EntityEvent::ItemActorSpawnAfterEvent& ev) { - auto pos = ev.getPosition(); - auto dimid = ev.getBlockSource().getDimensionId().id; - std::pair lsePos = {pos, dimid}; - try { - Call(&ev.getItem(), (Actor*)&ev.getItemActor(), lsePos, ev.getSpawner()); - } catch (...) {} + eventBus->emplaceListener( + [Call](Event::EntityEvent::ItemActorSpawnBeforeEvent& ev) { + auto pos = ev.getPosition(); + auto dimid = ev.getBlockSource().getDimensionId().id; + std::pair lsePos = {pos, dimid}; + bool result = true; + try { + result = Call(&ev.getItem(), lsePos, ev.getSpawner()); + } catch (...) {} + if (!result) { + ev.cancel(); } - ); - return true; - } - case doHash("onEntityChangeDim"): { - auto Call = RemoteCall::importAs(eventName, eventId); - eventBus->emplaceListener( - [Call](Event::EntityEvent::ActorChangeDimensionBeforeEvent& ev) { - bool result = true; - try { - result = Call(&ev.self(), ev.getToDimensionId()); - } catch (...) {} - if (!result) { - ev.cancel(); - } - } - ); - return true; - } - case doHash("onLeaveBed"): { - auto Call = RemoteCall::importAs(eventName, eventId); - eventBus->emplaceListener( - [Call](Event::PlayerEvent::PlayerStopSleepBeforeEvent& ev) { - bool result = true; - try { - result = Call(&ev.self()); - } catch (...) {} - if (!result) { - ev.cancel(); - } + } + ); + return true; + } + case doHash("onItemSpawned"): { + auto Call = RemoteCall::importAs< + bool(const ItemStack* item, Actor* itemActor, std::pair position, Actor* spawner)>( + eventName, + eventId + ); + eventBus->emplaceListener( + [Call](Event::EntityEvent::ItemActorSpawnAfterEvent& ev) { + auto pos = ev.getPosition(); + auto dimid = ev.getBlockSource().getDimensionId().id; + std::pair lsePos = {pos, dimid}; + try { + Call(&ev.getItem(), (Actor*)&ev.getItemActor(), lsePos, ev.getSpawner()); + } catch (...) {} + } + ); + return true; + } + case doHash("onEntityChangeDim"): { + auto Call = RemoteCall::importAs(eventName, eventId); + eventBus->emplaceListener( + [Call](Event::EntityEvent::ActorChangeDimensionBeforeEvent& ev) { + bool result = true; + try { + result = Call(&ev.self(), ev.getToDimensionId()); + } catch (...) {} + if (!result) { + ev.cancel(); } - ); - return true; - } - case doHash("onDeathMessage"): { - auto Call = - RemoteCall::importAs, Actor* dead)>( - eventName, - eventId - ); - eventBus->emplaceListener( - [Call](Event::EntityEvent::DeathMessageAfterEvent& ev) { - auto msg = ev.getDeathMessage(); - auto source = ev.getDamageSource(); - try { - Call(msg.first, msg.second, &ev.self()); - } catch (...) {} + } + ); + return true; + } + case doHash("onLeaveBed"): { + auto Call = RemoteCall::importAs(eventName, eventId); + eventBus->emplaceListener( + [Call](Event::PlayerEvent::PlayerStopSleepBeforeEvent& ev) { + bool result = true; + try { + result = Call(&ev.self()); + } catch (...) {} + if (!result) { + ev.cancel(); } - ); - return true; - } - case doHash("onMobHurted"): { - auto Call = RemoteCall::importAs( + } + ); + return true; + } + case doHash("onDeathMessage"): { + auto Call = + RemoteCall::importAs, Actor* dead)>( eventName, eventId ); - eventBus->emplaceListener( - [Call](Event::EntityEvent::MobHurtAfterEvent& ev) { - auto& damageSource = ev.getSource(); - Actor* source = nullptr; - if (damageSource.isEntitySource()) { - auto uniqueId = damageSource.getDamagingEntityUniqueID(); - source = ll::service::getLevel()->fetchEntity(uniqueId); - if (source->getOwner()) { - source = source->getOwner(); - } + eventBus->emplaceListener( + [Call](Event::EntityEvent::DeathMessageAfterEvent& ev) { + auto msg = ev.getDeathMessage(); + auto source = ev.getDamageSource(); + try { + Call(msg.first, msg.second, &ev.self()); + } catch (...) {} + } + ); + return true; + } + case doHash("onMobHurted"): { + auto Call = RemoteCall::importAs( + eventName, + eventId + ); + eventBus->emplaceListener( + [Call](Event::EntityEvent::MobHurtAfterEvent& ev) { + auto& damageSource = ev.getSource(); + Actor* source = nullptr; + if (damageSource.isEntitySource()) { + auto uniqueId = damageSource.getDamagingEntityUniqueID(); + source = ll::service::getLevel()->fetchEntity(uniqueId); + if (source->getOwner()) { + source = source->getOwner(); } - try { - Call(&ev.self(), source, ev.getDamage(), (int)damageSource.getCause()); - } catch (...) {} } - ); - return true; - } - case doHash("onEndermanTake"): { - auto Call = RemoteCall::importAs(eventName, eventId); - eventBus->emplaceListener( - [Call](Event::EntityEvent::EndermanTakeBlockBeforeEvent& ev) { - bool result = true; - try { - result = Call(&ev.self()); - } catch (...) {} - if (!result) { - ev.cancel(); - } + try { + Call(&ev.self(), source, ev.getDamage(), (int)damageSource.getCause()); + } catch (...) {} + } + ); + return true; + } + case doHash("onEndermanTake"): { + auto Call = RemoteCall::importAs(eventName, eventId); + eventBus->emplaceListener( + [Call](Event::EntityEvent::EndermanTakeBlockBeforeEvent& ev) { + bool result = true; + try { + result = Call(&ev.self()); + } catch (...) {} + if (!result) { + ev.cancel(); } - ); - return true; - } - default: - return false; - } + } + ); + return true; + } + case doHash("onEntityChangeDimAfter"): { + auto Call = RemoteCall::importAs(eventName, eventId); + eventBus->emplaceListener( + [Call](Event::EntityEvent::ActorChangeDimensionAfterEvent& ev) { + bool result = true; + try { + result = Call(&ev.self(), ev.getFromDimensionId()); + } catch (...) {} + } + ); + return true; + } + case doHash("DragonRespawn"): { + auto Call = RemoteCall::importAs(eventName, eventId); + eventBus->emplaceListener( + [Call](Event::EntityEvent::DragonRespawnBeforeEvent& ev) { + bool result = true; + try { + result = Call(ev.getEnderDragon().id); + } catch (...) {} + if (!result) { + ev.cancel(); + } + } + ); + return true; + } + case doHash("ProjectileTryCreate"): { + auto Call = RemoteCall::importAs(eventName, eventId); + eventBus->emplaceListener( + [Call](Event::EntityEvent::ProjectileCreateBeforeEvent& ev) { + bool result = true; + try { + result = Call(&ev.self()); + } catch (...) {} + if (!result) { + ev.cancel(); + } + } + ); + return true; + } + case doHash("ProjectileCreate"): { + auto Call = RemoteCall::importAs(eventName, eventId); + eventBus->emplaceListener( + [Call](Event::EntityEvent::ProjectileCreateAfterEvent& ev) { + try { + Call(&ev.self()); + } catch (...) {} + } + ); + return true; + } + default: + return false; } - return false; } ); } \ No newline at end of file From 5afb0f843389dca6a7806624870e8e6ee4bf5cbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=90=E6=B2=90=E5=91=80?= <163636894+zimuya4153@users.noreply.github.com> Date: Wed, 26 Jun 2024 20:28:16 +0800 Subject: [PATCH 02/37] =?UTF-8?q?=E6=96=B0=E5=A2=9E2=E6=8E=A5=E5=8F=A32?= =?UTF-8?q?=E4=BA=8B=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增getMaxPlayers和dropPlayerItem接口 - 新增handleRequestTryAction和handleRequestAction事件 --- lib/EventAPI-JS.d.ts | 34 +++++++++++++++ lib/GMLIB_API-JS.d.ts | 23 +++++++++- lib/GMLIB_API-JS.js | 27 +++++++++++- src/CompatibilityApi.cpp | 5 +++ .../HandleRequestAction.cpp | 41 ++++++++++++++++++ .../HandleRequestAction/HandleRequestAction.h | 28 ++++++++++++ src/EventAPI.cpp | 43 ++++++++++++++++++- src/LegacyServerApi.cpp | 5 +++ 8 files changed, 201 insertions(+), 5 deletions(-) create mode 100644 src/Event/HandleRequestAction/HandleRequestAction.cpp create mode 100644 src/Event/HandleRequestAction/HandleRequestAction.h diff --git a/lib/EventAPI-JS.d.ts b/lib/EventAPI-JS.d.ts index 54af930..615af95 100644 --- a/lib/EventAPI-JS.d.ts +++ b/lib/EventAPI-JS.d.ts @@ -191,4 +191,38 @@ declare class Event2 { entity: Entity ) => void ): boolean; + + /** 尝试物品物品请求 */ + static listen( + /** 事件名 */ + event: "handleRequestTryAction", + /** 回调函数 */ + listener: ( + /** 请求的玩家对象 */ + Player: Player, + /** 请求的操作 */ + actionType: number, + /** 请求的槽位 */ + slot: number, + /** 容器的ID */ + containerNetId: number + ) => boolean | void + ): boolean; + + /** 处理物品请求后(不可拦截) */ + static listen( + /** 事件名 */ + event: "handleRequestAction", + /** 回调函数 */ + listener: ( + /** 请求的玩家对象 */ + Player: Player, + /** 请求的操作 */ + actionType: number, + /** 请求的槽位 */ + slot: number, + /** 容器的ID */ + containerNetId: number + ) => void + ): boolean; } diff --git a/lib/GMLIB_API-JS.d.ts b/lib/GMLIB_API-JS.d.ts index 20963e8..08de70f 100644 --- a/lib/GMLIB_API-JS.d.ts +++ b/lib/GMLIB_API-JS.d.ts @@ -348,7 +348,18 @@ declare class Minecraft { ): number; /** 获取游戏规则列表 */ - static getGameRules(): { Name: string; Value: boolean | number; }[] + static getGameRules(): { Name: string; Value: boolean | number; }[]; + + /** 获取附魔名字和等级 */ + static getEnchantNameAndLevel( + /** 附魔ID */ + id: number, + /** 附魔的等级 */ + level: number + ): string; + + /** 获取最大玩家数 */ + static getMaxPlayers(): number; } /** 合成表类 */ @@ -1002,6 +1013,14 @@ interface Player { /** (GMLIB)清除玩家重生点 */ clearSpawnPoint(): void; + + /** 丢出玩家物品 */ + dropItem( + /** 物品对象 */ + item: Item, + /** 随机丢出位置 */ + randomly: boolean | undefined + ): boolean; } interface Entity { @@ -1072,7 +1091,7 @@ interface Block { /** (GMLIB)方块是否不需要工具采集 */ isAlwaysDestroyable(): boolean; - /** (GMLIB) */ + /** (GMLIB)检测方块是否能被玩家挖掘(比如插件拦截) */ playerWillDestroy( /** 挖掘的玩家对象 */ player: Player diff --git a/lib/GMLIB_API-JS.js b/lib/GMLIB_API-JS.js index 2d8b90a..476b305 100644 --- a/lib/GMLIB_API-JS.js +++ b/lib/GMLIB_API-JS.js @@ -275,7 +275,11 @@ const GMLIB_API = { /** 获取附魔等级 @type {function(Item,number):number} */ getEnchantLevel: ll.import("GMLIB_API", "getEnchantLevel"), /** 获取附魔名字 @type {function(number,number):number} */ - getEnchantNameAndLevel: ll.import("GMLIB_API", "getEnchantNameAndLevel") + getEnchantNameAndLevel: ll.import("GMLIB_API", "getEnchantNameAndLevel"), + /** 获取最大玩家数 @type {function():number} */ + getMaxPlayers:ll.import("GMLIB_ServerAPI","getMaxPlayers"), + /** 丢出玩家背包内物品 @type {function(Player,Item,boolean):boolean} */ + dropPlayerItem:ll.import("GMLIB_API","dropPlayerItem") } /** 静态悬浮字类列表 @type {Map} */ @@ -938,6 +942,14 @@ class Minecraft { static getEnchantNameAndLevel(id, level) { return GMLIB_API.getEnchantNameAndLevel(id, level); } + + /** + * 获取最大玩家数量 + * @returns {number} 最大玩家数量 + */ + static getMaxPlayers(){ + return GMLIB_API.getMaxPlayers(); + } } /** 合成表类 */ @@ -2068,7 +2080,7 @@ LLSE_Block.prototype.isAlwaysDestroyable = LLSE_Block.prototype.playerWillDestroy = /** - * + * 检测方块是否能被玩家挖掘(比如插件拦截) * @param {Player} player 玩家对象 * @returns {boolean} */ @@ -2145,6 +2157,17 @@ LLSE_Item.prototype.getEnchantLevel = return GMLIB_API.getEnchantLevel(this, id); } +LLSE_Player.prototype.dropItem = + /** + * 使玩家丢出物品 + * @param {Item} item 物品对象 + * @param {boolean} [randomly=false] 随机丢出位置 + * @returns {boolean} 是否丢出成功 + */ + function (item, randomly = false) { + return GMLIB_API.dropPlayerItem(this, item, randomly); + } + module.exports = { StaticFloatingText, DynamicFloatingText, diff --git a/src/CompatibilityApi.cpp b/src/CompatibilityApi.cpp index b02f3c0..65241e8 100644 --- a/src/CompatibilityApi.cpp +++ b/src/CompatibilityApi.cpp @@ -743,4 +743,9 @@ void Export_Compatibility_API() { RemoteCall::exportAs("GMLIB_API", "getEnchantNameAndLevel", [](int id, int level) -> std::string { return EnchantUtils::getEnchantNameAndLevel((Enchant::Type)id, level); }); + RemoteCall::exportAs( + "GMLIB_API", + "dropPlayerItem", + [](Player* player, ItemStack const* item, bool randomly) -> bool { return player->drop(*item, randomly); } + ); } \ No newline at end of file diff --git a/src/Event/HandleRequestAction/HandleRequestAction.cpp b/src/Event/HandleRequestAction/HandleRequestAction.cpp new file mode 100644 index 0000000..8073cbd --- /dev/null +++ b/src/Event/HandleRequestAction/HandleRequestAction.cpp @@ -0,0 +1,41 @@ +#include "HandleRequestAction.h" +#include "Global.h" + + +HandleRequestActionBeforeEvent::HandleRequestActionBeforeEvent( + Player* player, + ItemStackRequestAction& requestAction +) +: mPlayer(player), + mRequestAction(requestAction) {} + +Player* HandleRequestActionBeforeEvent::self() const { return mPlayer; } + +ItemStackRequestAction& HandleRequestActionBeforeEvent::getRequestAction() const { return mRequestAction; } + +HandleRequestActionAfterEvent::HandleRequestActionAfterEvent( + Player* player, + ItemStackRequestAction& requestAction +) +: mPlayer(player), + mRequestAction(requestAction) {} + +Player* HandleRequestActionAfterEvent::self() const { return mPlayer; } + +ItemStackRequestAction& HandleRequestActionAfterEvent::getRequestAction() const { return mRequestAction; } + + +LL_AUTO_TYPE_INSTANCE_HOOK( + HandleRequestActionHook, + HookPriority::Normal, + ItemStackRequestActionHandler, + "?handleRequestAction@ItemStackRequestActionHandler@@QEAA?AW4ItemStackNetResult@@AEBVItemStackRequestAction@@@Z", + void, + ItemStackRequestAction& requestAction +) { + auto beforeEvent = HandleRequestActionBeforeEvent(((Player*)(*(__int64*)this)), requestAction); + ll::event::EventBus::getInstance().publish(beforeEvent); + if (beforeEvent.isCancelled()) return; + ll::event::EventBus::getInstance().publish(HandleRequestActionAfterEvent(((Player*)(*(__int64*)this)), requestAction)); + return origin(requestAction); +} \ No newline at end of file diff --git a/src/Event/HandleRequestAction/HandleRequestAction.h b/src/Event/HandleRequestAction/HandleRequestAction.h new file mode 100644 index 0000000..89922c8 --- /dev/null +++ b/src/Event/HandleRequestAction/HandleRequestAction.h @@ -0,0 +1,28 @@ +#include "Global.h" +#include "ll/api/event/Cancellable.h" + +class HandleRequestActionBeforeEvent final : public ll::event::Cancellable { +private: + Player* mPlayer{}; + ItemStackRequestAction& mRequestAction; + +public: + HandleRequestActionBeforeEvent(Player* player, ItemStackRequestAction& requestAction); + + Player* self() const; + + ItemStackRequestAction& getRequestAction() const; +}; + +class HandleRequestActionAfterEvent final : public ll::event::Event { +private: + Player* mPlayer; + ItemStackRequestAction& mRequestAction; + +public: + HandleRequestActionAfterEvent(Player* player, ItemStackRequestAction& requestAction); + + Player* self() const; + + ItemStackRequestAction& getRequestAction() const; +}; \ No newline at end of file diff --git a/src/EventAPI.cpp b/src/EventAPI.cpp index bfa03d2..685021f 100644 --- a/src/EventAPI.cpp +++ b/src/EventAPI.cpp @@ -1,4 +1,5 @@ #include "Global.h" +#include "Event/HandleRequestAction/HandleRequestAction.h" using namespace ll::hash_utils; void Export_Event_API() { @@ -234,7 +235,7 @@ void Export_Event_API() { } } ); - return true; + return true; } case doHash("ProjectileCreate"): { auto Call = RemoteCall::importAs(eventName, eventId); @@ -247,6 +248,46 @@ void Export_Event_API() { ); return true; } + case doHash("handleRequestTryAction"): { + auto Call = + RemoteCall::importAs( + eventName, + eventId + ); + eventBus->emplaceListener([Call](HandleRequestActionBeforeEvent& ev) { + bool result = true; + try { + result = Call( + ev.self(), + (int)ev.getRequestAction().getActionType(), + (int)ev.getRequestAction().getSrc().mSlot, + (int)ev.getRequestAction().getSrc().mOpenContainerNetId + ); + } catch (...) {} + if (!result) { + ev.cancel(); + } + }); + return true; + } + case doHash("handleRequestAction"): { + auto Call = + RemoteCall::importAs( + eventName, + eventId + ); + eventBus->emplaceListener([Call](HandleRequestActionAfterEvent& ev) { + try { + Call( + ev.self(), + (int)ev.getRequestAction().getActionType(), + (int)ev.getRequestAction().getSrc().mSlot, + (int)ev.getRequestAction().getSrc().mOpenContainerNetId + ); + } catch (...) {} + }); + return true; + } default: return false; } diff --git a/src/LegacyServerApi.cpp b/src/LegacyServerApi.cpp index d3fb494..6a2dd50 100644 --- a/src/LegacyServerApi.cpp +++ b/src/LegacyServerApi.cpp @@ -1,6 +1,8 @@ #include "GMLIB/Server/FakeListAPI.h" +#include "GMLIB/Server/LevelAPI.h" #include "Global.h" #include "mc/world/ActorUniqueID.h" +#include void Export_Legacy_GMLib_ServerAPI() { RemoteCall::exportAs("GMLib_ServerAPI", "setEducationFeatureEnabled", []() -> void { @@ -73,4 +75,7 @@ void Export_Legacy_GMLib_ServerAPI() { RemoteCall::exportAs("GMLib_ServerAPI", "removeAllFakeList", []() -> void { return FakeList::removeAllFakeLists(); }); + RemoteCall::exportAs("GMLib_ServerAPI", "getMaxPlayers", []() -> int { + return ll::memory::dAccess(ll::service::getServerNetworkHandler().as_ptr(), 200); + }); } From a7f5ad26ac89063359c258a86ab4d1cf1ef99d32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=90=E6=B2=90=E5=91=80?= <163636894+zimuya4153@users.noreply.github.com> Date: Wed, 26 Jun 2024 23:57:36 +0800 Subject: [PATCH 03/37] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E8=A1=A5=E5=85=A8?= =?UTF-8?q?=E7=B1=BB=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/EventAPI-JS.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/EventAPI-JS.d.ts b/lib/EventAPI-JS.d.ts index 615af95..1234a35 100644 --- a/lib/EventAPI-JS.d.ts +++ b/lib/EventAPI-JS.d.ts @@ -1,7 +1,7 @@ /// /** 事件监听接口 */ -declare class Event2 { +declare class Event { /** 生物捡起物品 */ static listen( /** 事件名 */ From d78a63044b368098df3d06ffb2dde160e8270f17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=90=E6=B2=90=E5=91=80?= <163636894+zimuya4153@users.noreply.github.com> Date: Thu, 27 Jun 2024 04:13:17 +0800 Subject: [PATCH 04/37] =?UTF-8?q?=E5=88=A0=E9=99=A4=E5=92=8C=E4=BF=AE?= =?UTF-8?q?=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 删除新增的handleRequestTryAction事件和handleRequestAction事件 有关附魔接口均改采用命名空间 新增id转命名空间接口 修正获取最大玩家数代码 --- lib/EventAPI-JS.d.ts | 34 ------------ lib/GMLIB_API-JS.d.ts | 24 +++++---- lib/GMLIB_API-JS.js | 54 +++++++++++-------- src/CompatibilityApi.cpp | 46 ++++++++++++---- .../HandleRequestAction.cpp | 41 -------------- .../HandleRequestAction/HandleRequestAction.h | 28 ---------- src/EventAPI.cpp | 41 -------------- src/LegacyServerApi.cpp | 9 ++-- 8 files changed, 87 insertions(+), 190 deletions(-) delete mode 100644 src/Event/HandleRequestAction/HandleRequestAction.cpp delete mode 100644 src/Event/HandleRequestAction/HandleRequestAction.h diff --git a/lib/EventAPI-JS.d.ts b/lib/EventAPI-JS.d.ts index 1234a35..7cbaa7f 100644 --- a/lib/EventAPI-JS.d.ts +++ b/lib/EventAPI-JS.d.ts @@ -191,38 +191,4 @@ declare class Event { entity: Entity ) => void ): boolean; - - /** 尝试物品物品请求 */ - static listen( - /** 事件名 */ - event: "handleRequestTryAction", - /** 回调函数 */ - listener: ( - /** 请求的玩家对象 */ - Player: Player, - /** 请求的操作 */ - actionType: number, - /** 请求的槽位 */ - slot: number, - /** 容器的ID */ - containerNetId: number - ) => boolean | void - ): boolean; - - /** 处理物品请求后(不可拦截) */ - static listen( - /** 事件名 */ - event: "handleRequestAction", - /** 回调函数 */ - listener: ( - /** 请求的玩家对象 */ - Player: Player, - /** 请求的操作 */ - actionType: number, - /** 请求的槽位 */ - slot: number, - /** 容器的ID */ - containerNetId: number - ) => void - ): boolean; } diff --git a/lib/GMLIB_API-JS.d.ts b/lib/GMLIB_API-JS.d.ts index 08de70f..9c9d0d8 100644 --- a/lib/GMLIB_API-JS.d.ts +++ b/lib/GMLIB_API-JS.d.ts @@ -352,12 +352,18 @@ declare class Minecraft { /** 获取附魔名字和等级 */ static getEnchantNameAndLevel( - /** 附魔ID */ - id: number, + /** 附魔命名空间 */ + typeName: string, /** 附魔的等级 */ level: number ): string; + /** 通过附魔ID获取附魔命名空间 */ + static getMaxPlayers( + /** 附魔ID */ + id: number + ): string | null; + /** 获取最大玩家数 */ static getMaxPlayers(): number; } @@ -1130,12 +1136,12 @@ interface Item { ): boolean; /** 获取物品可以拥有的附魔 */ - getLegalEnchants(): number[] + getLegalEnchants(): string[] /** 添加附魔 */ applyEnchant( - /** 附魔ID */ - id: number, + /** 附魔的命名空间 */ + typeName: string, /** 附魔等级 */ level: number, /** 允许非原版附魔 */ @@ -1147,13 +1153,13 @@ interface Item { /** 判断是否拥有附魔 */ hasEnchant( - /** 附魔ID */ - id: number + /** 附魔的命名空间 */ + typeName: string ): boolean; /** 获取附魔等级 */ getEnchantLevel( - /** 附魔ID */ - id: number + /** 附魔的命名空间 */ + typeName: string ): number; } \ No newline at end of file diff --git a/lib/GMLIB_API-JS.js b/lib/GMLIB_API-JS.js index 476b305..e71f69f 100644 --- a/lib/GMLIB_API-JS.js +++ b/lib/GMLIB_API-JS.js @@ -264,22 +264,24 @@ const GMLIB_API = { getBlockLightEmission: ll.import("GMLIB_API", "getBlockLightEmission"), /** 获取游戏规则列表 @type {function():Array.<{Name:string,Value:string,Type:"Bool"|"Float"|"Int"}>} */ getGameRules: ll.import("GMLIB_API", "getGameRules"), - /** 获取物品可以拥有的附魔 @type {function(Item):Array.} */ + /** 获取物品可以拥有的附魔 @type {function(Item):Array.} */ getLegalEnchants: ll.import("GMLIB_API", "getLegalEnchants"), - /** 给物品添加附魔 @type {function(Item,number,number,boolean):boolean} */ + /** 给物品添加附魔 @type {function(Item,string,number,boolean):boolean} */ applyEnchant: ll.import("GMLIB_API", "applyEnchant"), /** 删除物品所有附魔 @type {function(Item):void} */ removeEnchants: ll.import("GMLIB_API", "removeEnchants"), - /** 判断物品是否拥有附魔 @type {function(Item,number):boolean} */ + /** 判断物品是否拥有附魔 @type {function(Item,string):boolean} */ hasEnchant: ll.import("GMLIB_API", "hasEnchant"), - /** 获取附魔等级 @type {function(Item,number):number} */ + /** 获取附魔等级 @type {function(Item,string):number} */ getEnchantLevel: ll.import("GMLIB_API", "getEnchantLevel"), - /** 获取附魔名字 @type {function(number,number):number} */ + /** 获取附魔名字 @type {function(string,number):number} */ getEnchantNameAndLevel: ll.import("GMLIB_API", "getEnchantNameAndLevel"), + /** 通过ID获取附魔命名空间 @type {function(number):string} */ + getEnchantTypeNameFromId: ll.import("GMLIB_API", "getEnchantTypeNameFromId"), /** 获取最大玩家数 @type {function():number} */ - getMaxPlayers:ll.import("GMLIB_ServerAPI","getMaxPlayers"), + getMaxPlayers: ll.import("GMLib_ServerAPI", "getMaxPlayers"), /** 丢出玩家背包内物品 @type {function(Player,Item,boolean):boolean} */ - dropPlayerItem:ll.import("GMLIB_API","dropPlayerItem") + dropPlayerItem: ll.import("GMLIB_API", "dropPlayerItem") } /** 静态悬浮字类列表 @type {Map} */ @@ -935,19 +937,29 @@ class Minecraft { /** * 获取附魔名字和等级 - * @param {number} id 附魔ID + * @param {string} typeName 附魔的命名空间 * @param {number} level 附魔等级 * @returns {string} 文本 */ - static getEnchantNameAndLevel(id, level) { - return GMLIB_API.getEnchantNameAndLevel(id, level); + static getEnchantNameAndLevel(typeName, level) { + return GMLIB_API.getEnchantNameAndLevel(typeName, level); + } + + /** + * 通过附魔ID获取附魔命名空间 + * @param {number} id 附魔ID + * @returns {string?} 附魔的命名空间 + */ + static getEnchantTypeNameFromId(id) { + const result = GMLIB_API.getEnchantTypeNameFromId(id); + return result === "" ? null : result; } /** * 获取最大玩家数量 * @returns {number} 最大玩家数量 */ - static getMaxPlayers(){ + static getMaxPlayers() { return GMLIB_API.getMaxPlayers(); } } @@ -2111,7 +2123,7 @@ LLSE_Player.prototype.pullInEntity = LLSE_Item.prototype.getLegalEnchants = /** * 获取物品可以拥有的合法附魔 - * @returns {Array.} 附魔ID列表 + * @returns {Array.} 附魔ID列表 */ function () { return GMLIB_API.getLegalEnchants(this); @@ -2120,13 +2132,13 @@ LLSE_Item.prototype.getLegalEnchants = LLSE_Item.prototype.applyEnchant = /** * 添加附魔 - * @param {number} id 附魔ID + * @param {string} typeName 附魔的命名空间 * @param {number} level 等级 * @param {boolean} allowNonVanilla 允许非原版附魔 * @returns {boolean} 是否附魔成功 */ - function (id, level, allowNonVanilla = true) { - return GMLIB_API.applyEnchant(this, id, level, allowNonVanilla); + function (typeName, level, allowNonVanilla = true) { + return GMLIB_API.applyEnchant(this, typeName, level, allowNonVanilla); } LLSE_Item.prototype.removeEnchants = @@ -2140,21 +2152,21 @@ LLSE_Item.prototype.removeEnchants = LLSE_Item.prototype.hasEnchant = /** * 判断是否拥有附魔 - * @param {number} id 附魔ID + * @param {number} typeName 附魔的命名空间 * @returns {boolean} 是否拥有附魔 */ - function (id) { - return GMLIB_API.hasEnchant(this, id); + function (typeName) { + return GMLIB_API.hasEnchant(this, typeName); } LLSE_Item.prototype.getEnchantLevel = /** * 获取附魔等级 - * @param {number} id 附魔ID + * @param {number} typeName 附魔ID * @returns {number} 附魔等级 */ - function (id) { - return GMLIB_API.getEnchantLevel(this, id); + function (typeName) { + return GMLIB_API.getEnchantLevel(this, typeName); } LLSE_Player.prototype.dropItem = diff --git a/src/CompatibilityApi.cpp b/src/CompatibilityApi.cpp index 65241e8..df6e229 100644 --- a/src/CompatibilityApi.cpp +++ b/src/CompatibilityApi.cpp @@ -1,4 +1,5 @@ #include "Global.h" +#include "mc/deps/core/string/HashedString.h" #include bool isInteger(const std::string& str) { @@ -721,28 +722,51 @@ void Export_Compatibility_API() { return result; } ); - RemoteCall::exportAs("GMLIB_API", "getLegalEnchants", [](ItemStack const* item) -> std::vector { - return EnchantUtils::getLegalEnchants(item->getItem()); + RemoteCall::exportAs("GMLIB_API", "getLegalEnchants", [](ItemStack const* item) -> std::vector { + std::vector enchants = EnchantUtils::getLegalEnchants(item->getItem()); + std::vector result; + for (auto& enchant : enchants) { + result.push_back(Enchant::getEnchant((Enchant::Type)enchant)->getStringId()); + } + return result; + }); + RemoteCall::exportAs("GMLIB_API", "getEnchantTypeNameFromId", [](int id) -> std::string { + if (auto enchant = Enchant::getEnchant((Enchant::Type)id)) { + return enchant->getStringId(); + } + return ""; }); RemoteCall::exportAs( "GMLIB_API", "applyEnchant", - [](ItemStack const* item, int id, int level, bool allowNonVanilla) -> bool { - return EnchantUtils::applyEnchant((ItemStackBase&)*item, (Enchant::Type)id, level, allowNonVanilla); + [](ItemStack const* item, std::string const& typeName, int level, bool allowNonVanilla) -> bool { + return EnchantUtils::applyEnchant( + (ItemStackBase&)*item, + Enchant::getEnchantTypeFromName(HashedString(typeName)), + level, + allowNonVanilla + ); } ); RemoteCall::exportAs("GMLIB_API", "removeEnchants", [](ItemStack const* item) -> void { EnchantUtils::removeEnchants((ItemStack&)*item); }); - RemoteCall::exportAs("GMLIB_API", "hasEnchant", [](ItemStack const* item, int id) -> bool { - return EnchantUtils::hasEnchant((Enchant::Type)id, (ItemStackBase&)*item); + RemoteCall::exportAs("GMLIB_API", "hasEnchant", [](ItemStack const* item, std::string const& typeName) -> bool { + return EnchantUtils::hasEnchant(Enchant::getEnchantTypeFromName(HashedString(typeName)), (ItemStackBase&)*item); }); - RemoteCall::exportAs("GMLIB_API", "getEnchantLevel", [](ItemStack const* item, int id) -> int { - return EnchantUtils::getEnchantLevel((Enchant::Type)id, (ItemStackBase&)*item); - }); - RemoteCall::exportAs("GMLIB_API", "getEnchantNameAndLevel", [](int id, int level) -> std::string { - return EnchantUtils::getEnchantNameAndLevel((Enchant::Type)id, level); + RemoteCall::exportAs("GMLIB_API", "getEnchantLevel", [](ItemStack const* item, std::string const& typeName) -> int { + return EnchantUtils::getEnchantLevel( + Enchant::getEnchantTypeFromName(HashedString(typeName)), + (ItemStackBase&)*item + ); }); + RemoteCall::exportAs( + "GMLIB_API", + "getEnchantNameAndLevel", + [](std::string const& typeName, int level) -> std::string { + return EnchantUtils::getEnchantNameAndLevel(Enchant::getEnchantTypeFromName(HashedString(typeName)), level); + } + ); RemoteCall::exportAs( "GMLIB_API", "dropPlayerItem", diff --git a/src/Event/HandleRequestAction/HandleRequestAction.cpp b/src/Event/HandleRequestAction/HandleRequestAction.cpp deleted file mode 100644 index 8073cbd..0000000 --- a/src/Event/HandleRequestAction/HandleRequestAction.cpp +++ /dev/null @@ -1,41 +0,0 @@ -#include "HandleRequestAction.h" -#include "Global.h" - - -HandleRequestActionBeforeEvent::HandleRequestActionBeforeEvent( - Player* player, - ItemStackRequestAction& requestAction -) -: mPlayer(player), - mRequestAction(requestAction) {} - -Player* HandleRequestActionBeforeEvent::self() const { return mPlayer; } - -ItemStackRequestAction& HandleRequestActionBeforeEvent::getRequestAction() const { return mRequestAction; } - -HandleRequestActionAfterEvent::HandleRequestActionAfterEvent( - Player* player, - ItemStackRequestAction& requestAction -) -: mPlayer(player), - mRequestAction(requestAction) {} - -Player* HandleRequestActionAfterEvent::self() const { return mPlayer; } - -ItemStackRequestAction& HandleRequestActionAfterEvent::getRequestAction() const { return mRequestAction; } - - -LL_AUTO_TYPE_INSTANCE_HOOK( - HandleRequestActionHook, - HookPriority::Normal, - ItemStackRequestActionHandler, - "?handleRequestAction@ItemStackRequestActionHandler@@QEAA?AW4ItemStackNetResult@@AEBVItemStackRequestAction@@@Z", - void, - ItemStackRequestAction& requestAction -) { - auto beforeEvent = HandleRequestActionBeforeEvent(((Player*)(*(__int64*)this)), requestAction); - ll::event::EventBus::getInstance().publish(beforeEvent); - if (beforeEvent.isCancelled()) return; - ll::event::EventBus::getInstance().publish(HandleRequestActionAfterEvent(((Player*)(*(__int64*)this)), requestAction)); - return origin(requestAction); -} \ No newline at end of file diff --git a/src/Event/HandleRequestAction/HandleRequestAction.h b/src/Event/HandleRequestAction/HandleRequestAction.h deleted file mode 100644 index 89922c8..0000000 --- a/src/Event/HandleRequestAction/HandleRequestAction.h +++ /dev/null @@ -1,28 +0,0 @@ -#include "Global.h" -#include "ll/api/event/Cancellable.h" - -class HandleRequestActionBeforeEvent final : public ll::event::Cancellable { -private: - Player* mPlayer{}; - ItemStackRequestAction& mRequestAction; - -public: - HandleRequestActionBeforeEvent(Player* player, ItemStackRequestAction& requestAction); - - Player* self() const; - - ItemStackRequestAction& getRequestAction() const; -}; - -class HandleRequestActionAfterEvent final : public ll::event::Event { -private: - Player* mPlayer; - ItemStackRequestAction& mRequestAction; - -public: - HandleRequestActionAfterEvent(Player* player, ItemStackRequestAction& requestAction); - - Player* self() const; - - ItemStackRequestAction& getRequestAction() const; -}; \ No newline at end of file diff --git a/src/EventAPI.cpp b/src/EventAPI.cpp index 685021f..2b37197 100644 --- a/src/EventAPI.cpp +++ b/src/EventAPI.cpp @@ -1,5 +1,4 @@ #include "Global.h" -#include "Event/HandleRequestAction/HandleRequestAction.h" using namespace ll::hash_utils; void Export_Event_API() { @@ -248,46 +247,6 @@ void Export_Event_API() { ); return true; } - case doHash("handleRequestTryAction"): { - auto Call = - RemoteCall::importAs( - eventName, - eventId - ); - eventBus->emplaceListener([Call](HandleRequestActionBeforeEvent& ev) { - bool result = true; - try { - result = Call( - ev.self(), - (int)ev.getRequestAction().getActionType(), - (int)ev.getRequestAction().getSrc().mSlot, - (int)ev.getRequestAction().getSrc().mOpenContainerNetId - ); - } catch (...) {} - if (!result) { - ev.cancel(); - } - }); - return true; - } - case doHash("handleRequestAction"): { - auto Call = - RemoteCall::importAs( - eventName, - eventId - ); - eventBus->emplaceListener([Call](HandleRequestActionAfterEvent& ev) { - try { - Call( - ev.self(), - (int)ev.getRequestAction().getActionType(), - (int)ev.getRequestAction().getSrc().mSlot, - (int)ev.getRequestAction().getSrc().mOpenContainerNetId - ); - } catch (...) {} - }); - return true; - } default: return false; } diff --git a/src/LegacyServerApi.cpp b/src/LegacyServerApi.cpp index 6a2dd50..ccb9313 100644 --- a/src/LegacyServerApi.cpp +++ b/src/LegacyServerApi.cpp @@ -1,8 +1,4 @@ -#include "GMLIB/Server/FakeListAPI.h" -#include "GMLIB/Server/LevelAPI.h" #include "Global.h" -#include "mc/world/ActorUniqueID.h" -#include void Export_Legacy_GMLib_ServerAPI() { RemoteCall::exportAs("GMLib_ServerAPI", "setEducationFeatureEnabled", []() -> void { @@ -76,6 +72,9 @@ void Export_Legacy_GMLib_ServerAPI() { return FakeList::removeAllFakeLists(); }); RemoteCall::exportAs("GMLib_ServerAPI", "getMaxPlayers", []() -> int { - return ll::memory::dAccess(ll::service::getServerNetworkHandler().as_ptr(), 200); + if (auto level = GMLIB_Level::getInstance()) { + return level->getMaxPlayerCount(); + } + return {}; }); } From 27518fa2fce9bae72ca9ebeb7558c93f25ce9f9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=90=E6=B2=90=E5=91=80?= <163636894+zimuya4153@users.noreply.github.com> Date: Mon, 8 Jul 2024 15:55:47 +0800 Subject: [PATCH 05/37] =?UTF-8?q?=E6=96=B0=E5=A2=9E2=E4=BA=8B=E4=BB=B6?= =?UTF-8?q?=EF=BC=8C=E4=BF=AE=E6=94=B92=E4=BA=8B=E4=BB=B6=EF=BC=8C2?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增事件: - SpawnWanderingTrader - HandleRequestAction 修改事件: - ProjectileTryCreate - ProjectileCreate 修改接口: - getPlayerFromUniqueId - getEntityFromUniqueId --- lib/EventAPI-JS.d.ts | 36 +++++++++++++++++++++++++++-- lib/GMLIB_API-JS.d.ts | 4 ++-- lib/GMLIB_API-JS.js | 8 +++---- src/EventAPI.cpp | 53 +++++++++++++++++++++++++++++++++++++++---- 4 files changed, 88 insertions(+), 13 deletions(-) diff --git a/lib/EventAPI-JS.d.ts b/lib/EventAPI-JS.d.ts index 7cbaa7f..897d826 100644 --- a/lib/EventAPI-JS.d.ts +++ b/lib/EventAPI-JS.d.ts @@ -177,7 +177,9 @@ declare class Event { /** 回调函数 */ listener: ( /** 弹射物实体对象 */ - entity: Entity + entity: Entity, + /** 创建弹射的实体的uniqueID */ + uniqueId: number ) => boolean | void ): boolean; @@ -188,7 +190,37 @@ declare class Event { /** 回调函数 */ listener: ( /** 弹射物实体对象 */ - entity: Entity + entity: Entity, + /** 创建弹射的实体的uniqueID */ + uniqueId: number ) => void ): boolean; + + /** 生成流浪商人 */ + static listen( + /** 事件名 */ + event: "SpawnWanderingTrader", + /** 回调函数 */ + listener: ( + /** 生成的坐标 */ + pos: IntPos + ) => boolean | void + ): boolean; + + /** 处理物品请求 */ + static listen( + /** 事件名 */ + event: "HandleRequestAction", + /** 回调函数 */ + listener: ( + /** 请求玩家 */ + player: Player, + /** 请求类型 */ + actionType: string, + /** 容器ID */ + ContainerNetId: string, + /** 请求的槽位 */ + slot: number + ) => boolean | void + ): boolean; } diff --git a/lib/GMLIB_API-JS.d.ts b/lib/GMLIB_API-JS.d.ts index 9c9d0d8..f4d6aca 100644 --- a/lib/GMLIB_API-JS.d.ts +++ b/lib/GMLIB_API-JS.d.ts @@ -276,12 +276,12 @@ declare class Minecraft { /** 根据UniqueId获取玩家对象 */ static getPlayerFromUniqueId( - uniqueId: string + uniqueId: string | number ): Player; /** 根据UniqueId获取实体对象 */ static getEntityFromUniqueId( - uniqueId: string + uniqueId: string | number ): Entity; /** 获取方块runtimeId */ diff --git a/lib/GMLIB_API-JS.js b/lib/GMLIB_API-JS.js index e71f69f..5f66202 100644 --- a/lib/GMLIB_API-JS.js +++ b/lib/GMLIB_API-JS.js @@ -805,20 +805,20 @@ class Minecraft { /** * 根据UniqueId获取玩家对象 - * @param {string} uniqueId 玩家的UniqueId + * @param {string|number} uniqueId 玩家的UniqueId * @returns {Player} 玩家对象 */ static getPlayerFromUniqueId(uniqueId) { - return GMLIB_API.getPlayerFromUniqueId(uniqueId); + return GMLIB_API.getPlayerFromUniqueId(uniqueId.toString()); } /** * 根据UniqueId获取实体对象 - * @param {string} uniqueId 实体的UniqueId + * @param {string|number} uniqueId 实体的UniqueId * @returns {Entity} 实体对象 */ static getEntityFromUniqueId(uniqueId) { - return GMLIB_API.getEntityFromUniqueId(uniqueId); + return GMLIB_API.getEntityFromUniqueId(uniqueId.toString()); } /** diff --git a/src/EventAPI.cpp b/src/EventAPI.cpp index 2b37197..1ae5c61 100644 --- a/src/EventAPI.cpp +++ b/src/EventAPI.cpp @@ -1,4 +1,5 @@ #include "Global.h" +#include "mc/world/ActorUniqueID.h" using namespace ll::hash_utils; void Export_Event_API() { @@ -222,31 +223,73 @@ void Export_Event_API() { return true; } case doHash("ProjectileTryCreate"): { - auto Call = RemoteCall::importAs(eventName, eventId); + auto Call = RemoteCall::importAs(eventName, eventId); eventBus->emplaceListener( [Call](Event::EntityEvent::ProjectileCreateBeforeEvent& ev) { bool result = true; try { - result = Call(&ev.self()); + auto uid = ev.getShooter() ? ev.getShooter()->getOrCreateUniqueID().id : -1; + result = Call(&ev.self(), uid); } catch (...) {} if (!result) { ev.cancel(); } } ); - return true; + return true; } case doHash("ProjectileCreate"): { - auto Call = RemoteCall::importAs(eventName, eventId); + auto Call = RemoteCall::importAs(eventName, eventId); eventBus->emplaceListener( [Call](Event::EntityEvent::ProjectileCreateAfterEvent& ev) { try { - Call(&ev.self()); + auto uid = ev.getShooter() ? ev.getShooter()->getOrCreateUniqueID().id : -1; + Call(&ev.self(), uid); } catch (...) {} } ); return true; } + case doHash("SpawnWanderingTrader"): { + auto Call = RemoteCall::importAs pos)>(eventName, eventId); + eventBus->emplaceListener( + [Call](Event::EntityEvent::SpawnWanderingTraderBeforeEvent& ev) { + bool result = true; + try { + result = Call({ev.getPos(), 0}); + } catch (...) {} + if (!result) { + ev.cancel(); + } + } + ); + return true; + } + case doHash("HandleRequestAction"): { + auto Call = RemoteCall::importAs< + bool(Player * player, std::string const& actionType, std::string const& ContainerNetId, int slot)>( + eventName, + eventId + ); + eventBus->emplaceListener( + [Call](Event::PlayerEvent::HandleRequestActionBeforeEvent& ev) { + bool result = true; + try { + auto requestAction = (ItemStackRequestActionTransferBase*)&ev.getRequestAction(); + result = Call( + &ev.self(), + magic_enum::enum_name(requestAction->mActionType).data(), + magic_enum::enum_name(requestAction->getSrc().mOpenContainerNetId).data(), + requestAction->getSrc().mSlot + ); + } catch (...) {} + if (!result) { + ev.cancel(); + } + } + ); + return true; + } default: return false; } From 2d5e6736d7f5d98412dfb91f5c05822422d4671f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=90=E6=B2=90=E5=91=80?= <163636894+zimuya4153@users.noreply.github.com> Date: Wed, 10 Jul 2024 11:06:44 +0800 Subject: [PATCH 06/37] =?UTF-8?q?=E5=A2=9E=E5=8A=A03=E4=B8=AA=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - getPlayerRuntimeId - getEntityRuntimeId - getEntityNameTag --- src/CompatibilityApi.cpp | 12 ++++++++++-- src/EventAPI.cpp | 1 - 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/CompatibilityApi.cpp b/src/CompatibilityApi.cpp index df6e229..f90995a 100644 --- a/src/CompatibilityApi.cpp +++ b/src/CompatibilityApi.cpp @@ -1,5 +1,4 @@ #include "Global.h" -#include "mc/deps/core/string/HashedString.h" #include bool isInteger(const std::string& str) { @@ -732,7 +731,7 @@ void Export_Compatibility_API() { }); RemoteCall::exportAs("GMLIB_API", "getEnchantTypeNameFromId", [](int id) -> std::string { if (auto enchant = Enchant::getEnchant((Enchant::Type)id)) { - return enchant->getStringId(); + return std::string(enchant->getStringId()); } return ""; }); @@ -772,4 +771,13 @@ void Export_Compatibility_API() { "dropPlayerItem", [](Player* player, ItemStack const* item, bool randomly) -> bool { return player->drop(*item, randomly); } ); + RemoteCall::exportAs("GMLIB_API", "getPlayerRuntimeId", [](Player* player) -> uint64 { + return player->getRuntimeID().id; + }); + RemoteCall::exportAs("GMLIB_API", "getEntityRuntimeId", [](Actor* entity) -> uint64 { + return entity->getRuntimeID().id; + }); + RemoteCall::exportAs("GMLIB_API", "getEntityNameTag", [](Actor* entity) -> std::string { + return entity->getNameTag(); + }); } \ No newline at end of file diff --git a/src/EventAPI.cpp b/src/EventAPI.cpp index 1ae5c61..a9225e3 100644 --- a/src/EventAPI.cpp +++ b/src/EventAPI.cpp @@ -1,5 +1,4 @@ #include "Global.h" -#include "mc/world/ActorUniqueID.h" using namespace ll::hash_utils; void Export_Event_API() { From a5fe6c5a3974d8d14897baa83c59c55984fde94a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=90=E6=B2=90=E5=91=80?= <163636894+zimuya4153@users.noreply.github.com> Date: Wed, 10 Jul 2024 11:26:24 +0800 Subject: [PATCH 07/37] =?UTF-8?q?=E8=A1=A5=E5=85=A8=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/GMLIB_API-JS.d.ts | 9 +++++++++ lib/GMLIB_API-JS.js | 37 ++++++++++++++++++++++++++++++++++++- 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/lib/GMLIB_API-JS.d.ts b/lib/GMLIB_API-JS.d.ts index f4d6aca..67beb3d 100644 --- a/lib/GMLIB_API-JS.d.ts +++ b/lib/GMLIB_API-JS.d.ts @@ -1027,6 +1027,9 @@ interface Player { /** 随机丢出位置 */ randomly: boolean | undefined ): boolean; + + /** (GMLIB)获取玩家的rumtimeId */ + getRuntimeId(): number; } interface Entity { @@ -1070,6 +1073,12 @@ interface Entity { /** 实体对象 */ entity: Entity ): boolean; + + /** (GMLIB)获取实体的rumtimeId */ + getRuntimeId(): number; + + /** (GMLIB)获取实体的命名 */ + getNameTag(): string; } interface Block { diff --git a/lib/GMLIB_API-JS.js b/lib/GMLIB_API-JS.js index 5f66202..ce4deef 100644 --- a/lib/GMLIB_API-JS.js +++ b/lib/GMLIB_API-JS.js @@ -1,3 +1,5 @@ +/// + /** LRCA导出接口 */ const GMLIB_API = { /** 创建悬浮字 @type {function(FloatPos,string,boolean):number} */ @@ -281,7 +283,13 @@ const GMLIB_API = { /** 获取最大玩家数 @type {function():number} */ getMaxPlayers: ll.import("GMLib_ServerAPI", "getMaxPlayers"), /** 丢出玩家背包内物品 @type {function(Player,Item,boolean):boolean} */ - dropPlayerItem: ll.import("GMLIB_API", "dropPlayerItem") + dropPlayerItem: ll.import("GMLIB_API", "dropPlayerItem"), + /** 获取玩家的RuntimeId @type {function(Player):number} */ + getPlayerRuntimeId: ll.import("GMLIB_API", "getPlayerRuntimeId"), + /** 获取实体的RuntimeId @type {function(Entity):number} */ + getEntityRuntimeId: ll.import("GMLIB_API", "getEntityRuntimeId"), + /** 获取实体命名 @type {function(Entity):string} */ + getEntityNameTag: ll.import("GMLIB_API", "getEntityNameTag") } /** 静态悬浮字类列表 @type {Map} */ @@ -2180,6 +2188,33 @@ LLSE_Player.prototype.dropItem = return GMLIB_API.dropPlayerItem(this, item, randomly); } +LLSE_Player.prototype.getRuntimeId = + /** + * 获取玩家的runtimeId + * @returns {number} 玩家的runtimeId + */ + function () { + return GMLIB_API.getPlayerRuntimeId(this); + } + +LLSE_Entity.prototype.getRuntimeId = + /** + * 获取实体的runtimeId + * @returns {number} 实体的runtimeId + */ + function () { + return GMLIB_API.getEntityRuntimeId(this); + } + +LLSE_Entity.prototype.getNameTag = + /** + * 获取实体的命名 + * @returns {string} 实体的命名 + */ + function () { + return GMLIB_API.getEntityNameTag(this); + } + module.exports = { StaticFloatingText, DynamicFloatingText, From 4dce1f7a8ba7af1350f9b91d0759cfdcbf41e61f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=90=E6=B2=90=E5=91=80?= <163636894+zimuya4153@users.noreply.github.com> Date: Thu, 11 Jul 2024 03:50:50 +0800 Subject: [PATCH 08/37] =?UTF-8?q?=E5=A2=9E=E5=8A=A06=E4=B8=AA=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ItemisUnbreakable - setItemUnbreakable - getItemShouldKeepOnDeath - setItemShouldKeepOnDeath - getItemLockMode - setItemLockMode --- lib/GMLIB_API-JS.d.ts | 43 +++++++++++++++++++++---- lib/GMLIB_API-JS.js | 68 +++++++++++++++++++++++++++++++++++++++- src/CompatibilityApi.cpp | 18 +++++++++++ 3 files changed, 122 insertions(+), 7 deletions(-) diff --git a/lib/GMLIB_API-JS.d.ts b/lib/GMLIB_API-JS.d.ts index 67beb3d..d08a6e3 100644 --- a/lib/GMLIB_API-JS.d.ts +++ b/lib/GMLIB_API-JS.d.ts @@ -785,6 +785,7 @@ declare class JsonConfig { ): void; } +/** JSON语言文件 */ declare class JsonLanguage extends JsonConfig { /** 创建或打开一个 Json 语言文件 */ constructor( @@ -803,6 +804,7 @@ declare class JsonLanguage extends JsonConfig { ): string; } +/** JSON版翻译类 */ declare class JsonI18n { /** 加载翻译数据目录 */ constructor( @@ -895,6 +897,7 @@ declare class Version { static getGmlibVersion(): Version; } +/** 翻译API类 */ declare class I18nAPI { private constructor(); @@ -955,6 +958,7 @@ declare class I18nAPI { ): void; } +/** 玩家信息存储类 */ declare class UserCache { private constructor(); @@ -1020,7 +1024,7 @@ interface Player { /** (GMLIB)清除玩家重生点 */ clearSpawnPoint(): void; - /** 丢出玩家物品 */ + /** (GMLIB)丢出玩家物品 */ dropItem( /** 物品对象 */ item: Item, @@ -1144,10 +1148,10 @@ interface Item { block: Block ): boolean; - /** 获取物品可以拥有的附魔 */ + /** (GMLIB)获取物品可以拥有的附魔 */ getLegalEnchants(): string[] - /** 添加附魔 */ + /** (GMLIB)添加附魔 */ applyEnchant( /** 附魔的命名空间 */ typeName: string, @@ -1157,18 +1161,45 @@ interface Item { allowNonVanilla: boolean | null ): boolean; - /** 删除所有附魔 */ + /** (GMLIB)删除所有附魔 */ removeEnchants(): void; - /** 判断是否拥有附魔 */ + /** (GMLIB)判断是否拥有附魔 */ hasEnchant( /** 附魔的命名空间 */ typeName: string ): boolean; - /** 获取附魔等级 */ + /** (GMLIB)获取附魔等级 */ getEnchantLevel( /** 附魔的命名空间 */ typeName: string ): number; + + /** (GMLIB)物品是否拥有不可破坏标签 */ + isUnbreakable(): boolean; + + /** (GMLIB)设置物品不可破坏标签 */ + setUnbreakable( + /** 是否不可破坏 */ + unbreakable: boolean + ): void; + + /** (GMLIB)物品是否拥有死亡不掉落标签 */ + getShouldKeepOnDeath(): boolean; + + /** (GMLIB)设置物品死亡不掉落标签 */ + setShouldKeepOnDeath( + /** 物品是否死亡不掉落 */ + value: boolean + ): void; + + /** (GMLIB)获取物品的锁定模式 0:无 1:锁定在格子里 2:锁定在背包里 */ + getItemLockMode(): 0 | 1 | 2; + + /** (GMLIB)设置物品的锁定模式 0:无 1:锁定在格子里 2:锁定在背包里 */ + setItemLockMode( + /** 锁定模式 */ + mode: 0 | 1 | 2 + ): void; } \ No newline at end of file diff --git a/lib/GMLIB_API-JS.js b/lib/GMLIB_API-JS.js index ce4deef..fc70b8a 100644 --- a/lib/GMLIB_API-JS.js +++ b/lib/GMLIB_API-JS.js @@ -289,7 +289,19 @@ const GMLIB_API = { /** 获取实体的RuntimeId @type {function(Entity):number} */ getEntityRuntimeId: ll.import("GMLIB_API", "getEntityRuntimeId"), /** 获取实体命名 @type {function(Entity):string} */ - getEntityNameTag: ll.import("GMLIB_API", "getEntityNameTag") + getEntityNameTag: ll.import("GMLIB_API", "getEntityNameTag"), + /** 物品是否有不可破坏标签 @type {function(Item):boolean} */ + ItemisUnbreakable: ll.import("GMLIB_API", "ItemisUnbreakable"), + /** 设置物品不可破坏标签 @type {function(Item,boolean):void} */ + setItemUnbreakable: ll.import("GMLIB_API", "setItemUnbreakable"), + /** 物品是否死亡不会掉落 @type {function(Item):boolean} */ + getItemShouldKeepOnDeath: ll.import("GMLIB_API", "getItemShouldKeepOnDeath"), + /** 设置物品死亡不掉落 @type {function(Item,boolean):void} */ + setItemShouldKeepOnDeath: ll.import("GMLIB_API", "setItemShouldKeepOnDeath"), + /** 获取物品锁定模式 @type {function(Item):number} */ + getItemLockMode: ll.import("GMLIB_API", "getItemLockMode"), + /** 设置物品锁定模式 @type {function(Item,number):void} */ + setItemLockMode: ll.import("GMLIB_API", "setItemLockMode") } /** 静态悬浮字类列表 @type {Map} */ @@ -2215,6 +2227,60 @@ LLSE_Entity.prototype.getNameTag = return GMLIB_API.getEntityNameTag(this); } +LLSE_Item.prototype.isUnbreakable = + /** + * 物品是否拥有不可破坏标签 + * @returns {boolean} 是否拥有 + */ + function () { + return GMLIB_API.ItemisUnbreakable(this); + } + +LLSE_Item.prototype.setUnbreakable = + /** + * 设置物品不可破坏标签 + * @param {boolean} value 是否不可破坏 + */ + function (value) { + GMLIB_API.setItemUnbreakable(this, value); + } + +LLSE_Item.prototype.getShouldKeepOnDeath = + /** + * 物品是否拥有死亡不掉落标签 + * @returns {boolean} 物品是否拥有死亡不掉落标签 + */ + function () { + return GMLIB_API.getItemShouldKeepOnDeath(this); + } + +LLSE_Item.prototype.setShouldKeepOnDeath = + /** + * 设置物品死亡不掉落标签 + * @param {boolean} value 物品是否死亡不掉落 + */ + function (value) { + GMLIB_API.setItemShouldKeepOnDeath(this, value); + } + +LLSE_Item.prototype.getItemLockMode = + /** + * 获取物品的锁定模式 + * @returns {0|1|2} 锁定的模式 0:无 1:锁定在格子里 2:锁定在背包里 + */ + function () { + return GMLIB_API.getItemLockMode(this) + } + +LLSE_Item.prototype.setItemLockMode = + /** + * 设置物品的锁定模式 + * @param {0|1|2} mode 锁定的模式 0:无 1:锁定在格子里 2:锁定在背包里 + */ + function (mode) { + GMLIB_API.setItemLockMode(this, mode); + } + module.exports = { StaticFloatingText, DynamicFloatingText, diff --git a/src/CompatibilityApi.cpp b/src/CompatibilityApi.cpp index f90995a..56ccdd8 100644 --- a/src/CompatibilityApi.cpp +++ b/src/CompatibilityApi.cpp @@ -780,4 +780,22 @@ void Export_Compatibility_API() { RemoteCall::exportAs("GMLIB_API", "getEntityNameTag", [](Actor* entity) -> std::string { return entity->getNameTag(); }); + RemoteCall::exportAs("GMLIB_API", "ItemisUnbreakable", [](ItemStack const* item) -> bool { + return ((GMLIB_ItemStack*)item)->isUnbreakable(); + }); + RemoteCall::exportAs("GMLIB_API", "setItemUnbreakable", [](ItemStack const* item, bool value) -> void { + ((GMLIB_ItemStack*)item)->setUnbreakable(value); + }); + RemoteCall::exportAs("GMLIB_API", "getItemShouldKeepOnDeath", [](ItemStack const* item) -> bool { + return ((GMLIB_ItemStack*)item)->getShouldKeepOnDeath(); + }); + RemoteCall::exportAs("GMLIB_API", "setItemShouldKeepOnDeath", [](ItemStack const* item, bool value) -> void { + ((GMLIB_ItemStack*)item)->setShouldKeepOnDeath(true); + }); + RemoteCall::exportAs("GMLIB_API", "getItemLockMode", [](ItemStack const* item) -> int { + return (int)((GMLIB_ItemStack*)item)->getItemLockMode(); + }); + RemoteCall::exportAs("GMLIB_API", "setItemLockMode", [](ItemStack const* item, int value) -> void { + ((GMLIB_ItemStack*)item)->setItemLockMode((ItemLockMode)value); + }); } \ No newline at end of file From 93b99f936a91244f6937d68f29d00408923998af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=90=E6=B2=90=E5=91=80?= <163636894+zimuya4153@users.noreply.github.com> Date: Thu, 11 Jul 2024 13:23:22 +0800 Subject: [PATCH 09/37] =?UTF-8?q?=E4=BF=AE=E5=A4=8DSpawnWanderingTrader?= =?UTF-8?q?=E4=BA=8B=E4=BB=B6=E5=9D=90=E6=A0=87=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/EventAPI.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/EventAPI.cpp b/src/EventAPI.cpp index a9225e3..fae1556 100644 --- a/src/EventAPI.cpp +++ b/src/EventAPI.cpp @@ -255,7 +255,7 @@ void Export_Event_API() { [Call](Event::EntityEvent::SpawnWanderingTraderBeforeEvent& ev) { bool result = true; try { - result = Call({ev.getPos(), 0}); + result = Call({ev.getPos(), ev.getRegion().getDimensionId()}); } catch (...) {} if (!result) { ev.cancel(); From 374e5a29e02b4ef42a6a4d0f324a3ce26a7a6b10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=90=E6=B2=90=E5=91=80?= <163636894+zimuya4153@users.noreply.github.com> Date: Thu, 11 Jul 2024 19:38:57 +0800 Subject: [PATCH 10/37] =?UTF-8?q?=E5=A2=9E=E5=8A=A02=E4=B8=AA=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - getItemRepairCost - setItemRepairCost --- lib/EventAPI-JS.d.ts | 2 -- lib/GMLIB_API-JS.d.ts | 9 +++++++++ lib/GMLIB_API-JS.js | 26 +++++++++++++++++++++++--- src/CompatibilityApi.cpp | 6 ++++++ 4 files changed, 38 insertions(+), 5 deletions(-) diff --git a/lib/EventAPI-JS.d.ts b/lib/EventAPI-JS.d.ts index 897d826..10eb645 100644 --- a/lib/EventAPI-JS.d.ts +++ b/lib/EventAPI-JS.d.ts @@ -1,5 +1,3 @@ -/// - /** 事件监听接口 */ declare class Event { /** 生物捡起物品 */ diff --git a/lib/GMLIB_API-JS.d.ts b/lib/GMLIB_API-JS.d.ts index d08a6e3..18b5fc1 100644 --- a/lib/GMLIB_API-JS.d.ts +++ b/lib/GMLIB_API-JS.d.ts @@ -1202,4 +1202,13 @@ interface Item { /** 锁定模式 */ mode: 0 | 1 | 2 ): void; + + /** (GMLIB)获取物品的惩罚等级 */ + getRepairCost(): number; + + /** (GMLIB)设置物品的惩罚等级 */ + setRepairCost( + /** 要设置的惩罚等级 */ + cost: number + ): void; } \ No newline at end of file diff --git a/lib/GMLIB_API-JS.js b/lib/GMLIB_API-JS.js index fc70b8a..863e5cc 100644 --- a/lib/GMLIB_API-JS.js +++ b/lib/GMLIB_API-JS.js @@ -1,5 +1,3 @@ -/// - /** LRCA导出接口 */ const GMLIB_API = { /** 创建悬浮字 @type {function(FloatPos,string,boolean):number} */ @@ -301,7 +299,11 @@ const GMLIB_API = { /** 获取物品锁定模式 @type {function(Item):number} */ getItemLockMode: ll.import("GMLIB_API", "getItemLockMode"), /** 设置物品锁定模式 @type {function(Item,number):void} */ - setItemLockMode: ll.import("GMLIB_API", "setItemLockMode") + setItemLockMode: ll.import("GMLIB_API", "setItemLockMode"), + /** 获取物品惩罚等级 @type {function(Item):number} */ + getItemRepairCost: ll.import("GMLIB_API", "getItemRepairCost"), + /** 设置物品惩罚等级 @type {function(Item,number):void} */ + setItemRepairCost: ll.import("GMLIB_API", "setItemRepairCost") } /** 静态悬浮字类列表 @type {Map} */ @@ -2281,6 +2283,24 @@ LLSE_Item.prototype.setItemLockMode = GMLIB_API.setItemLockMode(this, mode); } +LLSE_Item.prototype.getRepairCost = + /** + * 获取物品的惩罚等级 + * @returns {number} 惩罚等级 + */ + function () { + return GMLIB_API.getItemRepairCost(this); + } + +LLSE_Item.prototype.setRepairCost = + /** + * 设置物品的惩罚等级 + * @param {number} cost 要设置的惩罚等级 + */ + function (cost) { + return GMLIB_API.setItemRepairCost(this, cost); + } + module.exports = { StaticFloatingText, DynamicFloatingText, diff --git a/src/CompatibilityApi.cpp b/src/CompatibilityApi.cpp index 56ccdd8..4ddfb02 100644 --- a/src/CompatibilityApi.cpp +++ b/src/CompatibilityApi.cpp @@ -798,4 +798,10 @@ void Export_Compatibility_API() { RemoteCall::exportAs("GMLIB_API", "setItemLockMode", [](ItemStack const* item, int value) -> void { ((GMLIB_ItemStack*)item)->setItemLockMode((ItemLockMode)value); }); + RemoteCall::exportAs("GMLIB_API", "getItemRepairCost", [](ItemStack const* item) -> int { + return item->getBaseRepairCost(); + }); + RemoteCall::exportAs("GMLIB_API", "setItemRepairCost", [](ItemStack const* item, int cost) -> void { + ((ItemStackBase*)item)->setRepairCost(cost); + }); } \ No newline at end of file From b9d090040770528fe9c734716bca5f140710af8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=90=E6=B2=90=E5=91=80?= <163636894+zimuya4153@users.noreply.github.com> Date: Fri, 12 Jul 2024 03:20:37 +0800 Subject: [PATCH 11/37] =?UTF-8?q?=E5=A2=9E=E5=8A=A04=E4=B8=AA=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - getItemCanDestroy - setItemCanDestroy - getItemCanPlaceOn - setItemCanPlaceOn --- lib/GMLIB_API-JS.d.ts | 18 ++++++++++++++++ lib/GMLIB_API-JS.js | 46 +++++++++++++++++++++++++++++++++++++++- src/CompatibilityApi.cpp | 28 ++++++++++++++++++++++++ 3 files changed, 91 insertions(+), 1 deletion(-) diff --git a/lib/GMLIB_API-JS.d.ts b/lib/GMLIB_API-JS.d.ts index 18b5fc1..8dfeb69 100644 --- a/lib/GMLIB_API-JS.d.ts +++ b/lib/GMLIB_API-JS.d.ts @@ -1211,4 +1211,22 @@ interface Item { /** 要设置的惩罚等级 */ cost: number ): void; + + /** (GMLIB)获取冒险模式下能破坏的方块 */ + getCanDestroy(): string[]; + + /** (GMLIB)设置冒险模式下能破坏的方块 */ + setCanDestroy( + /** 能破坏的方块 */ + blocks: string[] + ): void; + + /** (GMLIB)获取冒险模式下能放置在什么方块上 */ + getCanPlaceOn(): string[]; + + /** (GMLIB)设置冒险模式下能放置在什么方块上 */ + getCanPlaceOn( + /** 能放置的方块 */ + blocks: string[] + ): void; } \ No newline at end of file diff --git a/lib/GMLIB_API-JS.js b/lib/GMLIB_API-JS.js index 863e5cc..6beaeac 100644 --- a/lib/GMLIB_API-JS.js +++ b/lib/GMLIB_API-JS.js @@ -303,7 +303,15 @@ const GMLIB_API = { /** 获取物品惩罚等级 @type {function(Item):number} */ getItemRepairCost: ll.import("GMLIB_API", "getItemRepairCost"), /** 设置物品惩罚等级 @type {function(Item,number):void} */ - setItemRepairCost: ll.import("GMLIB_API", "setItemRepairCost") + setItemRepairCost: ll.import("GMLIB_API", "setItemRepairCost"), + /** 获取物品冒险模式下可破坏的方块 @type {function(Item):Array.} */ + getItemCanDestroy: ll.import("GMLIB_API", "getItemCanDestroy"), + /** 设置物品冒险模式下可破坏的方块 @type {function(Item,Array.):void} */ + setItemCanDestroy: ll.import("GMLIB_API", "setItemCanDestroy"), + /** 获取物品冒险模式下能放置在什么方块上 @type {function(Item):Array.} */ + getItemCanPlaceOn: ll.import("GMLIB_API", "getItemCanPlaceOn"), + /** 设置物品冒险模式下能放置在什么方块上 @type {function(Item,Array.):void} */ + setItemCanPlaceOn: ll.import("GMLIB_API", "setItemCanPlaceOn") } /** 静态悬浮字类列表 @type {Map} */ @@ -2301,6 +2309,42 @@ LLSE_Item.prototype.setRepairCost = return GMLIB_API.setItemRepairCost(this, cost); } +LLSE_Item.prototype.getCanDestroy = + /** + * 获取冒险模式下能破坏的方块 + * @returns {Array.} 能破坏的方块 + */ + function () { + return GMLIB_API.getItemCanDestroy(this); + } + +LLSE_Item.prototype.setCanDestroy = + /** + * 设置冒险模式下能破坏的方块 + * @param {Array.} blocks 能破坏的方块 + */ + function (blocks) { + GMLIB_API.setItemCanDestroy(this, blocks); + } + +LLSE_Item.prototype.getCanPlaceOn = + /** + * 获取冒险模式下能放置在什么方块上 + * @returns {Array.} 能放置的方块 + */ + function () { + return GMLIB_API.getItemCanPlaceOn(this); + } + +LLSE_Item.prototype.setCanPlaceOn = + /** + * 设置冒险模式下能放置在什么方块上 + * @param {Array.} blocks 能放置的方块 + */ + function (blocks) { + GMLIB_API.setItemCanPlaceOn(this, blocks); + } + module.exports = { StaticFloatingText, DynamicFloatingText, diff --git a/src/CompatibilityApi.cpp b/src/CompatibilityApi.cpp index 4ddfb02..063af08 100644 --- a/src/CompatibilityApi.cpp +++ b/src/CompatibilityApi.cpp @@ -804,4 +804,32 @@ void Export_Compatibility_API() { RemoteCall::exportAs("GMLIB_API", "setItemRepairCost", [](ItemStack const* item, int cost) -> void { ((ItemStackBase*)item)->setRepairCost(cost); }); + RemoteCall::exportAs("GMLIB_API", "getItemCanDestroy", [](ItemStack const* item) -> std::vector { + std::vector result = {}; + for (auto& block : ((GMLIB_ItemStack*)item)->getCanDestroy()) { + result.push_back(block->getTypeName()); + } + return result; + }); + RemoteCall::exportAs( + "GMLIB_API", + "setItemCanDestroy", + [](ItemStack const* item, std::vector blocks) -> void { + ((GMLIB_ItemStack*)item)->setCanDestroy(blocks); + } + ); + RemoteCall::exportAs("GMLIB_API", "getItemCanPlaceOn", [](ItemStack const* item) -> std::vector { + std::vector result = {}; + for (auto& block : ((GMLIB_ItemStack*)item)->getCanPlaceOn()) { + result.push_back(block->getTypeName()); + } + return result; + }); + RemoteCall::exportAs( + "GMLIB_API", + "setItemCanPlaceOn", + [](ItemStack const* item, std::vector blocks) -> void { + ((GMLIB_ItemStack*)item)->setCanPlaceOn(blocks); + } + ); } \ No newline at end of file From cd1933519a8ecfeefea5a543bc1cc97abe014a5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=90=E6=B2=90=E5=91=80?= <163636894+zimuya4153@users.noreply.github.com> Date: Fri, 12 Jul 2024 19:01:59 +0800 Subject: [PATCH 12/37] =?UTF-8?q?=E4=BF=AE=E5=A4=8DsetItemShouldKeepOnDeat?= =?UTF-8?q?h=E6=8E=A5=E5=8F=A3=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/CompatibilityApi.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/CompatibilityApi.cpp b/src/CompatibilityApi.cpp index 063af08..fb9eea2 100644 --- a/src/CompatibilityApi.cpp +++ b/src/CompatibilityApi.cpp @@ -1,5 +1,6 @@ #include "Global.h" #include +#include bool isInteger(const std::string& str) { std::regex pattern("^[+-]?\\d+$"); @@ -790,7 +791,7 @@ void Export_Compatibility_API() { return ((GMLIB_ItemStack*)item)->getShouldKeepOnDeath(); }); RemoteCall::exportAs("GMLIB_API", "setItemShouldKeepOnDeath", [](ItemStack const* item, bool value) -> void { - ((GMLIB_ItemStack*)item)->setShouldKeepOnDeath(true); + ((GMLIB_ItemStack*)item)->setShouldKeepOnDeath(value); }); RemoteCall::exportAs("GMLIB_API", "getItemLockMode", [](ItemStack const* item) -> int { return (int)((GMLIB_ItemStack*)item)->getItemLockMode(); From a47f8c729d221a097630f0843ba3ffd315868b25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=90=E6=B2=90=E5=91=80?= <163636894+zimuya4153@users.noreply.github.com> Date: Sat, 13 Jul 2024 13:13:40 +0800 Subject: [PATCH 13/37] =?UTF-8?q?=E5=A2=9E=E5=8A=A03=E4=B8=AA=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - getPlayerHungry - getPlayerArmorCoverPercentage - getPlayerArmorValue --- lib/GMLIB_API-JS.d.ts | 9 +++++++++ lib/GMLIB_API-JS.js | 35 ++++++++++++++++++++++++++++++++++- src/CompatibilityApi.cpp | 10 ++++++++++ 3 files changed, 53 insertions(+), 1 deletion(-) diff --git a/lib/GMLIB_API-JS.d.ts b/lib/GMLIB_API-JS.d.ts index 8dfeb69..b21eeff 100644 --- a/lib/GMLIB_API-JS.d.ts +++ b/lib/GMLIB_API-JS.d.ts @@ -1229,4 +1229,13 @@ interface Item { /** 能放置的方块 */ blocks: string[] ): void; + + /** (GMLIB)获取玩家饱食度 */ + getHungry(): number; + + /** (GMLIB)获取玩家盔甲覆盖百分比 */ + getArmorCoverPercentage(): number; + + /** (GMLIB)获取玩家盔甲值 */ + getArmorValue(): number; } \ No newline at end of file diff --git a/lib/GMLIB_API-JS.js b/lib/GMLIB_API-JS.js index 6beaeac..a9d3e1c 100644 --- a/lib/GMLIB_API-JS.js +++ b/lib/GMLIB_API-JS.js @@ -311,7 +311,13 @@ const GMLIB_API = { /** 获取物品冒险模式下能放置在什么方块上 @type {function(Item):Array.} */ getItemCanPlaceOn: ll.import("GMLIB_API", "getItemCanPlaceOn"), /** 设置物品冒险模式下能放置在什么方块上 @type {function(Item,Array.):void} */ - setItemCanPlaceOn: ll.import("GMLIB_API", "setItemCanPlaceOn") + setItemCanPlaceOn: ll.import("GMLIB_API", "setItemCanPlaceOn"), + /** 获取玩家饱食度 @type {function(Player):number} */ + getPlayerHungry: ll.import("GMLIB_API", "getPlayerHungry"), + /** 获取玩家盔甲覆盖百分比 @type {function(Player):number} */ + getPlayerArmorCoverPercentage: ll.import("GMLIB_API", "getPlayerArmorCoverPercentage"), + /** 获取玩家盔甲值 @type {function(Player):number} */ + getPlayerArmorValue: ll.import("GMLIB_API", "getPlayerArmorValue"), } /** 静态悬浮字类列表 @type {Map} */ @@ -2345,6 +2351,33 @@ LLSE_Item.prototype.setCanPlaceOn = GMLIB_API.setItemCanPlaceOn(this, blocks); } +LLSE_Player.prototype.getHungry = + /** + * 获取玩家饱食度 + * @returns {number} + */ + function () { + return GMLIB_API.getPlayerHungry(this) + } + +LLSE_Player.prototype.getArmorCoverPercentage = + /** + * 获取玩家盔甲覆盖百分比 + * @returns {number} + */ + function () { + return GMLIB_API.getPlayerArmorCoverPercentage(this) + } + +LLSE_Player.prototype.getArmorValue = + /** + * 获取玩家盔甲值覆盖百分比 + * @returns {number} + */ + function () { + return GMLIB_API.getPlayerArmorValue(this) + } + module.exports = { StaticFloatingText, DynamicFloatingText, diff --git a/src/CompatibilityApi.cpp b/src/CompatibilityApi.cpp index fb9eea2..9503c39 100644 --- a/src/CompatibilityApi.cpp +++ b/src/CompatibilityApi.cpp @@ -1,4 +1,5 @@ #include "Global.h" +#include "mc/enums/AbilitiesIndex.h" #include #include @@ -833,4 +834,13 @@ void Export_Compatibility_API() { ((GMLIB_ItemStack*)item)->setCanPlaceOn(blocks); } ); + RemoteCall::exportAs("GMLIB_API", "getPlayerHungry", [](Player* player) -> float { + return player->getMutableAttribute(Player::HUNGER)->getCurrentValue(); + }); + RemoteCall::exportAs("GMLIB_API", "getPlayerArmorCoverPercentage", [](Player* player) -> float { + return player->getArmorCoverPercentage(); + }); + RemoteCall::exportAs("GMLIB_API", "getPlayerArmorValue", [](Player* player) -> int { + return player->getArmorValue(); + }); } \ No newline at end of file From 52897a25a7c40438a5ef8da022d60746856b3c04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=90=E6=B2=90=E5=91=80?= <163636894+zimuya4153@users.noreply.github.com> Date: Thu, 18 Jul 2024 21:39:49 +0800 Subject: [PATCH 14/37] =?UTF-8?q?1=E6=96=B0=E5=A2=9E=202=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增getEntityOwnerUniqueId接口 - 修复注册PAPI变量无法使用匿名函数 - 修复注册相同PAPI名字无法重载 --- lib/BEPlaceholderAPI-JS.js | 29 ++++++++++++++++++++--------- lib/GMLIB_API-JS.d.ts | 3 +++ lib/GMLIB_API-JS.js | 18 +++++++++++++++--- src/CompatibilityApi.cpp | 5 +++++ src/PlaceholderApi.cpp | 4 ++++ 5 files changed, 47 insertions(+), 12 deletions(-) diff --git a/lib/BEPlaceholderAPI-JS.js b/lib/BEPlaceholderAPI-JS.js index 6d5af74..b2ce12d 100644 --- a/lib/BEPlaceholderAPI-JS.js +++ b/lib/BEPlaceholderAPI-JS.js @@ -19,14 +19,25 @@ const PlaceholderAPI = { getAllPAPI: ll.import("BEPlaceholderAPI", "getAllPAPI") } -Function.prototype.getName = -/** - * 获取函数名字 - * @returns {string} - */ -function () { - return this.name || this.toString().match(/function\s*([^(]*)\(/)[1] || Math.ceil(Math.random() * 1000000).toString(16); -} +Function.prototype.getName = + /** + * 获取函数名字 + * @returns {string} + */ + function () { + return this.name || this.toString().match(/function\s*([^(]*)\(/)?.[1] || this.toString().hashCode().toString(16); + } + +String.prototype.hashCode = function () { + var hash = 0, i, chr; + if (this.length === 0) return hash; + for (i = 0; i < this.length; i++) { + chr = this.charCodeAt(i); + hash = ((hash << 5) - hash) + chr; + hash |= 0; + } + return hash; +}; /** PAPI变量类 */ class PAPI { @@ -79,7 +90,7 @@ class PAPI { static getValue(key) { return PlaceholderAPI.getValueAPI(key); } - + /** * 获取一个玩家变量的值 * @param {string} key PAPI变量名 diff --git a/lib/GMLIB_API-JS.d.ts b/lib/GMLIB_API-JS.d.ts index b21eeff..4d6380b 100644 --- a/lib/GMLIB_API-JS.d.ts +++ b/lib/GMLIB_API-JS.d.ts @@ -1083,6 +1083,9 @@ interface Entity { /** (GMLIB)获取实体的命名 */ getNameTag(): string; + + /** 获取实体的主人 */ + getEntityOwner(): Entity | null; } interface Block { diff --git a/lib/GMLIB_API-JS.js b/lib/GMLIB_API-JS.js index a9d3e1c..acb42d9 100644 --- a/lib/GMLIB_API-JS.js +++ b/lib/GMLIB_API-JS.js @@ -318,6 +318,8 @@ const GMLIB_API = { getPlayerArmorCoverPercentage: ll.import("GMLIB_API", "getPlayerArmorCoverPercentage"), /** 获取玩家盔甲值 @type {function(Player):number} */ getPlayerArmorValue: ll.import("GMLIB_API", "getPlayerArmorValue"), + /** 获取实体主人的UniqueID @type {function(Entity):Entity} */ + getEntityOwnerUniqueId: ll.import("GMLIB_API", "getEntityOwnerUniqueId") } /** 静态悬浮字类列表 @type {Map} */ @@ -2357,7 +2359,7 @@ LLSE_Player.prototype.getHungry = * @returns {number} */ function () { - return GMLIB_API.getPlayerHungry(this) + return GMLIB_API.getPlayerHungry(this); } LLSE_Player.prototype.getArmorCoverPercentage = @@ -2366,7 +2368,7 @@ LLSE_Player.prototype.getArmorCoverPercentage = * @returns {number} */ function () { - return GMLIB_API.getPlayerArmorCoverPercentage(this) + return GMLIB_API.getPlayerArmorCoverPercentage(this); } LLSE_Player.prototype.getArmorValue = @@ -2375,7 +2377,17 @@ LLSE_Player.prototype.getArmorValue = * @returns {number} */ function () { - return GMLIB_API.getPlayerArmorValue(this) + return GMLIB_API.getPlayerArmorValue(this); + } + +LLSE_Player.prototype.getEntityOwner = + /** + * 获取实体的主人 + * @returns {Entity|null} + */ + function () { + const uniqueId = GMLIB_API.getEntityOwnerUniqueId(this); + return uniqueId === -1 ? null : Minecraft.getEntityFromUniqueId(uniqueId); } module.exports = { diff --git a/src/CompatibilityApi.cpp b/src/CompatibilityApi.cpp index 9503c39..c4cf94b 100644 --- a/src/CompatibilityApi.cpp +++ b/src/CompatibilityApi.cpp @@ -1,5 +1,9 @@ #include "Global.h" +#include "magic_enum.hpp" +#include "mc/entity/systems/common/ServerCameraStateSystem.h" #include "mc/enums/AbilitiesIndex.h" +#include "mc/scripting/modules/minecraft/ScriptCameraSetLocationOptions.h" +#include "mc/world/actor/common/CameraInstruction.h" #include #include @@ -843,4 +847,5 @@ void Export_Compatibility_API() { RemoteCall::exportAs("GMLIB_API", "getPlayerArmorValue", [](Player* player) -> int { return player->getArmorValue(); }); + RemoteCall::exportAs("GMLIB_API", "getEntityOwnerUniqueId", [](Actor* entity) -> int64 { return entity->getOwnerId().id; }); } \ No newline at end of file diff --git a/src/PlaceholderApi.cpp b/src/PlaceholderApi.cpp index 16341c4..a01a164 100644 --- a/src/PlaceholderApi.cpp +++ b/src/PlaceholderApi.cpp @@ -1,3 +1,4 @@ +#include "GMLIB/Server/PlaceholderAPI.h" #include "Global.h" #include @@ -25,6 +26,7 @@ bool registerPlayerPlaceholder( std::string const& PAPIName ) { if (RemoteCall::hasFunc(PluginName, FuncName)) { + PlaceholderAPI::unregisterPlaceholder(PAPIName); if (isParameters(PAPIName)) { auto Call = RemoteCall::importAs)>( PluginName, @@ -54,6 +56,7 @@ bool registerServerPlaceholder( std::string const& PAPIName ) { if (RemoteCall::hasFunc(PluginName, FuncName)) { + PlaceholderAPI::unregisterPlaceholder(PAPIName); if (isParameters(PAPIName)) { auto Call = RemoteCall::importAs)>(PluginName, FuncName); @@ -78,6 +81,7 @@ bool registerStaticPlaceholder( int num ) { if (RemoteCall::hasFunc(PluginName, FuncName)) { + PlaceholderAPI::unregisterPlaceholder(PAPIName); if (isParameters(PAPIName)) { auto Call = RemoteCall::importAs(PluginName, FuncName); if (num == -1) { From 55424a447b1c5cf79f27f540e36bddea5f3e6503 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=90=E6=B2=90=E5=91=80?= <163636894+zimuya4153@users.noreply.github.com> Date: Thu, 18 Jul 2024 21:51:05 +0800 Subject: [PATCH 15/37] =?UTF-8?q?=E5=88=A0=E9=99=A4=E5=A4=9A=E4=BD=99inclu?= =?UTF-8?q?de?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/CompatibilityApi.cpp | 6 ------ src/PlaceholderApi.cpp | 1 - 2 files changed, 7 deletions(-) diff --git a/src/CompatibilityApi.cpp b/src/CompatibilityApi.cpp index c4cf94b..d7180db 100644 --- a/src/CompatibilityApi.cpp +++ b/src/CompatibilityApi.cpp @@ -1,11 +1,5 @@ #include "Global.h" -#include "magic_enum.hpp" -#include "mc/entity/systems/common/ServerCameraStateSystem.h" -#include "mc/enums/AbilitiesIndex.h" -#include "mc/scripting/modules/minecraft/ScriptCameraSetLocationOptions.h" -#include "mc/world/actor/common/CameraInstruction.h" #include -#include bool isInteger(const std::string& str) { std::regex pattern("^[+-]?\\d+$"); diff --git a/src/PlaceholderApi.cpp b/src/PlaceholderApi.cpp index a01a164..626b11e 100644 --- a/src/PlaceholderApi.cpp +++ b/src/PlaceholderApi.cpp @@ -1,4 +1,3 @@ -#include "GMLIB/Server/PlaceholderAPI.h" #include "Global.h" #include From c544569bd8539f11c03a08cb5bb8a11973d2c86c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=90=E6=B2=90=E5=91=80?= <163636894+zimuya4153@users.noreply.github.com> Date: Fri, 19 Jul 2024 00:17:48 +0800 Subject: [PATCH 16/37] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/BEPlaceholderAPI-JS.d.ts | 9 +++++++-- lib/BEPlaceholderAPI-JS.js | 19 +++++++++++------- lib/EventAPI-JS.d.ts | 2 +- lib/GMLIB_API-JS.d.ts | 38 ++++++++++++++++++------------------ lib/GMLIB_API-JS.js | 36 +++++++++++++++++----------------- src/CompatibilityApi.cpp | 15 +++++++++----- 6 files changed, 67 insertions(+), 52 deletions(-) diff --git a/lib/BEPlaceholderAPI-JS.d.ts b/lib/BEPlaceholderAPI-JS.d.ts index 0328a22..e28b63e 100644 --- a/lib/BEPlaceholderAPI-JS.d.ts +++ b/lib/BEPlaceholderAPI-JS.d.ts @@ -4,7 +4,9 @@ declare class PAPI { /** PAPI调用函数 */ func: ( /** 玩家对象 */ - player: Player + player: Player, + /** 变量参数 */ + param: null | object. ) => string, /** 插件名字 */ pluginsName: string, @@ -15,7 +17,10 @@ declare class PAPI { /** 注册一个服务器PAPI变量 */ static registerServerPlaceholder( /** PAPI调用函数 */ - func: () => string, + func: ( + /** 变量参数 */ + param: null | object. + ) => string, /** 插件名字 */ pluginsName: string, /** PAPI变量 */ diff --git a/lib/BEPlaceholderAPI-JS.js b/lib/BEPlaceholderAPI-JS.js index b2ce12d..64274ec 100644 --- a/lib/BEPlaceholderAPI-JS.js +++ b/lib/BEPlaceholderAPI-JS.js @@ -25,19 +25,24 @@ Function.prototype.getName = * @returns {string} */ function () { - return this.name || this.toString().match(/function\s*([^(]*)\(/)?.[1] || this.toString().hashCode().toString(16); + return this.name || this.toString().match(/function\s*([^(]*)\(/)?.[1] || getStringHashCode(this.toString()).toString(16); } -String.prototype.hashCode = function () { - var hash = 0, i, chr; - if (this.length === 0) return hash; - for (i = 0; i < this.length; i++) { - chr = this.charCodeAt(i); +/** + * 获取字符串哈希值 + * @param {string} str 字符串 + * @returns {number} + */ +function getStringHashCode(str) { + let hash = 0, chr; + if (str.length === 0) return hash; + for (let i = 0; i < str.length; i++) { + chr = str.charCodeAt(i); hash = ((hash << 5) - hash) + chr; hash |= 0; } return hash; -}; +} /** PAPI变量类 */ class PAPI { diff --git a/lib/EventAPI-JS.d.ts b/lib/EventAPI-JS.d.ts index 10eb645..cb6e598 100644 --- a/lib/EventAPI-JS.d.ts +++ b/lib/EventAPI-JS.d.ts @@ -63,7 +63,7 @@ declare class Event { /** 掉落物生成完毕(不可以拦截) */ static listen( /** 事件名 */ - event: "onItemTrySpawn", + event: "onItemSpawned", /** 回调函数 */ listener: ( /** 物品对象 */ diff --git a/lib/GMLIB_API-JS.d.ts b/lib/GMLIB_API-JS.d.ts index 4d6380b..1a7cf32 100644 --- a/lib/GMLIB_API-JS.d.ts +++ b/lib/GMLIB_API-JS.d.ts @@ -219,7 +219,7 @@ declare class Minecraft { static spawnEntity( /** 生成坐标 */ pos: FloatPos, - /** 实体命名空间 */ + /** 实体命名空间ID */ name: string ): Entity; @@ -227,7 +227,7 @@ declare class Minecraft { static shootProjectile( /** 实体对象 */ entity: Entity, - /** 投射物命名空间 */ + /** 投射物命名空间ID */ proj: string, /** 速度 */ speed: number, @@ -286,7 +286,7 @@ declare class Minecraft { /** 获取方块runtimeId */ static getBlockRuntimeId( - /** 方块命名空间 */ + /** 方块命名空间ID */ block: string, /** 方块的特殊值 */ legacyData: Number | undefined @@ -330,18 +330,18 @@ declare class Minecraft { isBinary: boolean | undefined ): NbtCompound; - /** 根据命名空间获取翻译键名 */ + /** 根据命名空间ID获取翻译键名 */ static getBlockTranslateKeyFromName( - /** 方块命名空间 */ + /** 方块命名空间ID */ name: string ): string; - /** 获取存档种子号 */ + /** 获取存档种子 */ static getLevelSeed(): string; /** 获取方块亮度 */ static getBlockLightEmission( - /** 方块的命名空间 */ + /** 方块的命名空间ID */ block: string, /** 方块的特殊值 */ legacyData: number @@ -352,13 +352,13 @@ declare class Minecraft { /** 获取附魔名字和等级 */ static getEnchantNameAndLevel( - /** 附魔命名空间 */ + /** 附魔命名空间ID */ typeName: string, /** 附魔的等级 */ level: number ): string; - /** 通过附魔ID获取附魔命名空间 */ + /** 通过附魔ID获取附魔命名空间ID */ static getMaxPlayers( /** 附魔ID */ id: number @@ -468,7 +468,7 @@ declare class Recipes { result: string, /** 合成结果的数量 */ count: number | undefined, - /** 解锁条件(也可以填物品命名空间) */ + /** 解锁条件(也可以填物品命名空间ID) */ unlock: "AlwaysUnlocked" | "PlayerHasManyItems" | "PlayerInWater" | "None" | undefined ): boolean; @@ -482,7 +482,7 @@ declare class Recipes { result: string, /** 合成结果的数量 */ count: number | undefined, - /** 解锁条件(也可以填物品命名空间) */ + /** 解锁条件(也可以填物品命名空间ID) */ unlock: "AlwaysUnlocked" | "PlayerHasManyItems" | "PlayerInWater" | "None" | undefined ): boolean; } @@ -760,15 +760,15 @@ declare class JsonConfig { ): void; /** 获取所有数据 */ - getData(): object; + getData(): Record; /** 读取数据 */ - get( + get( /** 键名 */ key: string, /** 不存在返回值 */ - defaultValue: any - ): any; + defaultValue: T + ): T; /** 设置数据 */ set( @@ -1039,7 +1039,7 @@ interface Player { interface Entity { /** (GMLIB)射弹投射物 */ shootProjectile( - /** 投射物命名空间 */ + /** 投射物命名空间ID */ proj: string, /** 速度 */ speed: number | undefined, @@ -1156,7 +1156,7 @@ interface Item { /** (GMLIB)添加附魔 */ applyEnchant( - /** 附魔的命名空间 */ + /** 附魔的命名空间ID */ typeName: string, /** 附魔等级 */ level: number, @@ -1169,13 +1169,13 @@ interface Item { /** (GMLIB)判断是否拥有附魔 */ hasEnchant( - /** 附魔的命名空间 */ + /** 附魔的命名空间ID */ typeName: string ): boolean; /** (GMLIB)获取附魔等级 */ getEnchantLevel( - /** 附魔的命名空间 */ + /** 附魔的命名空间ID */ typeName: string ): number; diff --git a/lib/GMLIB_API-JS.js b/lib/GMLIB_API-JS.js index acb42d9..820f747 100644 --- a/lib/GMLIB_API-JS.js +++ b/lib/GMLIB_API-JS.js @@ -258,7 +258,7 @@ const GMLIB_API = { playerPullInEntity: ll.import("GMLIB_API", "playerPullInEntity"), /** 根据命令空间获取翻译键名 @type {function(string):string} */ getBlockTranslateKeyFromName: ll.import("GMLIB_API", "getBlockTranslateKeyFromName"), - /** 获取存档种子号 @type {function():string} */ + /** 获取存档种子 @type {function():string} */ getLevelSeed: ll.import("GMLib_ServerAPI", "getLevelSeed"), /** 获取方块亮度 @type {function(string,number):number} */ getBlockLightEmission: ll.import("GMLIB_API", "getBlockLightEmission"), @@ -276,7 +276,7 @@ const GMLIB_API = { getEnchantLevel: ll.import("GMLIB_API", "getEnchantLevel"), /** 获取附魔名字 @type {function(string,number):number} */ getEnchantNameAndLevel: ll.import("GMLIB_API", "getEnchantNameAndLevel"), - /** 通过ID获取附魔命名空间 @type {function(number):string} */ + /** 通过ID获取附魔命名空间ID @type {function(number):string} */ getEnchantTypeNameFromId: ll.import("GMLIB_API", "getEnchantTypeNameFromId"), /** 获取最大玩家数 @type {function():number} */ getMaxPlayers: ll.import("GMLib_ServerAPI", "getMaxPlayers"), @@ -765,7 +765,7 @@ class Minecraft { /** * 强制生成实体 * @param {FloatPos} pos 要生成的坐标 - * @param {string} name 实体命名空间 + * @param {string} name 实体命名空间ID * @returns {boolean} 是否成功生成实体 */ static spawnEntity(pos, name) { @@ -775,7 +775,7 @@ class Minecraft { /** * 射弹投射物 * @param {Entity} entity 实体对象 - * @param {string} proj 投射物命名空间 + * @param {string} proj 投射物命名空间ID * @param {number} [speed=2] 速度 * @param {number} [offset=3] 偏移量 * @returns {boolean} 是否成功投射投射物 @@ -861,7 +861,7 @@ class Minecraft { /** * 获取方块runtimeId - * @param {string} block 方块命名空间 + * @param {string} block 方块命名空间ID * @param {number} [legacyData=0] 方块的特殊值 * @returns {number} 方块的runtimeId */ @@ -925,8 +925,8 @@ class Minecraft { } /** - * 根据命名空间获取翻译键名 - * @param {string} name 方块的命名空间 + * 根据命名空间ID获取翻译键名 + * @param {string} name 方块的命名空间ID * @returns {string} 方块的翻译键名 */ static getBlockTranslateKeyFromName(name) { @@ -934,7 +934,7 @@ class Minecraft { } /** - * 获取存档种子号 + * 获取存档种子 */ static getLevelSeed() { return GMLIB_API.getLevelSeed(); @@ -942,7 +942,7 @@ class Minecraft { /** * 获取方块亮度 - * @param {string} block 方块的命名空间 + * @param {string} block 方块的命名空间ID * @param {number} [legacyData=0] 方块的特殊值 * @returns {number} 方块的亮度(-1为不存在) */ @@ -975,7 +975,7 @@ class Minecraft { /** * 获取附魔名字和等级 - * @param {string} typeName 附魔的命名空间 + * @param {string} typeName 附魔的命名空间ID * @param {number} level 附魔等级 * @returns {string} 文本 */ @@ -984,9 +984,9 @@ class Minecraft { } /** - * 通过附魔ID获取附魔命名空间 + * 通过附魔ID获取附魔命名空间ID * @param {number} id 附魔ID - * @returns {string?} 附魔的命名空间 + * @returns {string?} 附魔的命名空间ID */ static getEnchantTypeNameFromId(id) { const result = GMLIB_API.getEnchantTypeNameFromId(id); @@ -1085,7 +1085,7 @@ class Recipes { * @param {string} recipeId 合成表唯一标识 * @param {string} input 输入材料 * @param {string} output 合成结果 - * @param {Array.<"furnace"|"blast_furnace"|"smoker"|"campfire"|"soul_campfire">} [tags=["furnace"]] 材料的标签数组 + * @param {Array.} [tags=["furnace"]] 材料的标签数组 * @returns {boolean} 是否注册成功 */ static registerFurnaceRecipe(recipeId, input, output, tags = ["furnace"]) { @@ -1099,7 +1099,7 @@ class Recipes { * @param {Array.} ingredients 材料数组 * @param {string} result 合成结果 * @param {string} [count=1] 合成结果的数量 - * @param {"AlwaysUnlocked"|"PlayerHasManyItems"|"PlayerInWater"|"None"} [unlock=AlwaysUnlocked] 解锁条件(也可以填物品命名空间) + * @param {string} [unlock=AlwaysUnlocked] 解锁条件(也可以填物品命名空间ID) * @returns {boolean} 是否注册成功 */ static registerShapedRecipe(recipeId, shape, ingredients, result, count = 1, unlock = "AlwaysUnlocked") { @@ -1112,7 +1112,7 @@ class Recipes { * @param {Array.} ingredients 合成材料 * @param {string} result 合成结果 * @param {number} [count=1] 合成数量 - * @param {"AlwaysUnlocked"|"PlayerHasManyItems"|"PlayerInWater"|"None"} [unlock=AlwaysUnlocked] 解锁条件(也可以填物品命名空间) + * @param {string} [unlock=AlwaysUnlocked] 解锁条件(也可以填物品命名空间ID) * @returns {boolean} 是否注册成功 */ static registerShapelessRecipe(recipeId, ingredients, result, count = 1, unlock = "AlwaysUnlocked") { @@ -1975,7 +1975,7 @@ LLSE_Player.prototype.clearSpawnPoint = LLSE_Entity.prototype.shootProjectile = /** * 射弹投射物 - * @param {string} proj 投射物命名空间 + * @param {string} proj 投射物命名空间ID * @param {number} [speed=2] 速度 * @param {number} [offset=3] 偏移量 * @returns {boolean} 是射弹投射物 @@ -2170,7 +2170,7 @@ LLSE_Item.prototype.getLegalEnchants = LLSE_Item.prototype.applyEnchant = /** * 添加附魔 - * @param {string} typeName 附魔的命名空间 + * @param {string} typeName 附魔的命名空间ID * @param {number} level 等级 * @param {boolean} allowNonVanilla 允许非原版附魔 * @returns {boolean} 是否附魔成功 @@ -2190,7 +2190,7 @@ LLSE_Item.prototype.removeEnchants = LLSE_Item.prototype.hasEnchant = /** * 判断是否拥有附魔 - * @param {number} typeName 附魔的命名空间 + * @param {number} typeName 附魔的命名空间ID * @returns {boolean} 是否拥有附魔 */ function (typeName) { diff --git a/src/CompatibilityApi.cpp b/src/CompatibilityApi.cpp index d7180db..cca5ae3 100644 --- a/src/CompatibilityApi.cpp +++ b/src/CompatibilityApi.cpp @@ -740,7 +740,7 @@ void Export_Compatibility_API() { "applyEnchant", [](ItemStack const* item, std::string const& typeName, int level, bool allowNonVanilla) -> bool { return EnchantUtils::applyEnchant( - (ItemStackBase&)*item, + *(const_cast(item)), Enchant::getEnchantTypeFromName(HashedString(typeName)), level, allowNonVanilla @@ -751,12 +751,15 @@ void Export_Compatibility_API() { EnchantUtils::removeEnchants((ItemStack&)*item); }); RemoteCall::exportAs("GMLIB_API", "hasEnchant", [](ItemStack const* item, std::string const& typeName) -> bool { - return EnchantUtils::hasEnchant(Enchant::getEnchantTypeFromName(HashedString(typeName)), (ItemStackBase&)*item); + return EnchantUtils::hasEnchant( + Enchant::getEnchantTypeFromName(HashedString(typeName)), + *(const_cast(item)) + ); }); RemoteCall::exportAs("GMLIB_API", "getEnchantLevel", [](ItemStack const* item, std::string const& typeName) -> int { return EnchantUtils::getEnchantLevel( Enchant::getEnchantTypeFromName(HashedString(typeName)), - (ItemStackBase&)*item + *(const_cast(item)) ); }); RemoteCall::exportAs( @@ -802,7 +805,7 @@ void Export_Compatibility_API() { return item->getBaseRepairCost(); }); RemoteCall::exportAs("GMLIB_API", "setItemRepairCost", [](ItemStack const* item, int cost) -> void { - ((ItemStackBase*)item)->setRepairCost(cost); + (*(const_cast(item))).setRepairCost(cost); }); RemoteCall::exportAs("GMLIB_API", "getItemCanDestroy", [](ItemStack const* item) -> std::vector { std::vector result = {}; @@ -841,5 +844,7 @@ void Export_Compatibility_API() { RemoteCall::exportAs("GMLIB_API", "getPlayerArmorValue", [](Player* player) -> int { return player->getArmorValue(); }); - RemoteCall::exportAs("GMLIB_API", "getEntityOwnerUniqueId", [](Actor* entity) -> int64 { return entity->getOwnerId().id; }); + RemoteCall::exportAs("GMLIB_API", "getEntityOwnerUniqueId", [](Actor* entity) -> int64 { + return entity->getOwnerId().id; + }); } \ No newline at end of file From ed472f10d8029d469a5a063c10327c748908cbdc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=90=E6=B2=90=E5=91=80?= <163636894+zimuya4153@users.noreply.github.com> Date: Fri, 19 Jul 2024 02:30:14 +0800 Subject: [PATCH 17/37] =?UTF-8?q?=E6=96=B0=E5=A2=9E4=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - getItemCategoryName - getItemCustomName - getItemEffecName - itemIsFood --- lib/GMLIB_API-JS.d.ts | 26 +++++++++++++++++------ lib/GMLIB_API-JS.js | 46 +++++++++++++++++++++++++++++++++++++++- src/CompatibilityApi.cpp | 15 +++++++++++++ 3 files changed, 79 insertions(+), 8 deletions(-) diff --git a/lib/GMLIB_API-JS.d.ts b/lib/GMLIB_API-JS.d.ts index 1a7cf32..2dbaa2d 100644 --- a/lib/GMLIB_API-JS.d.ts +++ b/lib/GMLIB_API-JS.d.ts @@ -760,7 +760,7 @@ declare class JsonConfig { ): void; /** 获取所有数据 */ - getData(): Record; + getData(): Record; /** 读取数据 */ get( @@ -1034,6 +1034,15 @@ interface Player { /** (GMLIB)获取玩家的rumtimeId */ getRuntimeId(): number; + + /** (GMLIB)获取玩家饱食度 */ + getHungry(): number; + + /** (GMLIB)获取玩家盔甲覆盖百分比 */ + getArmorCoverPercentage(): number; + + /** (GMLIB)获取玩家盔甲值 */ + getArmorValue(): number; } interface Entity { @@ -1233,12 +1242,15 @@ interface Item { blocks: string[] ): void; - /** (GMLIB)获取玩家饱食度 */ - getHungry(): number; + /** 获取物品分类名称 */ + getCategoryName(): string; - /** (GMLIB)获取玩家盔甲覆盖百分比 */ - getArmorCoverPercentage(): number; + /** 获取物品的命名 */ + getCustomName(): string; - /** (GMLIB)获取玩家盔甲值 */ - getArmorValue(): number; + /** 获取物品的BUFF效果名称 */ + getEffecName(): string; + + /** 物品是否为食物 */ + isFood(): boolean; } \ No newline at end of file diff --git a/lib/GMLIB_API-JS.js b/lib/GMLIB_API-JS.js index 820f747..86a58f7 100644 --- a/lib/GMLIB_API-JS.js +++ b/lib/GMLIB_API-JS.js @@ -319,7 +319,15 @@ const GMLIB_API = { /** 获取玩家盔甲值 @type {function(Player):number} */ getPlayerArmorValue: ll.import("GMLIB_API", "getPlayerArmorValue"), /** 获取实体主人的UniqueID @type {function(Entity):Entity} */ - getEntityOwnerUniqueId: ll.import("GMLIB_API", "getEntityOwnerUniqueId") + getEntityOwnerUniqueId: ll.import("GMLIB_API", "getEntityOwnerUniqueId"), + /** 获取物品分类名称 @type {function(Item):string} */ + getItemCategoryName: ll.import("GMLIB_API", "getItemCategoryName"), + /** 获取物品的命名 @type {function(Item):string} */ + getItemCustomName: ll.import("GMLIB_API", "getItemCustomName"), + /** 获取物品BUFF效果名称 @type {function(Item):string} */ + getItemEffecName: ll.import("GMLIB_API", "getItemEffecName"), + /** 物品是否为食物 @type {function(Item):boolean} */ + itemIsFood: ll.import("GMLIB_API", "itemIsFood") } /** 静态悬浮字类列表 @type {Map} */ @@ -2390,6 +2398,42 @@ LLSE_Player.prototype.getEntityOwner = return uniqueId === -1 ? null : Minecraft.getEntityFromUniqueId(uniqueId); } +LLSE_Item.prototype.getCategoryName = + /** + * 获取物品分类名称 + * @returns {string} + */ + function () { + return GMLIB_API.getItemCategoryName(this); + } + +LLSE_Item.prototype.getCustomName = + /** + * 获取物品的命名 + * @returns {string} + */ + function () { + return GMLIB_API.getItemCustomName(this); + } + +LLSE_Item.prototype.getEffecName = + /** + * 获取物品的BUFF效果名称 + * @returns {string} + */ + function () { + return GMLIB_API.getItemEffecName(this); + } + +LLSE_Item.prototype.isFood = + /** + * 物品是否为食物 + * @returns {boolean} + */ + function () { + return GMLIB_API.itemIsFood(this); + } + module.exports = { StaticFloatingText, DynamicFloatingText, diff --git a/src/CompatibilityApi.cpp b/src/CompatibilityApi.cpp index cca5ae3..557c5d7 100644 --- a/src/CompatibilityApi.cpp +++ b/src/CompatibilityApi.cpp @@ -847,4 +847,19 @@ void Export_Compatibility_API() { RemoteCall::exportAs("GMLIB_API", "getEntityOwnerUniqueId", [](Actor* entity) -> int64 { return entity->getOwnerId().id; }); + RemoteCall::exportAs("GMLIB_API", "getItemCategoryName", [](ItemStack const* item) -> std::string { + return item->getCategoryName(); + }); + RemoteCall::exportAs("GMLIB_API", "getItemCustomName", [](ItemStack const* item) -> std::string { + return item->getCustomName(); + }); + RemoteCall::exportAs("GMLIB_API", "getItemEffecName", [](ItemStack const* item) -> std::string { + return item->getEffectName(); + }); + RemoteCall::exportAs("GMLIB_API", "itemIsFood", [](ItemStack const* item) -> bool { + if (auto itemDef = item->getItem()) { + return itemDef->isFood(); + } + return false; + }); } \ No newline at end of file From cd088431f34922a8e6ae5b159f309f85a690fc1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=90=E6=B2=90=E5=91=80?= <163636894+zimuya4153@users.noreply.github.com> Date: Sat, 20 Jul 2024 17:00:47 +0800 Subject: [PATCH 18/37] =?UTF-8?q?=E6=B7=BB=E5=8A=A02=E4=B8=AA=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - setPlayerUIItem - getPlayerUIItem --- lib/GMLIB_API-JS.d.ts | 14 ++++++++++++++ lib/GMLIB_API-JS.js | 26 +++++++++++++++++++++++++- src/CompatibilityApi.cpp | 6 ++++++ 3 files changed, 45 insertions(+), 1 deletion(-) diff --git a/lib/GMLIB_API-JS.d.ts b/lib/GMLIB_API-JS.d.ts index 2dbaa2d..7aa1c4a 100644 --- a/lib/GMLIB_API-JS.d.ts +++ b/lib/GMLIB_API-JS.d.ts @@ -1043,6 +1043,20 @@ interface Player { /** (GMLIB)获取玩家盔甲值 */ getArmorValue(): number; + + /** (GMLIB)设置玩家UI栏物品 */ + setPlayerUIItem( + /** 槽位 */ + slot: number, + /** 物品 */ + item: Item + ): void; + + /** (GMLIB)获取玩家UI栏物品 */ + setPlayerUIItem( + /** 槽位 */ + slot: number + ): Item; } interface Entity { diff --git a/lib/GMLIB_API-JS.js b/lib/GMLIB_API-JS.js index 86a58f7..af2dea8 100644 --- a/lib/GMLIB_API-JS.js +++ b/lib/GMLIB_API-JS.js @@ -327,7 +327,11 @@ const GMLIB_API = { /** 获取物品BUFF效果名称 @type {function(Item):string} */ getItemEffecName: ll.import("GMLIB_API", "getItemEffecName"), /** 物品是否为食物 @type {function(Item):boolean} */ - itemIsFood: ll.import("GMLIB_API", "itemIsFood") + itemIsFood: ll.import("GMLIB_API", "itemIsFood"), + /** 设置玩家UI栏物品 @type {function(Player,number,Item):void} */ + setPlayerUIItem: ll.import("GMLIB_API", "setPlayerUIItem"), + /** 获取玩家UI栏物品 @type {function(Player,number):Item} */ + getPlayerUIItem: ll.import("GMLIB_API", "getPlayerUIItem") } /** 静态悬浮字类列表 @type {Map} */ @@ -2434,6 +2438,26 @@ LLSE_Item.prototype.isFood = return GMLIB_API.itemIsFood(this); } +LLSE_Player.prototype.setPlayerUIItem = + /** + * 设置玩家UI栏物品 + * @param {number} slot 格子槽位 + * @param {Item} item 要设置的物品 + */ + function (slot, item) { + return GMLIB_API.setPlayerUIItem(this, slot, item); + } + +LLSE_Player.prototype.setPlayerUIItem = + /** + * 获取玩家UI栏物品 + * @param {number} slot 格子槽位 + * @returns {Item} 物品对象 + */ + function (slot) { + return GMLIB_API.getPlayerUIItem(this, slot); + } + module.exports = { StaticFloatingText, DynamicFloatingText, diff --git a/src/CompatibilityApi.cpp b/src/CompatibilityApi.cpp index 557c5d7..02a607a 100644 --- a/src/CompatibilityApi.cpp +++ b/src/CompatibilityApi.cpp @@ -862,4 +862,10 @@ void Export_Compatibility_API() { } return false; }); + RemoteCall::exportAs("GMLIB_API", "setPlayerUIItem", [](Player* player, int slot, ItemStack const* item) -> void { + player->setPlayerUIItem((PlayerUISlot)slot, *item); + }); + RemoteCall::exportAs("GMLIB_API", "getPlayerUIItem", [](Player* player, int slot) -> void { + player->getPlayerUIItem((PlayerUISlot)slot); + }); } \ No newline at end of file From 7af336e4b0d9fbf239549b2a78c7e51e44d81b3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=90=E6=B2=90=E5=91=80?= <163636894+zimuya4153@users.noreply.github.com> Date: Sat, 20 Jul 2024 17:24:56 +0800 Subject: [PATCH 19/37] =?UTF-8?q?=E4=BF=AE=E5=A4=8DgetPlayerUIItem?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/GMLIB_API-JS.d.ts | 2 +- lib/GMLIB_API-JS.js | 2 +- src/CompatibilityApi.cpp | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/GMLIB_API-JS.d.ts b/lib/GMLIB_API-JS.d.ts index 7aa1c4a..ecedf22 100644 --- a/lib/GMLIB_API-JS.d.ts +++ b/lib/GMLIB_API-JS.d.ts @@ -1053,7 +1053,7 @@ interface Player { ): void; /** (GMLIB)获取玩家UI栏物品 */ - setPlayerUIItem( + getPlayerUIItem( /** 槽位 */ slot: number ): Item; diff --git a/lib/GMLIB_API-JS.js b/lib/GMLIB_API-JS.js index af2dea8..b83c7e8 100644 --- a/lib/GMLIB_API-JS.js +++ b/lib/GMLIB_API-JS.js @@ -2448,7 +2448,7 @@ LLSE_Player.prototype.setPlayerUIItem = return GMLIB_API.setPlayerUIItem(this, slot, item); } -LLSE_Player.prototype.setPlayerUIItem = +LLSE_Player.prototype.getPlayerUIItem = /** * 获取玩家UI栏物品 * @param {number} slot 格子槽位 diff --git a/src/CompatibilityApi.cpp b/src/CompatibilityApi.cpp index 02a607a..d4df1a8 100644 --- a/src/CompatibilityApi.cpp +++ b/src/CompatibilityApi.cpp @@ -865,7 +865,7 @@ void Export_Compatibility_API() { RemoteCall::exportAs("GMLIB_API", "setPlayerUIItem", [](Player* player, int slot, ItemStack const* item) -> void { player->setPlayerUIItem((PlayerUISlot)slot, *item); }); - RemoteCall::exportAs("GMLIB_API", "getPlayerUIItem", [](Player* player, int slot) -> void { - player->getPlayerUIItem((PlayerUISlot)slot); + RemoteCall::exportAs("GMLIB_API", "getPlayerUIItem", [](Player* player, int slot) -> ItemStack* { + return const_cast(&player->getPlayerUIItem((PlayerUISlot)slot)); }); } \ No newline at end of file From 8ee4e240f81651dcde254a13b9d23e613a544c07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=90=E6=B2=90=E5=91=80?= <163636894+zimuya4153@users.noreply.github.com> Date: Sat, 20 Jul 2024 21:50:54 +0800 Subject: [PATCH 20/37] =?UTF-8?q?=E6=96=B0=E5=A2=9ESendContainerClosePacke?= =?UTF-8?q?t=E4=BA=8B=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/EventAPI-JS.d.ts | 15 ++++++++++++++- src/EventAPI.cpp | 16 ++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/lib/EventAPI-JS.d.ts b/lib/EventAPI-JS.d.ts index cb6e598..638e1a2 100644 --- a/lib/EventAPI-JS.d.ts +++ b/lib/EventAPI-JS.d.ts @@ -215,10 +215,23 @@ declare class Event { player: Player, /** 请求类型 */ actionType: string, - /** 容器ID */ + /** 容器类型 */ ContainerNetId: string, /** 请求的槽位 */ slot: number ) => boolean | void ): boolean; + + /** 发送容器关闭数据包后(不可拦截) */ + static listen( + /** 事件名 */ + event: "SendContainerClosePacket", + /** 回调函数 */ + listener: ( + /** 要被关闭的玩家 */ + player: Player, + /** 容器类型 */ + ContainerNetId: string + ) => void + ): boolean; } diff --git a/src/EventAPI.cpp b/src/EventAPI.cpp index fae1556..f9a5d1a 100644 --- a/src/EventAPI.cpp +++ b/src/EventAPI.cpp @@ -289,6 +289,22 @@ void Export_Event_API() { ); return true; } + case doHash("SendContainerClosePacket"): { + auto Call = + RemoteCall::importAs(eventName, eventId); + eventBus->emplaceListener( + [Call](Event::PacketEvent::ContainerClosePacketSendAfterEvent& ev) { + try { + Call( + ev.getServerNetworkHandler() + .getServerPlayer(ev.getNetworkIdentifier(), ev.getPacket().mClientSubId), + magic_enum::enum_name(ev.getPacket().mContainerId).data() + ); + } catch (...) {} + } + ); + return true; + } default: return false; } From 6b01186f2321e3f28d642fc4877949cfd06a4627 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=90=E6=B2=90=E5=91=80?= <163636894+zimuya4153@users.noreply.github.com> Date: Sun, 21 Jul 2024 00:26:37 +0800 Subject: [PATCH 21/37] =?UTF-8?q?=E4=BF=AE=E5=A4=8DgetPlayerFromUuid?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/CompatibilityApi.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/CompatibilityApi.cpp b/src/CompatibilityApi.cpp index d4df1a8..9268450 100644 --- a/src/CompatibilityApi.cpp +++ b/src/CompatibilityApi.cpp @@ -510,8 +510,7 @@ void Export_Compatibility_API() { } ); RemoteCall::exportAs("GMLIB_API", "getPlayerFromUuid", [](std::string const& uuid) -> Player* { - auto uid = mce::UUID::fromString(uuid); - return ll::service::getLevel()->getPlayer(uuid); + return ll::service::getLevel()->getPlayer(mce::UUID::fromString(uuid)); }); RemoteCall::exportAs("GMLIB_API", "getPlayerFromUniqueId", [](std::string const& uniqueId) -> Actor* { auto auid = parseScriptUniqueID(uniqueId); From cf128f460d6917f3b5f280fabdd9a21f87bba745 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=90=E6=B2=90=E5=91=80?= <163636894+zimuya4153@users.noreply.github.com> Date: Sun, 21 Jul 2024 03:57:10 +0800 Subject: [PATCH 22/37] =?UTF-8?q?=E6=96=B0=E5=A2=9EsendInventorySlotPacket?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/GMLIB_API-JS.d.ts | 10 ++++++++++ lib/GMLIB_API-JS.js | 17 +++++++++++++++-- src/CompatibilityApi.cpp | 11 +++++++++++ 3 files changed, 36 insertions(+), 2 deletions(-) diff --git a/lib/GMLIB_API-JS.d.ts b/lib/GMLIB_API-JS.d.ts index ecedf22..41d072b 100644 --- a/lib/GMLIB_API-JS.d.ts +++ b/lib/GMLIB_API-JS.d.ts @@ -1057,6 +1057,16 @@ interface Player { /** 槽位 */ slot: number ): Item; + + /** (GMLIB)发送更新更新物品数据包 */ + sendInventorySlotPacket( + /** 容器ID */ + containerId: number, + /** 槽位 */ + slot: number, + /** 物品 */ + item: Item + ): void; } interface Entity { diff --git a/lib/GMLIB_API-JS.js b/lib/GMLIB_API-JS.js index b83c7e8..07a0383 100644 --- a/lib/GMLIB_API-JS.js +++ b/lib/GMLIB_API-JS.js @@ -331,7 +331,9 @@ const GMLIB_API = { /** 设置玩家UI栏物品 @type {function(Player,number,Item):void} */ setPlayerUIItem: ll.import("GMLIB_API", "setPlayerUIItem"), /** 获取玩家UI栏物品 @type {function(Player,number):Item} */ - getPlayerUIItem: ll.import("GMLIB_API", "getPlayerUIItem") + getPlayerUIItem: ll.import("GMLIB_API", "getPlayerUIItem"), + /** 更新玩家容器物品 @type {function(Player,number,number,Item):void} */ + sendInventorySlotPacket: ll.import("GMLIB_API","sendInventorySlotPacket") } /** 静态悬浮字类列表 @type {Map} */ @@ -2445,7 +2447,7 @@ LLSE_Player.prototype.setPlayerUIItem = * @param {Item} item 要设置的物品 */ function (slot, item) { - return GMLIB_API.setPlayerUIItem(this, slot, item); + GMLIB_API.setPlayerUIItem(this, slot, item); } LLSE_Player.prototype.getPlayerUIItem = @@ -2458,6 +2460,17 @@ LLSE_Player.prototype.getPlayerUIItem = return GMLIB_API.getPlayerUIItem(this, slot); } +LLSE_Player.prototype.sendInventorySlotPacket = + /** + * 发送更新更新物品数据包 + * @param {number} containerId 容器ID + * @param {number} slot 格子槽位 + * @param {Item} item 物品对象 + */ + function (containerId, slot, item) { + GMLIB_API.sendInventorySlotPacket(this, containerId, slot, item); + } + module.exports = { StaticFloatingText, DynamicFloatingText, diff --git a/src/CompatibilityApi.cpp b/src/CompatibilityApi.cpp index 9268450..991eba1 100644 --- a/src/CompatibilityApi.cpp +++ b/src/CompatibilityApi.cpp @@ -1,5 +1,9 @@ #include "Global.h" +#include "magic_enum.hpp" +#include "mc/network/packet/InventorySlotPacket.h" +#include #include +#include bool isInteger(const std::string& str) { std::regex pattern("^[+-]?\\d+$"); @@ -867,4 +871,11 @@ void Export_Compatibility_API() { RemoteCall::exportAs("GMLIB_API", "getPlayerUIItem", [](Player* player, int slot) -> ItemStack* { return const_cast(&player->getPlayerUIItem((PlayerUISlot)slot)); }); + RemoteCall::exportAs( + "GMLIB_API", + "sendInventorySlotPacket", + [](Player* player, int containerId, int slot, ItemStack* item) -> void { + InventorySlotPacket((ContainerID)containerId, slot, *item).sendTo(*player); + } + ); } \ No newline at end of file From 8ab2ee049792fa27e34a0e0e152493d675595696 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=90=E6=B2=90=E5=91=80?= <163636894+zimuya4153@users.noreply.github.com> Date: Sun, 21 Jul 2024 04:12:50 +0800 Subject: [PATCH 23/37] =?UTF-8?q?=E4=BF=AE=E5=A4=8D2=E4=BA=8B=E4=BB=B6?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - HandleRequestAction - SendContainerClosePacket --- lib/EventAPI-JS.d.ts | 8 ++++---- src/EventAPI.cpp | 5 ++--- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/lib/EventAPI-JS.d.ts b/lib/EventAPI-JS.d.ts index 638e1a2..735e00e 100644 --- a/lib/EventAPI-JS.d.ts +++ b/lib/EventAPI-JS.d.ts @@ -215,8 +215,8 @@ declare class Event { player: Player, /** 请求类型 */ actionType: string, - /** 容器类型 */ - ContainerNetId: string, + /** 容器ID */ + containerId: number, /** 请求的槽位 */ slot: number ) => boolean | void @@ -230,8 +230,8 @@ declare class Event { listener: ( /** 要被关闭的玩家 */ player: Player, - /** 容器类型 */ - ContainerNetId: string + /** 容器ID */ + containerId: number ) => void ): boolean; } diff --git a/src/EventAPI.cpp b/src/EventAPI.cpp index f9a5d1a..6f7d2f2 100644 --- a/src/EventAPI.cpp +++ b/src/EventAPI.cpp @@ -290,15 +290,14 @@ void Export_Event_API() { return true; } case doHash("SendContainerClosePacket"): { - auto Call = - RemoteCall::importAs(eventName, eventId); + auto Call = RemoteCall::importAs(eventName, eventId); eventBus->emplaceListener( [Call](Event::PacketEvent::ContainerClosePacketSendAfterEvent& ev) { try { Call( ev.getServerNetworkHandler() .getServerPlayer(ev.getNetworkIdentifier(), ev.getPacket().mClientSubId), - magic_enum::enum_name(ev.getPacket().mContainerId).data() + (int)ev.getPacket().mContainerId ); } catch (...) {} } From 7a0e3d80190f6e6db7ffd67559b0dd81e7aaee98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=90=E6=B2=90=E5=91=80?= <163636894+zimuya4153@users.noreply.github.com> Date: Sun, 21 Jul 2024 18:09:32 +0800 Subject: [PATCH 24/37] =?UTF-8?q?=E4=BF=AE=E5=A4=8DHandleRequestAction?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/EventAPI-JS.d.ts | 2 +- src/EventAPI.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/EventAPI-JS.d.ts b/lib/EventAPI-JS.d.ts index 735e00e..3fe4da5 100644 --- a/lib/EventAPI-JS.d.ts +++ b/lib/EventAPI-JS.d.ts @@ -234,4 +234,4 @@ declare class Event { containerId: number ) => void ): boolean; -} +} \ No newline at end of file diff --git a/src/EventAPI.cpp b/src/EventAPI.cpp index 6f7d2f2..a0bbbaf 100644 --- a/src/EventAPI.cpp +++ b/src/EventAPI.cpp @@ -266,7 +266,7 @@ void Export_Event_API() { } case doHash("HandleRequestAction"): { auto Call = RemoteCall::importAs< - bool(Player * player, std::string const& actionType, std::string const& ContainerNetId, int slot)>( + bool(Player * player, std::string const& actionType, int ContainerNetId, int slot)>( eventName, eventId ); @@ -278,7 +278,7 @@ void Export_Event_API() { result = Call( &ev.self(), magic_enum::enum_name(requestAction->mActionType).data(), - magic_enum::enum_name(requestAction->getSrc().mOpenContainerNetId).data(), + (int)requestAction->getSrc().mOpenContainerNetId, requestAction->getSrc().mSlot ); } catch (...) {} From f427f2f5e1491948d6ef011b74023842a06262cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=90=E6=B2=90=E5=91=80?= <163636894+zimuya4153@users.noreply.github.com> Date: Tue, 23 Jul 2024 05:59:08 +0800 Subject: [PATCH 25/37] =?UTF-8?q?=E6=96=B0=E5=A2=9E/=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增 - getContainerType 修改 - HandleRequestActionEvent --- lib/EventAPI-JS.d.ts | 4 ++-- lib/GMLIB_API-JS.d.ts | 13 +++++++++---- lib/GMLIB_API-JS.js | 12 +++++++++++- src/CompatibilityApi.cpp | 8 ++++++++ src/EventAPI.cpp | 4 ++-- 5 files changed, 32 insertions(+), 9 deletions(-) diff --git a/lib/EventAPI-JS.d.ts b/lib/EventAPI-JS.d.ts index 3fe4da5..249578f 100644 --- a/lib/EventAPI-JS.d.ts +++ b/lib/EventAPI-JS.d.ts @@ -215,8 +215,8 @@ declare class Event { player: Player, /** 请求类型 */ actionType: string, - /** 容器ID */ - containerId: number, + /** 容器枚举名 */ + containerNetId: string, /** 请求的槽位 */ slot: number ) => boolean | void diff --git a/lib/GMLIB_API-JS.d.ts b/lib/GMLIB_API-JS.d.ts index 41d072b..f7b3bf9 100644 --- a/lib/GMLIB_API-JS.d.ts +++ b/lib/GMLIB_API-JS.d.ts @@ -1266,15 +1266,20 @@ interface Item { blocks: string[] ): void; - /** 获取物品分类名称 */ + /** (GMLIB)获取物品分类名称 */ getCategoryName(): string; - /** 获取物品的命名 */ + /** (GMLIB)获取物品的命名 */ getCustomName(): string; - /** 获取物品的BUFF效果名称 */ + /** (GMLIB)获取物品的BUFF效果名称 */ getEffecName(): string; - /** 物品是否为食物 */ + /** (GMLIB)物品是否为食物 */ isFood(): boolean; +} + +interface Container { + /** (GMLIB)获取容器类型 */ + getContainerType(): string } \ No newline at end of file diff --git a/lib/GMLIB_API-JS.js b/lib/GMLIB_API-JS.js index 07a0383..25d3f94 100644 --- a/lib/GMLIB_API-JS.js +++ b/lib/GMLIB_API-JS.js @@ -333,7 +333,9 @@ const GMLIB_API = { /** 获取玩家UI栏物品 @type {function(Player,number):Item} */ getPlayerUIItem: ll.import("GMLIB_API", "getPlayerUIItem"), /** 更新玩家容器物品 @type {function(Player,number,number,Item):void} */ - sendInventorySlotPacket: ll.import("GMLIB_API","sendInventorySlotPacket") + sendInventorySlotPacket: ll.import("GMLIB_API", "sendInventorySlotPacket"), + /** 获取容器类型 @type {function(Container):string} */ + getContainerType: ll.import("GMLIB_API", "getContainerType") } /** 静态悬浮字类列表 @type {Map} */ @@ -2471,6 +2473,14 @@ LLSE_Player.prototype.sendInventorySlotPacket = GMLIB_API.sendInventorySlotPacket(this, containerId, slot, item); } +LLSE_Container.prototype.getContainerType = + /** + * 获取容器类型 + */ + function () { + return GMLIB_API.getContainerType(this); + } + module.exports = { StaticFloatingText, DynamicFloatingText, diff --git a/src/CompatibilityApi.cpp b/src/CompatibilityApi.cpp index 991eba1..a854dfb 100644 --- a/src/CompatibilityApi.cpp +++ b/src/CompatibilityApi.cpp @@ -1,6 +1,7 @@ #include "Global.h" #include "magic_enum.hpp" #include "mc/network/packet/InventorySlotPacket.h" +#include "mc/world/Container.h" #include #include #include @@ -878,4 +879,11 @@ void Export_Compatibility_API() { InventorySlotPacket((ContainerID)containerId, slot, *item).sendTo(*player); } ); + RemoteCall::exportAs( + "GMLIB_API", + "getContainerType", + [](Container* container) -> std::string { + return magic_enum::enum_name(container->getContainerType()).data(); + } + ); } \ No newline at end of file diff --git a/src/EventAPI.cpp b/src/EventAPI.cpp index a0bbbaf..c33c9ad 100644 --- a/src/EventAPI.cpp +++ b/src/EventAPI.cpp @@ -266,7 +266,7 @@ void Export_Event_API() { } case doHash("HandleRequestAction"): { auto Call = RemoteCall::importAs< - bool(Player * player, std::string const& actionType, int ContainerNetId, int slot)>( + bool(Player * player, std::string const& actionType, std::string const& containerNetId, int slot)>( eventName, eventId ); @@ -278,7 +278,7 @@ void Export_Event_API() { result = Call( &ev.self(), magic_enum::enum_name(requestAction->mActionType).data(), - (int)requestAction->getSrc().mOpenContainerNetId, + magic_enum::enum_name(requestAction->getSrc().mOpenContainerNetId).data(), requestAction->getSrc().mSlot ); } catch (...) {} From a5eb2e855a1b61b1480908e22dfbc37d94d5fda5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=90=E6=B2=90=E5=91=80?= <163636894+zimuya4153@users.noreply.github.com> Date: Tue, 23 Jul 2024 08:45:43 +0800 Subject: [PATCH 26/37] =?UTF-8?q?=E6=96=B0=E5=A2=9EhasPlayerNbt=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/GMLIB_API-JS.d.ts | 8 +++++++- lib/GMLIB_API-JS.js | 17 ++++++++++++++--- src/CompatibilityApi.cpp | 14 +++++++------- 3 files changed, 28 insertions(+), 11 deletions(-) diff --git a/lib/GMLIB_API-JS.d.ts b/lib/GMLIB_API-JS.d.ts index f7b3bf9..0dc3447 100644 --- a/lib/GMLIB_API-JS.d.ts +++ b/lib/GMLIB_API-JS.d.ts @@ -151,7 +151,7 @@ declare class Minecraft { /** 要设置的NBT数据 */ nbt: NbtCompound, /** 要覆盖的NBT标签 */ - tags: string + tags: string[] ): boolean; /** 删除玩家NBT */ @@ -366,6 +366,12 @@ declare class Minecraft { /** 获取最大玩家数 */ static getMaxPlayers(): number; + + /** 玩家是否拥有NBT */ + static hasPlayerNbt( + /** 玩家的uuid */ + uuid: string + ): boolean; } /** 合成表类 */ diff --git a/lib/GMLIB_API-JS.js b/lib/GMLIB_API-JS.js index 25d3f94..26ee6a5 100644 --- a/lib/GMLIB_API-JS.js +++ b/lib/GMLIB_API-JS.js @@ -30,7 +30,7 @@ const GMLIB_API = { getPlayerNbt: ll.import("GMLIB_API", "getPlayerNbt"), /** 设置玩家NBT @type {function(string,NbtCompound,boolean):boolean} */ setPlayerNbt: ll.import("GMLIB_API", "setPlayerNbt"), - /** 覆盖玩家的特定nbtTags @type {function(string,NbtCompound,string):boolean} */ + /** 覆盖玩家的特定nbtTags @type {function(string,NbtCompound,Array.):boolean} */ setPlayerNbtTags: ll.import("GMLIB_API", "setPlayerNbtTags"), /** 删除玩家所有的NBT @type {function(string):boolean} */ deletePlayerNbt: ll.import("GMLIB_API", "deletePlayerNbt"), @@ -335,7 +335,9 @@ const GMLIB_API = { /** 更新玩家容器物品 @type {function(Player,number,number,Item):void} */ sendInventorySlotPacket: ll.import("GMLIB_API", "sendInventorySlotPacket"), /** 获取容器类型 @type {function(Container):string} */ - getContainerType: ll.import("GMLIB_API", "getContainerType") + getContainerType: ll.import("GMLIB_API", "getContainerType"), + /** 玩家是否拥有NBT @type {function(string):boolean} */ + hasPlayerNbt: ll.import("GMLIB_API", "hasPlayerNbt") } /** 静态悬浮字类列表 @type {Map} */ @@ -656,7 +658,7 @@ class Minecraft { * 覆盖玩家NBT的特定Tags * @param {string} uuid 玩家的uuid * @param {NbtCompound} nbt 要写入的NBT - * @param {string} tags 要覆盖的NBT标签 + * @param {Array.} tags 要覆盖的NBT标签 * @returns {boolean} 是否成功写入NBT */ static setPlayerNbtTags(uuid, nbt, tags) { @@ -1016,6 +1018,15 @@ class Minecraft { static getMaxPlayers() { return GMLIB_API.getMaxPlayers(); } + + /** + * 玩家是否拥有NBT + * @param {string} uuid 玩家的uuid + * @returns 玩家是否拥有NBT + */ + static hasPlayerNbt(uuid) { + return GMLIB_API.hasPlayerNbt(uuid); + } } /** 合成表类 */ diff --git a/src/CompatibilityApi.cpp b/src/CompatibilityApi.cpp index a854dfb..3889da4 100644 --- a/src/CompatibilityApi.cpp +++ b/src/CompatibilityApi.cpp @@ -879,11 +879,11 @@ void Export_Compatibility_API() { InventorySlotPacket((ContainerID)containerId, slot, *item).sendTo(*player); } ); - RemoteCall::exportAs( - "GMLIB_API", - "getContainerType", - [](Container* container) -> std::string { - return magic_enum::enum_name(container->getContainerType()).data(); - } - ); + RemoteCall::exportAs("GMLIB_API", "getContainerType", [](Container* container) -> std::string { + return magic_enum::enum_name(container->getContainerType()).data(); + }); + RemoteCall::exportAs("GMLIB_API", "hasPlayerNbt", [](std::string const& uuid) -> bool { + auto uid = mce::UUID::fromString(uuid); + return GMLIB_Player::getPlayerNbt(uid) ? true : false; + }); } \ No newline at end of file From dda01660be2711db13fe6093fc2353bb48b553f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=90=E6=B2=90=E5=91=80?= <163636894+zimuya4153@users.noreply.github.com> Date: Thu, 25 Jul 2024 17:01:35 +0800 Subject: [PATCH 27/37] =?UTF-8?q?=E4=BF=AE=E6=94=B9HandleRequestAction?= =?UTF-8?q?=E4=BA=8B=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/EventAPI-JS.d.ts | 16 +++++++++++----- src/CompatibilityApi.cpp | 5 ----- src/EventAPI.cpp | 26 ++++++++++++++++++-------- 3 files changed, 29 insertions(+), 18 deletions(-) diff --git a/lib/EventAPI-JS.d.ts b/lib/EventAPI-JS.d.ts index 249578f..6be8885 100644 --- a/lib/EventAPI-JS.d.ts +++ b/lib/EventAPI-JS.d.ts @@ -123,7 +123,7 @@ declare class Event { /** 死亡信息键名 */ deathMsgKey: string, /** 死亡信息翻译参数 */ - deathMsgParams: Array., + deathMsgParams: string[], /** 死亡实体的实体对象 */ entity: Entity ) => void @@ -215,10 +215,16 @@ declare class Event { player: Player, /** 请求类型 */ actionType: string, - /** 容器枚举名 */ - containerNetId: string, - /** 请求的槽位 */ - slot: number + /** 请求数量 */ + count: number, + /** 第一个格子的容器类型 */ + sourceContainerNetId: string, + /** 第一个格子的槽位 */ + sourceSlot: number, + /** 第二个格子的容器类型 */ + destinationContainerNetId: string, + /** 第二个格子的槽位 */ + destinationSlot: number ) => boolean | void ): boolean; diff --git a/src/CompatibilityApi.cpp b/src/CompatibilityApi.cpp index 3889da4..00e10a1 100644 --- a/src/CompatibilityApi.cpp +++ b/src/CompatibilityApi.cpp @@ -1,10 +1,5 @@ #include "Global.h" -#include "magic_enum.hpp" -#include "mc/network/packet/InventorySlotPacket.h" -#include "mc/world/Container.h" -#include #include -#include bool isInteger(const std::string& str) { std::regex pattern("^[+-]?\\d+$"); diff --git a/src/EventAPI.cpp b/src/EventAPI.cpp index c33c9ad..e0134cb 100644 --- a/src/EventAPI.cpp +++ b/src/EventAPI.cpp @@ -265,21 +265,31 @@ void Export_Event_API() { return true; } case doHash("HandleRequestAction"): { - auto Call = RemoteCall::importAs< - bool(Player * player, std::string const& actionType, std::string const& containerNetId, int slot)>( - eventName, - eventId - ); + auto Call = RemoteCall::importAs(eventName, eventId); eventBus->emplaceListener( [Call](Event::PlayerEvent::HandleRequestActionBeforeEvent& ev) { bool result = true; try { auto requestAction = (ItemStackRequestActionTransferBase*)&ev.getRequestAction(); - result = Call( + auto source = requestAction->getSrc(); + // TODO: The next version of LeviLamina changes to a member function + auto destination = ll::memory::dAccess(requestAction, 56); + result = Call( &ev.self(), magic_enum::enum_name(requestAction->mActionType).data(), - magic_enum::enum_name(requestAction->getSrc().mOpenContainerNetId).data(), - requestAction->getSrc().mSlot + ll::memory::dAccess(requestAction, 18), + magic_enum::enum_name(source.mOpenContainerNetId).data(), + source.mSlot, + magic_enum::enum_name(destination.mOpenContainerNetId).data(), + destination.mSlot ); } catch (...) {} if (!result) { From 3b8a463b62bbc356e38c2f73cf012bf5d404433b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=90=E6=B2=90=E5=91=80?= <163636894+zimuya4153@users.noreply.github.com> Date: Mon, 29 Jul 2024 13:44:15 +0800 Subject: [PATCH 28/37] =?UTF-8?q?=E9=80=82=E9=85=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- manifest.json | 2 +- src/Entry.cpp | 2 +- src/Entry.h | 10 +++++----- src/Global.h | 2 +- tooth.json | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/manifest.json b/manifest.json index f7d01cd..147bfdd 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "name": "${pluginName}", "entry": "${pluginFile}", - "version": "0.13.0", + "version": "0.13.1", "author": "GroupMountain", "type": "native", "passive": true, diff --git a/src/Entry.cpp b/src/Entry.cpp index 0abb2b9..d761a55 100644 --- a/src/Entry.cpp +++ b/src/Entry.cpp @@ -33,4 +33,4 @@ bool LegacyRemoteCallApi::disable() { return true; } } // namespace GMLIB -LL_REGISTER_PLUGIN(LegacyRemoteCallApi, LegacyRemoteCallApi::getInstance()); +LL_REGISTER_MOD(LegacyRemoteCallApi, LegacyRemoteCallApi::getInstance()); diff --git a/src/Entry.h b/src/Entry.h index 26f70fe..49821d5 100644 --- a/src/Entry.h +++ b/src/Entry.h @@ -1,6 +1,6 @@ #pragma once -#include -#include +#include +#include namespace GMLIB { @@ -9,9 +9,9 @@ class LegacyRemoteCallApi { public: static std::unique_ptr& getInstance(); - LegacyRemoteCallApi(ll::plugin::NativePlugin& self) : mSelf(self) {} + LegacyRemoteCallApi(ll::mod::NativeMod& self) : mSelf(self) {} - [[nodiscard]] ll::plugin::NativePlugin& getSelf() const { return mSelf; } + [[nodiscard]] ll::mod::NativeMod& getSelf() const { return mSelf; } /// @return True if the plugin is loaded successfully. bool load(); @@ -27,7 +27,7 @@ class LegacyRemoteCallApi { // bool unload(); private: - ll::plugin::NativePlugin& mSelf; + ll::mod::NativeMod& mSelf; }; } // namespace GMLIB diff --git a/src/Global.h b/src/Global.h index 9b0aa90..418defa 100644 --- a/src/Global.h +++ b/src/Global.h @@ -11,7 +11,7 @@ using namespace Mod; #define LIB_VERSION_MAJOR 0 #define LIB_VERSION_MINOR 13 -#define LIB_VERSION_PATCH 0 +#define LIB_VERSION_PATCH 1 #define LIB_VERSION Version(LIB_VERSION_MAJOR, LIB_VERSION_MINOR, LIB_VERSION_PATCH) diff --git a/tooth.json b/tooth.json index 8968735..6dc57a1 100644 --- a/tooth.json +++ b/tooth.json @@ -1,7 +1,7 @@ { "format_version": 2, "tooth": "github.com/GroupMountain/GMLIB-LegacyRemoteCallApi", - "version": "0.13.0", + "version": "0.13.1", "info": { "name": "GMLIB-LegacyRemoteCallApi", "description": "Legacy RemoteCall API for GMLIB", @@ -14,7 +14,7 @@ "library" ] }, - "asset_url": "https://github.com/GroupMountain/GMLIB-LegacyRemoteCallApi/releases/download/v0.13.0/GMLIB-LegacyRemoteCallApi-windows-x64.zip", + "asset_url": "https://github.com/GroupMountain/GMLIB-LegacyRemoteCallApi/releases/download/v0.13.1/GMLIB-LegacyRemoteCallApi-windows-x64.zip", "dependencies": { "github.com/GroupMountain/GMLIB": ">=0.13.0" }, From a01ba9655d7eaabaf8931b7bfc23a43adc99a83d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=90=E6=B2=90=E5=91=80?= <163636894+zimuya4153@users.noreply.github.com> Date: Mon, 29 Jul 2024 14:34:40 +0800 Subject: [PATCH 29/37] =?UTF-8?q?=E6=B7=BB=E5=8A=A0getItemMaxCount?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/GMLIB_API-JS.d.ts | 3 +++ lib/GMLIB_API-JS.js | 14 +++++++++++++- src/CompatibilityApi.cpp | 5 ++++- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/lib/GMLIB_API-JS.d.ts b/lib/GMLIB_API-JS.d.ts index 0dc3447..bcd7168 100644 --- a/lib/GMLIB_API-JS.d.ts +++ b/lib/GMLIB_API-JS.d.ts @@ -1283,6 +1283,9 @@ interface Item { /** (GMLIB)物品是否为食物 */ isFood(): boolean; + + /** (GMLIB)获取物品最大堆叠数量 */ + getMaxCount(): number; } interface Container { diff --git a/lib/GMLIB_API-JS.js b/lib/GMLIB_API-JS.js index 26ee6a5..dff4155 100644 --- a/lib/GMLIB_API-JS.js +++ b/lib/GMLIB_API-JS.js @@ -337,7 +337,9 @@ const GMLIB_API = { /** 获取容器类型 @type {function(Container):string} */ getContainerType: ll.import("GMLIB_API", "getContainerType"), /** 玩家是否拥有NBT @type {function(string):boolean} */ - hasPlayerNbt: ll.import("GMLIB_API", "hasPlayerNbt") + hasPlayerNbt: ll.import("GMLIB_API", "hasPlayerNbt"), + /** 获取物品最大堆叠数量 @type {function(Item):number} */ + getItemMaxCount: ll.import("GMLIB_API", "getItemMaxCount") } /** 静态悬浮字类列表 @type {Map} */ @@ -2487,11 +2489,21 @@ LLSE_Player.prototype.sendInventorySlotPacket = LLSE_Container.prototype.getContainerType = /** * 获取容器类型 + * @returns {string} */ function () { return GMLIB_API.getContainerType(this); } +LLSE_Item.prototype.getMaxCount = + /** + * 获取物品最大堆叠数量 + * @returns {number} + */ + function () { + return GMLIB_API.getItemMaxCount(this); + } + module.exports = { StaticFloatingText, DynamicFloatingText, diff --git a/src/CompatibilityApi.cpp b/src/CompatibilityApi.cpp index 00e10a1..66d77fe 100644 --- a/src/CompatibilityApi.cpp +++ b/src/CompatibilityApi.cpp @@ -870,7 +870,7 @@ void Export_Compatibility_API() { RemoteCall::exportAs( "GMLIB_API", "sendInventorySlotPacket", - [](Player* player, int containerId, int slot, ItemStack* item) -> void { + [](Player* player, int containerId, int slot, ItemStack const* item) -> void { InventorySlotPacket((ContainerID)containerId, slot, *item).sendTo(*player); } ); @@ -881,4 +881,7 @@ void Export_Compatibility_API() { auto uid = mce::UUID::fromString(uuid); return GMLIB_Player::getPlayerNbt(uid) ? true : false; }); + RemoteCall::exportAs("GMLIB_API", "getItemMaxCount", [](ItemStack const* item) -> int { + return item->getMaxStackSize(); + }); } \ No newline at end of file From b72c4564bcd7578871f8ae7265d21c824b962def Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=90=E6=B2=90=E5=91=80?= <163636894+zimuya4153@users.noreply.github.com> Date: Thu, 1 Aug 2024 18:56:03 +0800 Subject: [PATCH 30/37] =?UTF-8?q?=E6=B7=BB=E5=8A=A0/=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加entityHasFamily,getPlayerDestroyBlockProgress接口 - 修改6事件名 --- lib/EventAPI-JS.d.ts | 12 ++++++------ lib/GMLIB_API-JS.d.ts | 14 +++++++++++++- lib/GMLIB_API-JS.js | 26 +++++++++++++++++++++++++- src/CompatibilityApi.cpp | 8 ++++++++ src/EventAPI.cpp | 12 ++++++------ 5 files changed, 58 insertions(+), 14 deletions(-) diff --git a/lib/EventAPI-JS.d.ts b/lib/EventAPI-JS.d.ts index 6be8885..0bfdb50 100644 --- a/lib/EventAPI-JS.d.ts +++ b/lib/EventAPI-JS.d.ts @@ -160,7 +160,7 @@ declare class Event { /** 末影龙重生事件 */ static listen( /** 事件名 */ - event: "DragonRespawn", + event: "onDragonRespawn", /** 回调函数 */ listener: ( /** 末影龙重生后的UniqueID */ @@ -171,7 +171,7 @@ declare class Event { /** 弹射物实体尝试创建 */ static listen( /** 事件名 */ - event: "ProjectileTryCreate", + event: "onProjectileTryCreate", /** 回调函数 */ listener: ( /** 弹射物实体对象 */ @@ -184,7 +184,7 @@ declare class Event { /** 弹射物实体成功后(不可拦截) */ static listen( /** 事件名 */ - event: "ProjectileCreate", + event: "onProjectileCreate", /** 回调函数 */ listener: ( /** 弹射物实体对象 */ @@ -197,7 +197,7 @@ declare class Event { /** 生成流浪商人 */ static listen( /** 事件名 */ - event: "SpawnWanderingTrader", + event: "onSpawnWanderingTrader", /** 回调函数 */ listener: ( /** 生成的坐标 */ @@ -208,7 +208,7 @@ declare class Event { /** 处理物品请求 */ static listen( /** 事件名 */ - event: "HandleRequestAction", + event: "onHandleRequestAction", /** 回调函数 */ listener: ( /** 请求玩家 */ @@ -231,7 +231,7 @@ declare class Event { /** 发送容器关闭数据包后(不可拦截) */ static listen( /** 事件名 */ - event: "SendContainerClosePacket", + event: "onSendContainerClosePacket", /** 回调函数 */ listener: ( /** 要被关闭的玩家 */ diff --git a/lib/GMLIB_API-JS.d.ts b/lib/GMLIB_API-JS.d.ts index bcd7168..443b3af 100644 --- a/lib/GMLIB_API-JS.d.ts +++ b/lib/GMLIB_API-JS.d.ts @@ -1073,6 +1073,12 @@ interface Player { /** 物品 */ item: Item ): void; + + /** (GMLIB)获取玩家破坏方块所需时间 */ + getDestroyProgress( + /** 方块对象 */ + block: Block + ): number; } interface Entity { @@ -1123,8 +1129,14 @@ interface Entity { /** (GMLIB)获取实体的命名 */ getNameTag(): string; - /** 获取实体的主人 */ + /** (GMLIB)获取实体的主人 */ getEntityOwner(): Entity | null; + + /** (GMLIB)实体是否包含在某类里 */ + hasFamily( + /** 实体族 */ + family: string + ): boolean; } interface Block { diff --git a/lib/GMLIB_API-JS.js b/lib/GMLIB_API-JS.js index dff4155..944c9ba 100644 --- a/lib/GMLIB_API-JS.js +++ b/lib/GMLIB_API-JS.js @@ -339,7 +339,11 @@ const GMLIB_API = { /** 玩家是否拥有NBT @type {function(string):boolean} */ hasPlayerNbt: ll.import("GMLIB_API", "hasPlayerNbt"), /** 获取物品最大堆叠数量 @type {function(Item):number} */ - getItemMaxCount: ll.import("GMLIB_API", "getItemMaxCount") + getItemMaxCount: ll.import("GMLIB_API", "getItemMaxCount"), + /** 实体包含在某族里 @type {function(Entity,string):boolean} */ + entityHasFamily: ll.import("GMLIB_API", "entityHasFamily"), + /** 获取玩家破坏方块所需时间 @type {function(Player,Block):number} */ + getPlayerDestroyBlockProgress: ll.import("GMLIB_API", "getPlayerDestroyBlockProgress") } /** 静态悬浮字类列表 @type {Map} */ @@ -2504,6 +2508,26 @@ LLSE_Item.prototype.getMaxCount = return GMLIB_API.getItemMaxCount(this); } +LLSE_Entity.prototype.hasFamily = + /** + * 实体是否拥包含在某族里 + * @param {string} family 实体族 + * @returns {boolean} + */ + function (family) { + return GMLIB_API.entityHasFamily(this, family); + } + +LLSE_Player.prototype.getDestroyProgress = + /** + * 获取玩家破坏方块所需时间 + * @param {Block} block + * @returns {number} + */ + function (block) { + return GMLIB_API.getPlayerDestroyBlockProgress(this, block); + } + module.exports = { StaticFloatingText, DynamicFloatingText, diff --git a/src/CompatibilityApi.cpp b/src/CompatibilityApi.cpp index 66d77fe..21b47c2 100644 --- a/src/CompatibilityApi.cpp +++ b/src/CompatibilityApi.cpp @@ -1,4 +1,6 @@ #include "Global.h" +#include "magic_enum.hpp" +#include "mc/deps/core/string/HashedString.h" #include bool isInteger(const std::string& str) { @@ -884,4 +886,10 @@ void Export_Compatibility_API() { RemoteCall::exportAs("GMLIB_API", "getItemMaxCount", [](ItemStack const* item) -> int { return item->getMaxStackSize(); }); + RemoteCall::exportAs("GMLIB_API", "entityHasFamily", [](Actor* entity, std::string const& family) -> bool { + return entity->hasFamily(HashedString(family)); + }); + RemoteCall::exportAs("GMLIB_API", "getPlayerDestroyBlockProgress", [](Player* player, Block const* block) -> float { + return player->getDestroyProgress(*block); + }); } \ No newline at end of file diff --git a/src/EventAPI.cpp b/src/EventAPI.cpp index e0134cb..f129297 100644 --- a/src/EventAPI.cpp +++ b/src/EventAPI.cpp @@ -206,7 +206,7 @@ void Export_Event_API() { ); return true; } - case doHash("DragonRespawn"): { + case doHash("onDragonRespawn"): { auto Call = RemoteCall::importAs(eventName, eventId); eventBus->emplaceListener( [Call](Event::EntityEvent::DragonRespawnBeforeEvent& ev) { @@ -221,7 +221,7 @@ void Export_Event_API() { ); return true; } - case doHash("ProjectileTryCreate"): { + case doHash("onProjectileTryCreate"): { auto Call = RemoteCall::importAs(eventName, eventId); eventBus->emplaceListener( [Call](Event::EntityEvent::ProjectileCreateBeforeEvent& ev) { @@ -237,7 +237,7 @@ void Export_Event_API() { ); return true; } - case doHash("ProjectileCreate"): { + case doHash("onProjectileCreate"): { auto Call = RemoteCall::importAs(eventName, eventId); eventBus->emplaceListener( [Call](Event::EntityEvent::ProjectileCreateAfterEvent& ev) { @@ -249,7 +249,7 @@ void Export_Event_API() { ); return true; } - case doHash("SpawnWanderingTrader"): { + case doHash("onSpawnWanderingTrader"): { auto Call = RemoteCall::importAs pos)>(eventName, eventId); eventBus->emplaceListener( [Call](Event::EntityEvent::SpawnWanderingTraderBeforeEvent& ev) { @@ -264,7 +264,7 @@ void Export_Event_API() { ); return true; } - case doHash("HandleRequestAction"): { + case doHash("onHandleRequestAction"): { auto Call = RemoteCall::importAs(eventName, eventId); eventBus->emplaceListener( [Call](Event::PacketEvent::ContainerClosePacketSendAfterEvent& ev) { From ae34d79b56b4c686278386acc3e8a5a4e1fda32b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=90=E6=B2=90=E5=91=80?= <163636894+zimuya4153@users.noreply.github.com> Date: Thu, 1 Aug 2024 20:22:21 +0800 Subject: [PATCH 31/37] =?UTF-8?q?=E6=B7=BB=E5=8A=A012=E4=B8=AA=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - getPlayerEffectVisible - getPlayerEffectDuration - getPlayerEffectDurationEasy - getPlayerEffectDurationHard - getPlayerEffectDurationNormal - getPlayerEffectAmplifier - getPlayerEffectAmbient - playerHasEffect - getGameDifficulty - setGameDifficulty - getDefaultGameMode - setDefaultGameMode --- lib/GMLIB_API-JS.d.ts | 67 +++++++++++++++++++++++++++ lib/GMLIB_API-JS.js | 98 +++++++++++++++++++++++++++++++++++++++- src/CompatibilityApi.cpp | 69 ++++++++++++++++++++++++++++ 3 files changed, 233 insertions(+), 1 deletion(-) diff --git a/lib/GMLIB_API-JS.d.ts b/lib/GMLIB_API-JS.d.ts index 443b3af..1109e5f 100644 --- a/lib/GMLIB_API-JS.d.ts +++ b/lib/GMLIB_API-JS.d.ts @@ -372,6 +372,24 @@ declare class Minecraft { /** 玩家的uuid */ uuid: string ): boolean; + + /** 获取游戏难度 */ + static getGameDifficulty(): -1 | 0 | 1 | 2 | 3; + + /** 设置游戏难度 */ + static setGameDifficulty( + /** 游戏难度 */ + difficulty: 0 | 1 | 2 | 3 + ): void; + + /** 获取默认游戏模式 */ + static getDefaultGameMode(): -1 | 0 | 1 | 2 | 5 | 6; + + /** 设置默认游戏模式 */ + static setDefaultGameMode( + /** 游戏模式 */ + gameMode: 0 | 1 | 2 | 5 | 6 + ): void; } /** 合成表类 */ @@ -1079,6 +1097,55 @@ interface Player { /** 方块对象 */ block: Block ): number; + + /** (GMLIB)玩家是否拥有buff效果 */ + hasEffect( + /** 效果ID */ + effectId: number + ): boolean; + + /** (GMLIB)获取buff信息 */ + getEffectInfo( + /** 效果ID */ + effectId: number + ): { + /** 效果ID */ + Id: number, + /** 效果等级 */ + Amplifier: number, + /** 持续时间 */ + Duration: number, + /** 简单难度下的持续时间 */ + DurationEasy: number, + /** 普通难度下的持续时间 */ + DurationNormal: number, + /** 困难难度下的持续时间 */ + DurationHard: number, + /** 是否为信标给予 */ + Ambient: boolean, + /** 是否显示粒子效果 */ + ShowParticles: boolean + } | null; + + /** (GMLIB)获取所有buff信息 */ + getAllEffectsInfo(): { + /** 效果ID */ + Id: number, + /** 效果等级 */ + Amplifier: number, + /** 持续时间 */ + Duration: number, + /** 简单难度下的持续时间 */ + DurationEasy: number, + /** 普通难度下的持续时间 */ + DurationNormal: number, + /** 困难难度下的持续时间 */ + DurationHard: number, + /** 是否为信标给予 */ + Ambient: boolean, + /** 是否显示粒子效果 */ + ShowParticles: boolean + }[]; } interface Entity { diff --git a/lib/GMLIB_API-JS.js b/lib/GMLIB_API-JS.js index 944c9ba..8e6cb3a 100644 --- a/lib/GMLIB_API-JS.js +++ b/lib/GMLIB_API-JS.js @@ -1,3 +1,5 @@ +/// + /** LRCA导出接口 */ const GMLIB_API = { /** 创建悬浮字 @type {function(FloatPos,string,boolean):number} */ @@ -343,7 +345,31 @@ const GMLIB_API = { /** 实体包含在某族里 @type {function(Entity,string):boolean} */ entityHasFamily: ll.import("GMLIB_API", "entityHasFamily"), /** 获取玩家破坏方块所需时间 @type {function(Player,Block):number} */ - getPlayerDestroyBlockProgress: ll.import("GMLIB_API", "getPlayerDestroyBlockProgress") + getPlayerDestroyBlockProgress: ll.import("GMLIB_API", "getPlayerDestroyBlockProgress"), + /** 获取玩家的buff是否显示 @type {function(Player,number):boolean} */ + getPlayerEffectVisible: ll.import("GMLIB_API", "getPlayerEffectVisible"), + /** 获取玩家的buff持续时间 @type {function(Player,number):number} */ + getPlayerEffectDuration: ll.import("GMLIB_API", "getPlayerEffectDuration"), + /** 获取玩家的buff简单模式下的持续时间 @type {function(Player,number):number} */ + getPlayerEffectDurationEasy: ll.import("GMLIB_API", "getPlayerEffectDuration"), + /** 获取玩家的buff困难模式下的持续时间 @type {function(Player,number):number} */ + getPlayerEffectDurationHard: ll.import("GMLIB_API", "getPlayerEffectDurationHard"), + /** 获取玩家的buff普通模式下的持续时间 @type {function(Player,number):number} */ + getPlayerEffectDurationNormal: ll.import("GMLIB_API", "getPlayerEffectDurationNormal"), + /** 获取玩家的buff效果等级 @type {function(Player,number):number} */ + getPlayerEffectAmplifier: ll.import("GMLIB_API", "getPlayerEffectAmplifier"), + /** 获取玩家的buff是否为信标给予 @type {function(Player,number):boolean} */ + getPlayerEffectAmbient: ll.import("GMLIB_API", "getPlayerEffectAmbient"), + /** 玩家是否拥有buff效果 @type {function(Player,number):boolean} */ + playerHasEffect: ll.import("GMLIB_API", "playerHasEffect"), + /** 获取游戏难度 @type {function():number} */ + getGameDifficulty: ll.import("GMLIB_API", "getGameDifficulty"), + /** 设置游戏难度 @type {function(difficulty):void} */ + setGameDifficulty: ll.import("GMLIB_API", "setGameDifficulty"), + /** 获取默认游戏模式 @type {function():number} */ + getDefaultGameMode: ll.import("GMLIB_API", "getDefaultGameMode"), + /** 设置默认游戏模式 @type {function(mode):void} */ + setDefaultGameMode: ll.import("GMLIB_API", "setDefaultGameMode"), } /** 静态悬浮字类列表 @type {Map} */ @@ -1033,6 +1059,37 @@ class Minecraft { static hasPlayerNbt(uuid) { return GMLIB_API.hasPlayerNbt(uuid); } + + /** + * 获取游戏难度 + * @returns {-1|0|1|2|3} 游戏难度 + */ + static getGameDifficulty() { + return GMLIB_API.getGameDifficulty(); + } + + /** + * 设置游戏难度 + * @param {0|1|2|3} difficulty 游戏难度 + */ + static setGameDifficulty(difficulty) { + GMLIB_API.setGameDifficulty(difficulty); + } + + /** + * 获取默认游戏模式 + * @returns {-1|0|1|2|5|6} 游戏模式 + */ + static getDefaultGameMode() { + return GMLIB_API.getDefaultGameMode(); + } + /** + * 设置默认游戏模式 + * @param {0|1|2|3} gameMode 游戏模式 + */ + static setDefaultGameMode(gameMode) { + GMLIB_API.setDefaultGameMode(gameMode); + } } /** 合成表类 */ @@ -2528,6 +2585,45 @@ LLSE_Player.prototype.getDestroyProgress = return GMLIB_API.getPlayerDestroyBlockProgress(this, block); } +LLSE_Player.prototype.hasEffect = + /** + * 玩家是否拥有buff效果 + * @param {number} effectId buff效果ID + * @returns {boolean} + */ + function (effectId) { + return GMLIB_API.playerHasEffect(this, effectId); + } + +LLSE_Player.prototype.getEffectInfo = + /** + * 获取buff信息 + * @param {number} effectId buff效果ID + * @returns {{Id: number, Amplifier: number, Duration: number, DurationEasy: number, DurationNormal: number, DurationHard: number, Ambient: boolean, ShowParticles: boolean} | null} + */ + function (effectId) { + if (!this.hasEffect(effectId)) return null; + return { + Id: id, + Amplifier: GMLIB_API.getPlayerEffectAmbient(this, effectId), + Duration: GMLIB_API.getPlayerEffectDuration(this, effectId), + DurationEasy: GMLIB_API.getPlayerEffectDurationEasy(this, effectId), + DurationNormal: GMLIB_API.getPlayerEffectDurationNormal(this, effectId), + DurationHard: GMLIB_API.getPlayerEffectDurationHard(this, effectId), + Ambient: GMLIB_API.getPlayerEffectAmbient(this, effectId), + ShowParticles: GMLIB_API.getPlayerEffectAmbient(this, effectId), + } + } + +LLSE_Player.prototype.getAllEffectsInfo = + /** + * 获取所有buff信息 + * @returns {{Id: number, Amplifier: number, Duration: number, DurationEasy: number, DurationNormal: number, DurationHard: number, Ambient: boolean, ShowParticles: boolean}[]} + */ + function () { + this.getAllEffects().map(this.getEffectInfo); + } + module.exports = { StaticFloatingText, DynamicFloatingText, diff --git a/src/CompatibilityApi.cpp b/src/CompatibilityApi.cpp index 21b47c2..9575c83 100644 --- a/src/CompatibilityApi.cpp +++ b/src/CompatibilityApi.cpp @@ -1,6 +1,8 @@ #include "Global.h" +#include "ll/api/service/Bedrock.h" #include "magic_enum.hpp" #include "mc/deps/core/string/HashedString.h" +#include "mc/world/effect/MobEffect.h" #include bool isInteger(const std::string& str) { @@ -892,4 +894,71 @@ void Export_Compatibility_API() { RemoteCall::exportAs("GMLIB_API", "getPlayerDestroyBlockProgress", [](Player* player, Block const* block) -> float { return player->getDestroyProgress(*block); }); + RemoteCall::exportAs("GMLIB_API", "getPlayerEffectVisible", [](Player* player, int effectId) -> bool { + if (auto effect = player->getEffect(effectId)) { + return effect->mEffectVisible; + } + return 0; + }); + RemoteCall::exportAs("GMLIB_API", "getPlayerEffectDuration", [](Player* player, int effectId) -> int { + if (auto effect = player->getEffect(effectId)) { + return effect->mDuration; + } + return 0; + }); + RemoteCall::exportAs("GMLIB_API", "getPlayerEffectDurationEasy", [](Player* player, int effectId) -> int { + if (auto effect = player->getEffect(effectId)) { + return effect->mDurationEasy; + } + return 0; + }); + RemoteCall::exportAs("GMLIB_API", "getPlayerEffectDurationHard", [](Player* player, int effectId) -> int { + if (auto effect = player->getEffect(effectId)) { + return effect->mDurationHard; + } + return 0; + }); + RemoteCall::exportAs("GMLIB_API", "getPlayerEffectDurationNormal", [](Player* player, int effectId) -> int { + if (auto effect = player->getEffect(effectId)) { + return effect->mDurationNormal; + } + return 0; + }); + RemoteCall::exportAs("GMLIB_API", "getPlayerEffectAmplifier", [](Player* player, int effectId) -> int { + if (auto effect = player->getEffect(effectId)) { + return effect->mAmplifier; + } + return 0; + }); + RemoteCall::exportAs("GMLIB_API", "getPlayerEffectAmbient", [](Player* player, int effectId) -> bool { + if (auto effect = player->getEffect(effectId)) { + return effect->mAmbient; + } + return 0; + }); + RemoteCall::exportAs("GMLIB_API", "playerHasEffect", [](Player* player, int effectId) -> int { + return player->hasEffect(*MobEffect::getById(effectId)); + }); + RemoteCall::exportAs("GMLIB_API", "getGameDifficulty", []() -> int { + if (auto level = ll::service::getLevel()) { + return (int)level->getDifficulty(); + } + return -1; + }); + RemoteCall::exportAs("GMLIB_API", "setGameDifficulty", [](int difficulty) -> void { + if (auto level = ll::service::getLevel()) { + level->setDifficulty((Difficulty)difficulty); + } + }); + RemoteCall::exportAs("GMLIB_API", "getDefaultGameMode", []() -> int { + if (auto level = ll::service::getLevel()) { + return (int)level->getDefaultGameType(); + } + return -1; + }); + RemoteCall::exportAs("GMLIB_API", "setDefaultGameMode", [](int gameMode) -> void { + if (auto level = ll::service::getLevel()) { + level->setDefaultGameType((GameType)gameMode); + } + }); } \ No newline at end of file From e2e053c8c1a2ad864f4fdc8dddd9b3b342faf398 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=90=E6=B2=90=E5=91=80?= <163636894+zimuya4153@users.noreply.github.com> Date: Thu, 1 Aug 2024 20:54:18 +0800 Subject: [PATCH 32/37] =?UTF-8?q?=E6=B7=BB=E5=8A=A0onServerStopping?= =?UTF-8?q?=E4=BA=8B=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/EventAPI-JS.d.ts | 8 ++++++++ lib/GMLIB_API-JS.js | 2 -- src/CompatibilityApi.cpp | 4 ---- src/EventAPI.cpp | 11 +++++++++++ 4 files changed, 19 insertions(+), 6 deletions(-) diff --git a/lib/EventAPI-JS.d.ts b/lib/EventAPI-JS.d.ts index 0bfdb50..ec9c4ec 100644 --- a/lib/EventAPI-JS.d.ts +++ b/lib/EventAPI-JS.d.ts @@ -240,4 +240,12 @@ declare class Event { containerId: number ) => void ): boolean; + + /** 关闭服务器(不可拦截) */ + static listen( + /** 事件名 */ + event: "onServerStopping", + /** 回调函数 */ + listener: () => void + ): boolean; } \ No newline at end of file diff --git a/lib/GMLIB_API-JS.js b/lib/GMLIB_API-JS.js index 8e6cb3a..f9cf0c2 100644 --- a/lib/GMLIB_API-JS.js +++ b/lib/GMLIB_API-JS.js @@ -1,5 +1,3 @@ -/// - /** LRCA导出接口 */ const GMLIB_API = { /** 创建悬浮字 @type {function(FloatPos,string,boolean):number} */ diff --git a/src/CompatibilityApi.cpp b/src/CompatibilityApi.cpp index 9575c83..4ef3312 100644 --- a/src/CompatibilityApi.cpp +++ b/src/CompatibilityApi.cpp @@ -1,8 +1,4 @@ #include "Global.h" -#include "ll/api/service/Bedrock.h" -#include "magic_enum.hpp" -#include "mc/deps/core/string/HashedString.h" -#include "mc/world/effect/MobEffect.h" #include bool isInteger(const std::string& str) { diff --git a/src/EventAPI.cpp b/src/EventAPI.cpp index f129297..fe20805 100644 --- a/src/EventAPI.cpp +++ b/src/EventAPI.cpp @@ -314,6 +314,17 @@ void Export_Event_API() { ); return true; } + case doHash("onServerStopping"): { + auto Call = RemoteCall::importAs(eventName, eventId); + eventBus->emplaceListener( + [Call](ll::event::server::ServerStoppingEvent& ev) { + try { + Call(); + } catch (...) {} + } + ); + return true; + } default: return false; } From 2f987b1c9362519ed438df4da2fecfd47af30fbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=90=E6=B2=90=E5=91=80?= <163636894+zimuya4153@users.noreply.github.com> Date: Thu, 1 Aug 2024 21:14:08 +0800 Subject: [PATCH 33/37] =?UTF-8?q?=E4=BF=AE=E6=94=B9buff=E7=9B=B8=E5=85=B3?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/GMLIB_API-JS.d.ts | 86 ++++++++++++++++++++-------------------- lib/GMLIB_API-JS.js | 36 ++++++++--------- src/CompatibilityApi.cpp | 32 +++++++-------- 3 files changed, 77 insertions(+), 77 deletions(-) diff --git a/lib/GMLIB_API-JS.d.ts b/lib/GMLIB_API-JS.d.ts index 1109e5f..ed07bc1 100644 --- a/lib/GMLIB_API-JS.d.ts +++ b/lib/GMLIB_API-JS.d.ts @@ -1103,49 +1103,6 @@ interface Player { /** 效果ID */ effectId: number ): boolean; - - /** (GMLIB)获取buff信息 */ - getEffectInfo( - /** 效果ID */ - effectId: number - ): { - /** 效果ID */ - Id: number, - /** 效果等级 */ - Amplifier: number, - /** 持续时间 */ - Duration: number, - /** 简单难度下的持续时间 */ - DurationEasy: number, - /** 普通难度下的持续时间 */ - DurationNormal: number, - /** 困难难度下的持续时间 */ - DurationHard: number, - /** 是否为信标给予 */ - Ambient: boolean, - /** 是否显示粒子效果 */ - ShowParticles: boolean - } | null; - - /** (GMLIB)获取所有buff信息 */ - getAllEffectsInfo(): { - /** 效果ID */ - Id: number, - /** 效果等级 */ - Amplifier: number, - /** 持续时间 */ - Duration: number, - /** 简单难度下的持续时间 */ - DurationEasy: number, - /** 普通难度下的持续时间 */ - DurationNormal: number, - /** 困难难度下的持续时间 */ - DurationHard: number, - /** 是否为信标给予 */ - Ambient: boolean, - /** 是否显示粒子效果 */ - ShowParticles: boolean - }[]; } interface Entity { @@ -1204,6 +1161,49 @@ interface Entity { /** 实体族 */ family: string ): boolean; + + /** (GMLIB)获取buff信息 */ + getEffectInfo( + /** 效果ID */ + effectId: number + ): { + /** 效果ID */ + Id: number, + /** 效果等级 */ + Amplifier: number, + /** 持续时间 */ + Duration: number, + /** 简单难度下的持续时间 */ + DurationEasy: number, + /** 普通难度下的持续时间 */ + DurationNormal: number, + /** 困难难度下的持续时间 */ + DurationHard: number, + /** 是否为信标给予 */ + Ambient: boolean, + /** 是否显示粒子效果 */ + ShowParticles: boolean + } | null; + + /** (GMLIB)获取所有buff信息 */ + getAllEffectsInfo(): { + /** 效果ID */ + Id: number, + /** 效果等级 */ + Amplifier: number, + /** 持续时间 */ + Duration: number, + /** 简单难度下的持续时间 */ + DurationEasy: number, + /** 普通难度下的持续时间 */ + DurationNormal: number, + /** 困难难度下的持续时间 */ + DurationHard: number, + /** 是否为信标给予 */ + Ambient: boolean, + /** 是否显示粒子效果 */ + ShowParticles: boolean + }[]; } interface Block { diff --git a/lib/GMLIB_API-JS.js b/lib/GMLIB_API-JS.js index f9cf0c2..0813107 100644 --- a/lib/GMLIB_API-JS.js +++ b/lib/GMLIB_API-JS.js @@ -345,21 +345,21 @@ const GMLIB_API = { /** 获取玩家破坏方块所需时间 @type {function(Player,Block):number} */ getPlayerDestroyBlockProgress: ll.import("GMLIB_API", "getPlayerDestroyBlockProgress"), /** 获取玩家的buff是否显示 @type {function(Player,number):boolean} */ - getPlayerEffectVisible: ll.import("GMLIB_API", "getPlayerEffectVisible"), + getEntityEffectVisible: ll.import("GMLIB_API", "getEntityEffectVisible"), /** 获取玩家的buff持续时间 @type {function(Player,number):number} */ - getPlayerEffectDuration: ll.import("GMLIB_API", "getPlayerEffectDuration"), + getEntityEffectDuration: ll.import("GMLIB_API", "getEntityEffectDuration"), /** 获取玩家的buff简单模式下的持续时间 @type {function(Player,number):number} */ - getPlayerEffectDurationEasy: ll.import("GMLIB_API", "getPlayerEffectDuration"), + getEntityEffectDurationEasy: ll.import("GMLIB_API", "getEntityEffectDuration"), /** 获取玩家的buff困难模式下的持续时间 @type {function(Player,number):number} */ - getPlayerEffectDurationHard: ll.import("GMLIB_API", "getPlayerEffectDurationHard"), + getEntityEffectDurationHard: ll.import("GMLIB_API", "getEntityEffectDurationHard"), /** 获取玩家的buff普通模式下的持续时间 @type {function(Player,number):number} */ - getPlayerEffectDurationNormal: ll.import("GMLIB_API", "getPlayerEffectDurationNormal"), + getEntityEffectDurationNormal: ll.import("GMLIB_API", "getEntityEffectDurationNormal"), /** 获取玩家的buff效果等级 @type {function(Player,number):number} */ - getPlayerEffectAmplifier: ll.import("GMLIB_API", "getPlayerEffectAmplifier"), + getEntityEffectAmplifier: ll.import("GMLIB_API", "getEntityEffectAmplifier"), /** 获取玩家的buff是否为信标给予 @type {function(Player,number):boolean} */ - getPlayerEffectAmbient: ll.import("GMLIB_API", "getPlayerEffectAmbient"), + getEntityEffectAmbient: ll.import("GMLIB_API", "getEntityEffectAmbient"), /** 玩家是否拥有buff效果 @type {function(Player,number):boolean} */ - playerHasEffect: ll.import("GMLIB_API", "playerHasEffect"), + entityHasEffect: ll.import("GMLIB_API", "entityHasEffect"), /** 获取游戏难度 @type {function():number} */ getGameDifficulty: ll.import("GMLIB_API", "getGameDifficulty"), /** 设置游戏难度 @type {function(difficulty):void} */ @@ -2583,7 +2583,7 @@ LLSE_Player.prototype.getDestroyProgress = return GMLIB_API.getPlayerDestroyBlockProgress(this, block); } -LLSE_Player.prototype.hasEffect = +LLSE_Entity.prototype.hasEffect = /** * 玩家是否拥有buff效果 * @param {number} effectId buff效果ID @@ -2593,7 +2593,7 @@ LLSE_Player.prototype.hasEffect = return GMLIB_API.playerHasEffect(this, effectId); } -LLSE_Player.prototype.getEffectInfo = +LLSE_Entity.prototype.getEffectInfo = /** * 获取buff信息 * @param {number} effectId buff效果ID @@ -2603,17 +2603,17 @@ LLSE_Player.prototype.getEffectInfo = if (!this.hasEffect(effectId)) return null; return { Id: id, - Amplifier: GMLIB_API.getPlayerEffectAmbient(this, effectId), - Duration: GMLIB_API.getPlayerEffectDuration(this, effectId), - DurationEasy: GMLIB_API.getPlayerEffectDurationEasy(this, effectId), - DurationNormal: GMLIB_API.getPlayerEffectDurationNormal(this, effectId), - DurationHard: GMLIB_API.getPlayerEffectDurationHard(this, effectId), - Ambient: GMLIB_API.getPlayerEffectAmbient(this, effectId), - ShowParticles: GMLIB_API.getPlayerEffectAmbient(this, effectId), + Amplifier: GMLIB_API.getEntityEffectAmbient(this, effectId), + Duration: GMLIB_API.getEntityEffectDuration(this, effectId), + DurationEasy: GMLIB_API.getEntityEffectDurationEasy(this, effectId), + DurationNormal: GMLIB_API.getEntityEffectDurationNormal(this, effectId), + DurationHard: GMLIB_API.getEntityEffectDurationHard(this, effectId), + Ambient: GMLIB_API.getEntityEffectAmbient(this, effectId), + ShowParticles: GMLIB_API.getEntityEffectAmbient(this, effectId), } } -LLSE_Player.prototype.getAllEffectsInfo = +LLSE_Entity.prototype.getAllEffectsInfo = /** * 获取所有buff信息 * @returns {{Id: number, Amplifier: number, Duration: number, DurationEasy: number, DurationNormal: number, DurationHard: number, Ambient: boolean, ShowParticles: boolean}[]} diff --git a/src/CompatibilityApi.cpp b/src/CompatibilityApi.cpp index 4ef3312..e09c092 100644 --- a/src/CompatibilityApi.cpp +++ b/src/CompatibilityApi.cpp @@ -890,50 +890,50 @@ void Export_Compatibility_API() { RemoteCall::exportAs("GMLIB_API", "getPlayerDestroyBlockProgress", [](Player* player, Block const* block) -> float { return player->getDestroyProgress(*block); }); - RemoteCall::exportAs("GMLIB_API", "getPlayerEffectVisible", [](Player* player, int effectId) -> bool { - if (auto effect = player->getEffect(effectId)) { + RemoteCall::exportAs("GMLIB_API", "getEntityEffectVisible", [](Actor* entity, int effectId) -> bool { + if (auto effect = entity->getEffect(effectId)) { return effect->mEffectVisible; } return 0; }); - RemoteCall::exportAs("GMLIB_API", "getPlayerEffectDuration", [](Player* player, int effectId) -> int { - if (auto effect = player->getEffect(effectId)) { + RemoteCall::exportAs("GMLIB_API", "getEntityEffectDuration", [](Actor* entity, int effectId) -> int { + if (auto effect = entity->getEffect(effectId)) { return effect->mDuration; } return 0; }); - RemoteCall::exportAs("GMLIB_API", "getPlayerEffectDurationEasy", [](Player* player, int effectId) -> int { - if (auto effect = player->getEffect(effectId)) { + RemoteCall::exportAs("GMLIB_API", "getEntityEffectDurationEasy", [](Actor* entity, int effectId) -> int { + if (auto effect = entity->getEffect(effectId)) { return effect->mDurationEasy; } return 0; }); - RemoteCall::exportAs("GMLIB_API", "getPlayerEffectDurationHard", [](Player* player, int effectId) -> int { - if (auto effect = player->getEffect(effectId)) { + RemoteCall::exportAs("GMLIB_API", "getEntityEffectDurationHard", [](Actor* entity, int effectId) -> int { + if (auto effect = entity->getEffect(effectId)) { return effect->mDurationHard; } return 0; }); - RemoteCall::exportAs("GMLIB_API", "getPlayerEffectDurationNormal", [](Player* player, int effectId) -> int { - if (auto effect = player->getEffect(effectId)) { + RemoteCall::exportAs("GMLIB_API", "getEntityEffectDurationNormal", [](Actor* entity, int effectId) -> int { + if (auto effect = entity->getEffect(effectId)) { return effect->mDurationNormal; } return 0; }); - RemoteCall::exportAs("GMLIB_API", "getPlayerEffectAmplifier", [](Player* player, int effectId) -> int { - if (auto effect = player->getEffect(effectId)) { + RemoteCall::exportAs("GMLIB_API", "getEntityEffectAmplifier", [](Actor* entity, int effectId) -> int { + if (auto effect = entity->getEffect(effectId)) { return effect->mAmplifier; } return 0; }); - RemoteCall::exportAs("GMLIB_API", "getPlayerEffectAmbient", [](Player* player, int effectId) -> bool { - if (auto effect = player->getEffect(effectId)) { + RemoteCall::exportAs("GMLIB_API", "getEntityEffectAmbient", [](Actor* entity, int effectId) -> bool { + if (auto effect = entity->getEffect(effectId)) { return effect->mAmbient; } return 0; }); - RemoteCall::exportAs("GMLIB_API", "playerHasEffect", [](Player* player, int effectId) -> int { - return player->hasEffect(*MobEffect::getById(effectId)); + RemoteCall::exportAs("GMLIB_API", "entityHasEffect", [](Actor* entity, int effectId) -> int { + return entity->hasEffect(*MobEffect::getById(effectId)); }); RemoteCall::exportAs("GMLIB_API", "getGameDifficulty", []() -> int { if (auto level = ll::service::getLevel()) { From 4857867821dc138bf529da18a8220ccfd458ab79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=90=E6=B2=90=E5=91=80?= <163636894+zimuya4153@users.noreply.github.com> Date: Thu, 1 Aug 2024 21:23:33 +0800 Subject: [PATCH 34/37] =?UTF-8?q?=E6=B7=BB=E5=8A=A0getEntityAllEffects?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/GMLIB_API-JS.d.ts | 12 ++++++------ lib/GMLIB_API-JS.js | 20 +++++++++++--------- src/CompatibilityApi.cpp | 9 +++++++++ 3 files changed, 26 insertions(+), 15 deletions(-) diff --git a/lib/GMLIB_API-JS.d.ts b/lib/GMLIB_API-JS.d.ts index ed07bc1..09c26f1 100644 --- a/lib/GMLIB_API-JS.d.ts +++ b/lib/GMLIB_API-JS.d.ts @@ -1097,12 +1097,6 @@ interface Player { /** 方块对象 */ block: Block ): number; - - /** (GMLIB)玩家是否拥有buff效果 */ - hasEffect( - /** 效果ID */ - effectId: number - ): boolean; } interface Entity { @@ -1162,6 +1156,12 @@ interface Entity { family: string ): boolean; + /** (GMLIB)实体是否拥有buff效果 */ + hasEffect( + /** 效果ID */ + effectId: number + ): boolean; + /** (GMLIB)获取buff信息 */ getEffectInfo( /** 效果ID */ diff --git a/lib/GMLIB_API-JS.js b/lib/GMLIB_API-JS.js index 0813107..93daa30 100644 --- a/lib/GMLIB_API-JS.js +++ b/lib/GMLIB_API-JS.js @@ -344,22 +344,24 @@ const GMLIB_API = { entityHasFamily: ll.import("GMLIB_API", "entityHasFamily"), /** 获取玩家破坏方块所需时间 @type {function(Player,Block):number} */ getPlayerDestroyBlockProgress: ll.import("GMLIB_API", "getPlayerDestroyBlockProgress"), - /** 获取玩家的buff是否显示 @type {function(Player,number):boolean} */ + /** 获取实体的buff是否显示 @type {function(Player,number):boolean} */ getEntityEffectVisible: ll.import("GMLIB_API", "getEntityEffectVisible"), - /** 获取玩家的buff持续时间 @type {function(Player,number):number} */ + /** 获取实体的buff持续时间 @type {function(Player,number):number} */ getEntityEffectDuration: ll.import("GMLIB_API", "getEntityEffectDuration"), - /** 获取玩家的buff简单模式下的持续时间 @type {function(Player,number):number} */ + /** 获取实体的buff简单模式下的持续时间 @type {function(Player,number):number} */ getEntityEffectDurationEasy: ll.import("GMLIB_API", "getEntityEffectDuration"), - /** 获取玩家的buff困难模式下的持续时间 @type {function(Player,number):number} */ + /** 获取实体的buff困难模式下的持续时间 @type {function(Player,number):number} */ getEntityEffectDurationHard: ll.import("GMLIB_API", "getEntityEffectDurationHard"), - /** 获取玩家的buff普通模式下的持续时间 @type {function(Player,number):number} */ + /** 获取实体的buff普通模式下的持续时间 @type {function(Player,number):number} */ getEntityEffectDurationNormal: ll.import("GMLIB_API", "getEntityEffectDurationNormal"), - /** 获取玩家的buff效果等级 @type {function(Player,number):number} */ + /** 获取实体的buff效果等级 @type {function(Player,number):number} */ getEntityEffectAmplifier: ll.import("GMLIB_API", "getEntityEffectAmplifier"), - /** 获取玩家的buff是否为信标给予 @type {function(Player,number):boolean} */ + /** 获取实体的buff是否为信标给予 @type {function(Player,number):boolean} */ getEntityEffectAmbient: ll.import("GMLIB_API", "getEntityEffectAmbient"), - /** 玩家是否拥有buff效果 @type {function(Player,number):boolean} */ + /** 实体是否拥有buff效果 @type {function(Player,number):boolean} */ entityHasEffect: ll.import("GMLIB_API", "entityHasEffect"), + /** 获取实体所有buff效果 @type {function(Entity):Array.} */ + getEntityAllEffects: ll.import("GMLIB_API", "getEntityAllEffects"), /** 获取游戏难度 @type {function():number} */ getGameDifficulty: ll.import("GMLIB_API", "getGameDifficulty"), /** 设置游戏难度 @type {function(difficulty):void} */ @@ -2585,7 +2587,7 @@ LLSE_Player.prototype.getDestroyProgress = LLSE_Entity.prototype.hasEffect = /** - * 玩家是否拥有buff效果 + * 实体是否拥有buff效果 * @param {number} effectId buff效果ID * @returns {boolean} */ diff --git a/src/CompatibilityApi.cpp b/src/CompatibilityApi.cpp index e09c092..ef3326c 100644 --- a/src/CompatibilityApi.cpp +++ b/src/CompatibilityApi.cpp @@ -1,5 +1,6 @@ #include "Global.h" #include +#include bool isInteger(const std::string& str) { std::regex pattern("^[+-]?\\d+$"); @@ -935,6 +936,14 @@ void Export_Compatibility_API() { RemoteCall::exportAs("GMLIB_API", "entityHasEffect", [](Actor* entity, int effectId) -> int { return entity->hasEffect(*MobEffect::getById(effectId)); }); + RemoteCall::exportAs("GMLIB_API", "getEntityAllEffects", [](Actor* entity) -> std::vector { + auto effects = entity->getAllEffects(); + std::vector results = {}; + for (auto effect : effects) { + results.push_back((int)effect.mId); + } + return results; + }); RemoteCall::exportAs("GMLIB_API", "getGameDifficulty", []() -> int { if (auto level = ll::service::getLevel()) { return (int)level->getDifficulty(); From 453f28ae6d1ea95f0f4bfd382b116034bbb14505 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=90=E6=B2=90=E5=91=80?= <163636894+zimuya4153@users.noreply.github.com> Date: Thu, 1 Aug 2024 21:32:13 +0800 Subject: [PATCH 35/37] =?UTF-8?q?=E5=88=A0=E9=99=A4getEntityAllEffects?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/GMLIB_API-JS.js | 2 -- src/CompatibilityApi.cpp | 8 -------- 2 files changed, 10 deletions(-) diff --git a/lib/GMLIB_API-JS.js b/lib/GMLIB_API-JS.js index 93daa30..9f5b5ca 100644 --- a/lib/GMLIB_API-JS.js +++ b/lib/GMLIB_API-JS.js @@ -360,8 +360,6 @@ const GMLIB_API = { getEntityEffectAmbient: ll.import("GMLIB_API", "getEntityEffectAmbient"), /** 实体是否拥有buff效果 @type {function(Player,number):boolean} */ entityHasEffect: ll.import("GMLIB_API", "entityHasEffect"), - /** 获取实体所有buff效果 @type {function(Entity):Array.} */ - getEntityAllEffects: ll.import("GMLIB_API", "getEntityAllEffects"), /** 获取游戏难度 @type {function():number} */ getGameDifficulty: ll.import("GMLIB_API", "getGameDifficulty"), /** 设置游戏难度 @type {function(difficulty):void} */ diff --git a/src/CompatibilityApi.cpp b/src/CompatibilityApi.cpp index ef3326c..e9518dc 100644 --- a/src/CompatibilityApi.cpp +++ b/src/CompatibilityApi.cpp @@ -936,14 +936,6 @@ void Export_Compatibility_API() { RemoteCall::exportAs("GMLIB_API", "entityHasEffect", [](Actor* entity, int effectId) -> int { return entity->hasEffect(*MobEffect::getById(effectId)); }); - RemoteCall::exportAs("GMLIB_API", "getEntityAllEffects", [](Actor* entity) -> std::vector { - auto effects = entity->getAllEffects(); - std::vector results = {}; - for (auto effect : effects) { - results.push_back((int)effect.mId); - } - return results; - }); RemoteCall::exportAs("GMLIB_API", "getGameDifficulty", []() -> int { if (auto level = ll::service::getLevel()) { return (int)level->getDifficulty(); From f8e5975fa77d4c46cf9862a63c71c91f2c86d22b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=90=E6=B2=90=E5=91=80?= <163636894+zimuya4153@users.noreply.github.com> Date: Thu, 1 Aug 2024 21:53:25 +0800 Subject: [PATCH 36/37] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/GMLIB_API-JS.js | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/lib/GMLIB_API-JS.js b/lib/GMLIB_API-JS.js index 9f5b5ca..585cac7 100644 --- a/lib/GMLIB_API-JS.js +++ b/lib/GMLIB_API-JS.js @@ -354,12 +354,14 @@ const GMLIB_API = { getEntityEffectDurationHard: ll.import("GMLIB_API", "getEntityEffectDurationHard"), /** 获取实体的buff普通模式下的持续时间 @type {function(Player,number):number} */ getEntityEffectDurationNormal: ll.import("GMLIB_API", "getEntityEffectDurationNormal"), - /** 获取实体的buff效果等级 @type {function(Player,number):number} */ + /** 获取实体的buff效果等级 @type {function(Entity,number):number} */ getEntityEffectAmplifier: ll.import("GMLIB_API", "getEntityEffectAmplifier"), - /** 获取实体的buff是否为信标给予 @type {function(Player,number):boolean} */ + /** 获取实体的buff是否为信标给予 @type {function(Entity,number):boolean} */ getEntityEffectAmbient: ll.import("GMLIB_API", "getEntityEffectAmbient"), - /** 实体是否拥有buff效果 @type {function(Player,number):boolean} */ + /** 实体是否拥有buff效果 @type {function(Entity,number):boolean} */ entityHasEffect: ll.import("GMLIB_API", "entityHasEffect"), + /** 获取实体所有buff效果 @type {function(Entity):Array.} */ + getEntityAllEffects: ll.import("GMLIB_API", "getEntityAllEffects"), /** 获取游戏难度 @type {function():number} */ getGameDifficulty: ll.import("GMLIB_API", "getGameDifficulty"), /** 设置游戏难度 @type {function(difficulty):void} */ @@ -2590,7 +2592,7 @@ LLSE_Entity.prototype.hasEffect = * @returns {boolean} */ function (effectId) { - return GMLIB_API.playerHasEffect(this, effectId); + return GMLIB_API.entityHasEffect(this, effectId); } LLSE_Entity.prototype.getEffectInfo = @@ -2602,7 +2604,7 @@ LLSE_Entity.prototype.getEffectInfo = function (effectId) { if (!this.hasEffect(effectId)) return null; return { - Id: id, + Id: effectId, Amplifier: GMLIB_API.getEntityEffectAmbient(this, effectId), Duration: GMLIB_API.getEntityEffectDuration(this, effectId), DurationEasy: GMLIB_API.getEntityEffectDurationEasy(this, effectId), @@ -2619,7 +2621,7 @@ LLSE_Entity.prototype.getAllEffectsInfo = * @returns {{Id: number, Amplifier: number, Duration: number, DurationEasy: number, DurationNormal: number, DurationHard: number, Ambient: boolean, ShowParticles: boolean}[]} */ function () { - this.getAllEffects().map(this.getEffectInfo); + return this.getAllEffects().map(effectId => this.getEffectInfo(effectId)); } module.exports = { From 7f3da4eb87660b40522f0a31f34f18c28edbaf31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=90=E6=B2=90=E5=91=80?= <163636894+zimuya4153@users.noreply.github.com> Date: Thu, 1 Aug 2024 22:01:38 +0800 Subject: [PATCH 37/37] =?UTF-8?q?=E4=BF=AE=E5=A4=8DgetEffectInfo=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/GMLIB_API-JS.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/GMLIB_API-JS.js b/lib/GMLIB_API-JS.js index 585cac7..59dbd69 100644 --- a/lib/GMLIB_API-JS.js +++ b/lib/GMLIB_API-JS.js @@ -2605,13 +2605,13 @@ LLSE_Entity.prototype.getEffectInfo = if (!this.hasEffect(effectId)) return null; return { Id: effectId, - Amplifier: GMLIB_API.getEntityEffectAmbient(this, effectId), + Amplifier: GMLIB_API.getEntityEffectAmplifier(this, effectId), Duration: GMLIB_API.getEntityEffectDuration(this, effectId), DurationEasy: GMLIB_API.getEntityEffectDurationEasy(this, effectId), DurationNormal: GMLIB_API.getEntityEffectDurationNormal(this, effectId), DurationHard: GMLIB_API.getEntityEffectDurationHard(this, effectId), Ambient: GMLIB_API.getEntityEffectAmbient(this, effectId), - ShowParticles: GMLIB_API.getEntityEffectAmbient(this, effectId), + ShowParticles: GMLIB_API.getEntityEffectVisible(this, effectId), } }