Compare commits
50 Commits
@@ -11,6 +11,8 @@ jobs:
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- uses: xmake-io/github-action-setup-xmake@v1
|
||||
with:
|
||||
xmake-version: "2.9.3"
|
||||
|
||||
- run: |
|
||||
xmake repo -u
|
||||
|
||||
@@ -11,6 +11,8 @@ jobs:
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- uses: xmake-io/github-action-setup-xmake@v1
|
||||
with:
|
||||
xmake-version: "2.9.3"
|
||||
|
||||
- run: |
|
||||
xmake repo -u
|
||||
|
||||
Vendored
+72
@@ -0,0 +1,72 @@
|
||||
declare class PAPI {
|
||||
/** 注册一个玩家PAPI变量 */
|
||||
static registerPlayerPlaceholder(
|
||||
/** PAPI调用函数 */
|
||||
func: (
|
||||
/** 玩家对象 */
|
||||
player: Player,
|
||||
/** 变量参数 */
|
||||
param: null | object.<string, string>
|
||||
) => string,
|
||||
/** 插件名字 */
|
||||
pluginsName: string,
|
||||
/** PAPI变量 */
|
||||
PAPIName: string
|
||||
): boolean;
|
||||
|
||||
/** 注册一个服务器PAPI变量 */
|
||||
static registerServerPlaceholder(
|
||||
/** PAPI调用函数 */
|
||||
func: (
|
||||
/** 变量参数 */
|
||||
param: null | object.<string, string>
|
||||
) => 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[];
|
||||
}
|
||||
@@ -1,47 +1,117 @@
|
||||
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.<string>} */
|
||||
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] || getStringHashCode(this.toString()).toString(16);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取字符串哈希值
|
||||
* @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 {
|
||||
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 +119,19 @@ class PAPI {
|
||||
return PlaceholderAPI.translateStringAPI(str);
|
||||
}
|
||||
|
||||
/**
|
||||
* 注销一个PAPI变量
|
||||
* @param {string} str PAPI变量名
|
||||
* @returns {boolean} 是否注销成功
|
||||
*/
|
||||
static unRegisterPlaceholder(str) {
|
||||
return PlaceholderAPI.unRegisterPlaceholderAPI(str);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有已注册的PAPI变量
|
||||
* @returns {Array.<string>} 已注册的PAPI变量数组
|
||||
*/
|
||||
static getAllPAPI() {
|
||||
return PlaceholderAPI.getAllPAPI();
|
||||
}
|
||||
|
||||
Vendored
+251
@@ -0,0 +1,251 @@
|
||||
/** 事件监听接口 */
|
||||
declare class Event {
|
||||
/** 生物捡起物品 */
|
||||
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: "onItemSpawned",
|
||||
/** 回调函数 */
|
||||
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: string[],
|
||||
/** 死亡实体的实体对象 */
|
||||
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: "onDragonRespawn",
|
||||
/** 回调函数 */
|
||||
listener: (
|
||||
/** 末影龙重生后的UniqueID */
|
||||
uniqueID: number
|
||||
) => boolean | void
|
||||
): boolean;
|
||||
|
||||
/** 弹射物实体尝试创建 */
|
||||
static listen(
|
||||
/** 事件名 */
|
||||
event: "onProjectileTryCreate",
|
||||
/** 回调函数 */
|
||||
listener: (
|
||||
/** 弹射物实体对象 */
|
||||
entity: Entity,
|
||||
/** 创建弹射的实体的uniqueID */
|
||||
uniqueId: number
|
||||
) => boolean | void
|
||||
): boolean;
|
||||
|
||||
/** 弹射物实体成功后(不可拦截) */
|
||||
static listen(
|
||||
/** 事件名 */
|
||||
event: "onProjectileCreate",
|
||||
/** 回调函数 */
|
||||
listener: (
|
||||
/** 弹射物实体对象 */
|
||||
entity: Entity,
|
||||
/** 创建弹射的实体的uniqueID */
|
||||
uniqueId: number
|
||||
) => void
|
||||
): boolean;
|
||||
|
||||
/** 生成流浪商人 */
|
||||
static listen(
|
||||
/** 事件名 */
|
||||
event: "onSpawnWanderingTrader",
|
||||
/** 回调函数 */
|
||||
listener: (
|
||||
/** 生成的坐标 */
|
||||
pos: IntPos
|
||||
) => boolean | void
|
||||
): boolean;
|
||||
|
||||
/** 处理物品请求 */
|
||||
static listen(
|
||||
/** 事件名 */
|
||||
event: "onHandleRequestAction",
|
||||
/** 回调函数 */
|
||||
listener: (
|
||||
/** 请求玩家 */
|
||||
player: Player,
|
||||
/** 请求类型 */
|
||||
actionType: string,
|
||||
/** 请求数量 */
|
||||
count: number,
|
||||
/** 第一个格子的容器类型 */
|
||||
sourceContainerNetId: string,
|
||||
/** 第一个格子的槽位 */
|
||||
sourceSlot: number,
|
||||
/** 第二个格子的容器类型 */
|
||||
destinationContainerNetId: string,
|
||||
/** 第二个格子的槽位 */
|
||||
destinationSlot: number
|
||||
) => boolean | void
|
||||
): boolean;
|
||||
|
||||
/** 发送容器关闭数据包后(不可拦截) */
|
||||
static listen(
|
||||
/** 事件名 */
|
||||
event: "onSendContainerClosePacket",
|
||||
/** 回调函数 */
|
||||
listener: (
|
||||
/** 要被关闭的玩家 */
|
||||
player: Player,
|
||||
/** 容器ID */
|
||||
containerId: number
|
||||
) => void
|
||||
): boolean;
|
||||
|
||||
/** 关闭服务器(不可拦截) */
|
||||
static listen(
|
||||
/** 事件名 */
|
||||
event: "onServerStopping",
|
||||
/** 回调函数 */
|
||||
listener: () => void
|
||||
): boolean;
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
Vendored
+1373
File diff suppressed because it is too large
Load Diff
+1714
-100
File diff suppressed because it is too large
Load Diff
+2
-1
@@ -1,9 +1,10 @@
|
||||
{
|
||||
"name": "${pluginName}",
|
||||
"entry": "${pluginFile}",
|
||||
"version": "0.12.8",
|
||||
"version": "0.13.2",
|
||||
"author": "GroupMountain",
|
||||
"type": "native",
|
||||
"passive": true,
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "GMLIB"
|
||||
|
||||
+285
-5
@@ -1,5 +1,6 @@
|
||||
#include "Global.h"
|
||||
#include <regex>
|
||||
#include <vector>
|
||||
|
||||
bool isInteger(const std::string& str) {
|
||||
std::regex pattern("^[+-]?\\d+$");
|
||||
@@ -510,8 +511,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);
|
||||
@@ -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,281 @@ 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<std::unordered_map<std::string, std::string>> {
|
||||
auto gameRules = ll::service::getLevel()->getGameRules().getRules();
|
||||
std::vector<std::unordered_map<std::string, std::string>> result;
|
||||
for (auto& gameRule : gameRules) {
|
||||
std::unordered_map<std::string, std::string> 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<std::string> {
|
||||
std::vector<int> enchants = EnchantUtils::getLegalEnchants(item->getItem());
|
||||
std::vector<std::string> 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 std::string(enchant->getStringId());
|
||||
}
|
||||
return "";
|
||||
});
|
||||
RemoteCall::exportAs(
|
||||
"GMLIB_API",
|
||||
"applyEnchant",
|
||||
[](ItemStack const* item, std::string const& typeName, int level, bool allowNonVanilla) -> bool {
|
||||
return EnchantUtils::applyEnchant(
|
||||
*(const_cast<ItemStack*>(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, std::string const& typeName) -> bool {
|
||||
return EnchantUtils::hasEnchant(
|
||||
Enchant::getEnchantTypeFromName(HashedString(typeName)),
|
||||
*(const_cast<ItemStack*>(item))
|
||||
);
|
||||
});
|
||||
RemoteCall::exportAs("GMLIB_API", "getEnchantLevel", [](ItemStack const* item, std::string const& typeName) -> int {
|
||||
return EnchantUtils::getEnchantLevel(
|
||||
Enchant::getEnchantTypeFromName(HashedString(typeName)),
|
||||
*(const_cast<ItemStack*>(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",
|
||||
[](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();
|
||||
});
|
||||
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(value);
|
||||
});
|
||||
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);
|
||||
});
|
||||
RemoteCall::exportAs("GMLIB_API", "getItemRepairCost", [](ItemStack const* item) -> int {
|
||||
return item->getBaseRepairCost();
|
||||
});
|
||||
RemoteCall::exportAs("GMLIB_API", "setItemRepairCost", [](ItemStack const* item, int cost) -> void {
|
||||
(*(const_cast<ItemStack*>(item))).setRepairCost(cost);
|
||||
});
|
||||
RemoteCall::exportAs("GMLIB_API", "getItemCanDestroy", [](ItemStack const* item) -> std::vector<std::string> {
|
||||
std::vector<std::string> 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<std::string> blocks) -> void {
|
||||
((GMLIB_ItemStack*)item)->setCanDestroy(blocks);
|
||||
}
|
||||
);
|
||||
RemoteCall::exportAs("GMLIB_API", "getItemCanPlaceOn", [](ItemStack const* item) -> std::vector<std::string> {
|
||||
std::vector<std::string> 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<std::string> blocks) -> void {
|
||||
((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();
|
||||
});
|
||||
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;
|
||||
});
|
||||
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) -> ItemStack* {
|
||||
return const_cast<ItemStack*>(&player->getPlayerUIItem((PlayerUISlot)slot));
|
||||
});
|
||||
RemoteCall::exportAs(
|
||||
"GMLIB_API",
|
||||
"sendInventorySlotPacket",
|
||||
[](Player* player, int containerId, int slot, ItemStack const* item) -> void {
|
||||
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", "hasPlayerNbt", [](std::string const& uuid) -> bool {
|
||||
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();
|
||||
});
|
||||
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);
|
||||
});
|
||||
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", "getEntityEffectDuration", [](Actor* entity, int effectId) -> int {
|
||||
if (auto effect = entity->getEffect(effectId)) {
|
||||
return effect->mDuration;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
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", "getEntityEffectDurationHard", [](Actor* entity, int effectId) -> int {
|
||||
if (auto effect = entity->getEffect(effectId)) {
|
||||
return effect->mDurationHard;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
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", "getEntityEffectAmplifier", [](Actor* entity, int effectId) -> int {
|
||||
if (auto effect = entity->getEffect(effectId)) {
|
||||
return effect->mAmplifier;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
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", "entityHasEffect", [](Actor* entity, int effectId) -> int {
|
||||
return entity->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);
|
||||
}
|
||||
});
|
||||
}
|
||||
+1
-1
@@ -33,4 +33,4 @@ bool LegacyRemoteCallApi::disable() { return true; }
|
||||
|
||||
} // namespace GMLIB
|
||||
|
||||
LL_REGISTER_PLUGIN(LegacyRemoteCallApi, LegacyRemoteCallApi::getInstance());
|
||||
LL_REGISTER_MOD(LegacyRemoteCallApi, LegacyRemoteCallApi::getInstance());
|
||||
|
||||
+5
-5
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
#include <ll/api/plugin/NativePlugin.h>
|
||||
#include <ll/api/plugin/RegisterHelper.h>
|
||||
#include <ll/api/mod/NativeMod.h>
|
||||
#include <ll/api/mod/RegisterHelper.h>
|
||||
|
||||
namespace GMLIB {
|
||||
|
||||
@@ -9,9 +9,9 @@ class LegacyRemoteCallApi {
|
||||
public:
|
||||
static std::unique_ptr<LegacyRemoteCallApi>& 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 @@ public:
|
||||
// bool unload();
|
||||
|
||||
private:
|
||||
ll::plugin::NativePlugin& mSelf;
|
||||
ll::mod::NativeMod& mSelf;
|
||||
};
|
||||
|
||||
} // namespace GMLIB
|
||||
|
||||
+320
-188
@@ -7,195 +7,327 @@ 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<bool(
|
||||
std::string const& realName,
|
||||
std::string const& uuid,
|
||||
std::string const& serverXuid,
|
||||
std::string const& clientXuid
|
||||
)>(eventName, eventId);
|
||||
eventBus->emplaceListener<Event::PacketEvent::ClientLoginAfterEvent>(
|
||||
[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<bool(int lightningLevel, int rainLevel, int lightningLast, int rainLast)>(
|
||||
eventName,
|
||||
eventId
|
||||
);
|
||||
eventBus->emplaceListener<Event::LevelEvent::WeatherUpdateBeforeEvent>(
|
||||
[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("onMobPick"): {
|
||||
auto Call = RemoteCall::importAs<bool(Actor * mob, Actor * item)>(eventName, eventId);
|
||||
eventBus->emplaceListener<Event::EntityEvent::MobPickupItemBeforeEvent>(
|
||||
[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("onItemTrySpawn"): {
|
||||
auto Call = RemoteCall::importAs<
|
||||
bool(const ItemStack* item, std::pair<Vec3, int> position, Actor* spawner)>(eventName, eventId);
|
||||
eventBus->emplaceListener<Event::EntityEvent::ItemActorSpawnBeforeEvent>(
|
||||
[Call](Event::EntityEvent::ItemActorSpawnBeforeEvent& ev) {
|
||||
auto pos = ev.getPosition();
|
||||
auto dimid = ev.getBlockSource().getDimensionId().id;
|
||||
std::pair<Vec3, int> lsePos = {pos, dimid};
|
||||
bool result = true;
|
||||
try {
|
||||
result = Call(&ev.getItem(), lsePos, ev.getSpawner());
|
||||
} catch (...) {}
|
||||
if (!result) {
|
||||
ev.cancel();
|
||||
}
|
||||
}
|
||||
);
|
||||
return true;
|
||||
}
|
||||
case doHash("onItemSpawned"): {
|
||||
auto Call = RemoteCall::importAs<
|
||||
bool(const ItemStack* item, Actor* itemActor, std::pair<Vec3, int> position, Actor* spawner)>(
|
||||
eventName,
|
||||
eventId
|
||||
);
|
||||
eventBus->emplaceListener<Event::EntityEvent::ItemActorSpawnAfterEvent>(
|
||||
[Call](Event::EntityEvent::ItemActorSpawnAfterEvent& ev) {
|
||||
auto pos = ev.getPosition();
|
||||
auto dimid = ev.getBlockSource().getDimensionId().id;
|
||||
std::pair<Vec3, int> lsePos = {pos, dimid};
|
||||
try {
|
||||
Call(&ev.getItem(), (Actor*)&ev.getItemActor(), lsePos, ev.getSpawner());
|
||||
} catch (...) {}
|
||||
}
|
||||
);
|
||||
return true;
|
||||
}
|
||||
case doHash("onEntityChangeDim"): {
|
||||
auto Call = RemoteCall::importAs<bool(Actor * entity, int toDimId)>(eventName, eventId);
|
||||
eventBus->emplaceListener<Event::EntityEvent::ActorChangeDimensionBeforeEvent>(
|
||||
[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<bool(Player * pl)>(eventName, eventId);
|
||||
eventBus->emplaceListener<Event::PlayerEvent::PlayerStopSleepBeforeEvent>(
|
||||
[Call](Event::PlayerEvent::PlayerStopSleepBeforeEvent& ev) {
|
||||
bool result = true;
|
||||
try {
|
||||
result = Call(&ev.self());
|
||||
} catch (...) {}
|
||||
if (!result) {
|
||||
ev.cancel();
|
||||
}
|
||||
}
|
||||
);
|
||||
return true;
|
||||
}
|
||||
case doHash("onDeathMessage"): {
|
||||
auto Call =
|
||||
RemoteCall::importAs<bool(std::string const& message, std::vector<std::string>, Actor* dead)>(
|
||||
eventName,
|
||||
eventId
|
||||
);
|
||||
eventBus->emplaceListener<Event::EntityEvent::DeathMessageAfterEvent>(
|
||||
[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<bool(Actor * mob, Actor * source, float damage, int cause)>(
|
||||
eventName,
|
||||
eventId
|
||||
);
|
||||
eventBus->emplaceListener<Event::EntityEvent::MobHurtAfterEvent>(
|
||||
[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<bool(Actor * mob)>(eventName, eventId);
|
||||
eventBus->emplaceListener<Event::EntityEvent::EndermanTakeBlockBeforeEvent>(
|
||||
[Call](Event::EntityEvent::EndermanTakeBlockBeforeEvent& ev) {
|
||||
bool result = true;
|
||||
try {
|
||||
result = Call(&ev.self());
|
||||
} catch (...) {}
|
||||
if (!result) {
|
||||
ev.cancel();
|
||||
}
|
||||
}
|
||||
);
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
if (!RemoteCall::hasFunc(eventName, eventId)) return false;
|
||||
switch (doHash(eventName)) {
|
||||
case doHash("onClientLogin"): {
|
||||
auto Call = RemoteCall::importAs<bool(
|
||||
std::string const& realName,
|
||||
std::string const& uuid,
|
||||
std::string const& serverXuid,
|
||||
std::string const& clientXuid
|
||||
)>(eventName, eventId);
|
||||
eventBus->emplaceListener<Event::PacketEvent::ClientLoginAfterEvent>(
|
||||
[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<bool(int lightningLevel, int rainLevel, int lightningLast, int rainLast)>(
|
||||
eventName,
|
||||
eventId
|
||||
);
|
||||
eventBus->emplaceListener<Event::LevelEvent::WeatherUpdateBeforeEvent>(
|
||||
[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("onMobPick"): {
|
||||
auto Call = RemoteCall::importAs<bool(Actor * mob, Actor * item)>(eventName, eventId);
|
||||
eventBus->emplaceListener<Event::EntityEvent::MobPickupItemBeforeEvent>(
|
||||
[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("onItemTrySpawn"): {
|
||||
auto Call =
|
||||
RemoteCall::importAs<bool(const ItemStack* item, std::pair<Vec3, int> position, Actor* spawner)>(
|
||||
eventName,
|
||||
eventId
|
||||
);
|
||||
eventBus->emplaceListener<Event::EntityEvent::ItemActorSpawnBeforeEvent>(
|
||||
[Call](Event::EntityEvent::ItemActorSpawnBeforeEvent& ev) {
|
||||
auto pos = ev.getPosition();
|
||||
auto dimid = ev.getBlockSource().getDimensionId().id;
|
||||
std::pair<Vec3, int> lsePos = {pos, dimid};
|
||||
bool result = true;
|
||||
try {
|
||||
result = Call(&ev.getItem(), lsePos, ev.getSpawner());
|
||||
} catch (...) {}
|
||||
if (!result) {
|
||||
ev.cancel();
|
||||
}
|
||||
}
|
||||
);
|
||||
return true;
|
||||
}
|
||||
case doHash("onItemSpawned"): {
|
||||
auto Call = RemoteCall::importAs<
|
||||
bool(const ItemStack* item, Actor* itemActor, std::pair<Vec3, int> position, Actor* spawner)>(
|
||||
eventName,
|
||||
eventId
|
||||
);
|
||||
eventBus->emplaceListener<Event::EntityEvent::ItemActorSpawnAfterEvent>(
|
||||
[Call](Event::EntityEvent::ItemActorSpawnAfterEvent& ev) {
|
||||
auto pos = ev.getPosition();
|
||||
auto dimid = ev.getBlockSource().getDimensionId().id;
|
||||
std::pair<Vec3, int> lsePos = {pos, dimid};
|
||||
try {
|
||||
Call(&ev.getItem(), (Actor*)&ev.getItemActor(), lsePos, ev.getSpawner());
|
||||
} catch (...) {}
|
||||
}
|
||||
);
|
||||
return true;
|
||||
}
|
||||
case doHash("onEntityChangeDim"): {
|
||||
auto Call = RemoteCall::importAs<bool(Actor * entity, int toDimId)>(eventName, eventId);
|
||||
eventBus->emplaceListener<Event::EntityEvent::ActorChangeDimensionBeforeEvent>(
|
||||
[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<bool(Player * pl)>(eventName, eventId);
|
||||
eventBus->emplaceListener<Event::PlayerEvent::PlayerStopSleepBeforeEvent>(
|
||||
[Call](Event::PlayerEvent::PlayerStopSleepBeforeEvent& ev) {
|
||||
bool result = true;
|
||||
try {
|
||||
result = Call(&ev.self());
|
||||
} catch (...) {}
|
||||
if (!result) {
|
||||
ev.cancel();
|
||||
}
|
||||
}
|
||||
);
|
||||
return true;
|
||||
}
|
||||
case doHash("onDeathMessage"): {
|
||||
auto Call =
|
||||
RemoteCall::importAs<bool(std::string const& message, std::vector<std::string>, Actor* dead)>(
|
||||
eventName,
|
||||
eventId
|
||||
);
|
||||
eventBus->emplaceListener<Event::EntityEvent::DeathMessageAfterEvent>(
|
||||
[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<bool(Actor * mob, Actor * source, float damage, int cause)>(
|
||||
eventName,
|
||||
eventId
|
||||
);
|
||||
eventBus->emplaceListener<Event::EntityEvent::MobHurtAfterEvent>(
|
||||
[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<bool(Actor * mob)>(eventName, eventId);
|
||||
eventBus->emplaceListener<Event::EntityEvent::EndermanTakeBlockBeforeEvent>(
|
||||
[Call](Event::EntityEvent::EndermanTakeBlockBeforeEvent& ev) {
|
||||
bool result = true;
|
||||
try {
|
||||
result = Call(&ev.self());
|
||||
} catch (...) {}
|
||||
if (!result) {
|
||||
ev.cancel();
|
||||
}
|
||||
}
|
||||
);
|
||||
return true;
|
||||
}
|
||||
case doHash("onEntityChangeDimAfter"): {
|
||||
auto Call = RemoteCall::importAs<bool(Actor * mob, int fromDimId)>(eventName, eventId);
|
||||
eventBus->emplaceListener<Event::EntityEvent::ActorChangeDimensionAfterEvent>(
|
||||
[Call](Event::EntityEvent::ActorChangeDimensionAfterEvent& ev) {
|
||||
bool result = true;
|
||||
try {
|
||||
result = Call(&ev.self(), ev.getFromDimensionId());
|
||||
} catch (...) {}
|
||||
}
|
||||
);
|
||||
return true;
|
||||
}
|
||||
case doHash("onDragonRespawn"): {
|
||||
auto Call = RemoteCall::importAs<bool(int64 enderDragonUniqueID)>(eventName, eventId);
|
||||
eventBus->emplaceListener<Event::EntityEvent::DragonRespawnBeforeEvent>(
|
||||
[Call](Event::EntityEvent::DragonRespawnBeforeEvent& ev) {
|
||||
bool result = true;
|
||||
try {
|
||||
result = Call(ev.getEnderDragon().id);
|
||||
} catch (...) {}
|
||||
if (!result) {
|
||||
ev.cancel();
|
||||
}
|
||||
}
|
||||
);
|
||||
return true;
|
||||
}
|
||||
case doHash("onProjectileTryCreate"): {
|
||||
auto Call = RemoteCall::importAs<bool(Actor * mob, int64 uniqueId)>(eventName, eventId);
|
||||
eventBus->emplaceListener<Event::EntityEvent::ProjectileCreateBeforeEvent>(
|
||||
[Call](Event::EntityEvent::ProjectileCreateBeforeEvent& ev) {
|
||||
bool result = true;
|
||||
try {
|
||||
auto uid = ev.getShooter() ? ev.getShooter()->getOrCreateUniqueID().id : -1;
|
||||
result = Call(&ev.self(), uid);
|
||||
} catch (...) {}
|
||||
if (!result) {
|
||||
ev.cancel();
|
||||
}
|
||||
}
|
||||
);
|
||||
return true;
|
||||
}
|
||||
case doHash("onProjectileCreate"): {
|
||||
auto Call = RemoteCall::importAs<bool(Actor * mob, int64 uniqueId)>(eventName, eventId);
|
||||
eventBus->emplaceListener<Event::EntityEvent::ProjectileCreateAfterEvent>(
|
||||
[Call](Event::EntityEvent::ProjectileCreateAfterEvent& ev) {
|
||||
try {
|
||||
auto uid = ev.getShooter() ? ev.getShooter()->getOrCreateUniqueID().id : -1;
|
||||
Call(&ev.self(), uid);
|
||||
} catch (...) {}
|
||||
}
|
||||
);
|
||||
return true;
|
||||
}
|
||||
case doHash("onSpawnWanderingTrader"): {
|
||||
auto Call = RemoteCall::importAs<bool(std::pair<BlockPos, int> pos)>(eventName, eventId);
|
||||
eventBus->emplaceListener<Event::EntityEvent::SpawnWanderingTraderBeforeEvent>(
|
||||
[Call](Event::EntityEvent::SpawnWanderingTraderBeforeEvent& ev) {
|
||||
bool result = true;
|
||||
try {
|
||||
result = Call({ev.getPos(), ev.getRegion().getDimensionId()});
|
||||
} catch (...) {}
|
||||
if (!result) {
|
||||
ev.cancel();
|
||||
}
|
||||
}
|
||||
);
|
||||
return true;
|
||||
}
|
||||
case doHash("onHandleRequestAction"): {
|
||||
auto Call = RemoteCall::importAs<bool(
|
||||
Player * player,
|
||||
std::string const& actionType,
|
||||
int count,
|
||||
std::string const& sourceContainerNetId,
|
||||
int sourceSlot,
|
||||
std::string const& destinationContainerNetId,
|
||||
int destinationSlot
|
||||
)>(eventName, eventId);
|
||||
eventBus->emplaceListener<Event::PlayerEvent::HandleRequestActionBeforeEvent>(
|
||||
[Call](Event::PlayerEvent::HandleRequestActionBeforeEvent& ev) {
|
||||
bool result = true;
|
||||
try {
|
||||
auto requestAction = (ItemStackRequestActionTransferBase*)&ev.getRequestAction();
|
||||
auto source = requestAction->getSrc();
|
||||
// TODO: The next version of LeviLamina changes to a member function
|
||||
auto destination = ll::memory::dAccess<ItemStackRequestSlotInfo>(requestAction, 56);
|
||||
result = Call(
|
||||
&ev.self(),
|
||||
magic_enum::enum_name(requestAction->mActionType).data(),
|
||||
ll::memory::dAccess<uchar>(requestAction, 18),
|
||||
magic_enum::enum_name(source.mOpenContainerNetId).data(),
|
||||
source.mSlot,
|
||||
magic_enum::enum_name(destination.mOpenContainerNetId).data(),
|
||||
destination.mSlot
|
||||
);
|
||||
} catch (...) {}
|
||||
if (!result) {
|
||||
ev.cancel();
|
||||
}
|
||||
}
|
||||
);
|
||||
return true;
|
||||
}
|
||||
case doHash("onSendContainerClosePacket"): {
|
||||
auto Call = RemoteCall::importAs<bool(Player * player, int ContainerNetId)>(eventName, eventId);
|
||||
eventBus->emplaceListener<Event::PacketEvent::ContainerClosePacketSendAfterEvent>(
|
||||
[Call](Event::PacketEvent::ContainerClosePacketSendAfterEvent& ev) {
|
||||
try {
|
||||
Call(
|
||||
ev.getServerNetworkHandler()
|
||||
.getServerPlayer(ev.getNetworkIdentifier(), ev.getPacket().mClientSubId),
|
||||
(int)ev.getPacket().mContainerId
|
||||
);
|
||||
} catch (...) {}
|
||||
}
|
||||
);
|
||||
return true;
|
||||
}
|
||||
case doHash("onServerStopping"): {
|
||||
auto Call = RemoteCall::importAs<bool()>(eventName, eventId);
|
||||
eventBus->emplaceListener<ll::event::server::ServerStoppingEvent>(
|
||||
[Call](ll::event::server::ServerStoppingEvent& ev) {
|
||||
try {
|
||||
Call();
|
||||
} catch (...) {}
|
||||
}
|
||||
);
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
);
|
||||
}
|
||||
+2
-2
@@ -10,8 +10,8 @@ using namespace Mod;
|
||||
#define PLUGIN_NAME fmt::format(fg(fmt::color::light_green), "GMLIB-LRCA")
|
||||
|
||||
#define LIB_VERSION_MAJOR 0
|
||||
#define LIB_VERSION_MINOR 12
|
||||
#define LIB_VERSION_PATCH 8
|
||||
#define LIB_VERSION_MINOR 13
|
||||
#define LIB_VERSION_PATCH 2
|
||||
|
||||
#define LIB_VERSION Version(LIB_VERSION_MAJOR, LIB_VERSION_MINOR, LIB_VERSION_PATCH)
|
||||
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
#include "GMLIB/Server/FakeListAPI.h"
|
||||
#include "Global.h"
|
||||
#include "mc/world/ActorUniqueID.h"
|
||||
|
||||
void Export_Legacy_GMLib_ServerAPI() {
|
||||
RemoteCall::exportAs("GMLib_ServerAPI", "setEducationFeatureEnabled", []() -> void {
|
||||
@@ -40,7 +38,7 @@ void Export_Legacy_GMLib_ServerAPI() {
|
||||
"GMLib_ServerAPI",
|
||||
"spawnEntity",
|
||||
[](std::pair<Vec3, int> pos, std::string const& name) -> Actor* {
|
||||
return GMLIB_Spawner::spawnEntity(pos.first, pos.second, name);
|
||||
return GMLIB_Spawner::spawnEntity(pos.first, pos.second, name).as_ptr();
|
||||
}
|
||||
);
|
||||
RemoteCall::exportAs(
|
||||
@@ -48,7 +46,7 @@ void Export_Legacy_GMLib_ServerAPI() {
|
||||
"shootProjectile",
|
||||
[](Actor* owner, std::string const& name, float speed, float offset) -> Actor* {
|
||||
auto ac = (GMLIB_Actor*)owner;
|
||||
return ac->shootProjectile(name, speed, offset);
|
||||
return ac->shootProjectile(name, speed, offset).as_ptr();
|
||||
}
|
||||
);
|
||||
RemoteCall::exportAs(
|
||||
@@ -73,4 +71,10 @@ void Export_Legacy_GMLib_ServerAPI() {
|
||||
RemoteCall::exportAs("GMLib_ServerAPI", "removeAllFakeList", []() -> void {
|
||||
return FakeList::removeAllFakeLists();
|
||||
});
|
||||
RemoteCall::exportAs("GMLib_ServerAPI", "getMaxPlayers", []() -> int {
|
||||
if (auto level = GMLIB_Level::getInstance()) {
|
||||
return level->getMaxPlayerCount();
|
||||
}
|
||||
return {};
|
||||
});
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ bool registerPlayerPlaceholder(
|
||||
std::string const& PAPIName
|
||||
) {
|
||||
if (RemoteCall::hasFunc(PluginName, FuncName)) {
|
||||
PlaceholderAPI::unregisterPlaceholder(PAPIName);
|
||||
if (isParameters(PAPIName)) {
|
||||
auto Call = RemoteCall::importAs<std::string(Player * pl, std::unordered_map<std::string, std::string>)>(
|
||||
PluginName,
|
||||
@@ -54,6 +55,7 @@ bool registerServerPlaceholder(
|
||||
std::string const& PAPIName
|
||||
) {
|
||||
if (RemoteCall::hasFunc(PluginName, FuncName)) {
|
||||
PlaceholderAPI::unregisterPlaceholder(PAPIName);
|
||||
if (isParameters(PAPIName)) {
|
||||
auto Call =
|
||||
RemoteCall::importAs<std::string(std::unordered_map<std::string, std::string>)>(PluginName, FuncName);
|
||||
@@ -78,6 +80,7 @@ bool registerStaticPlaceholder(
|
||||
int num
|
||||
) {
|
||||
if (RemoteCall::hasFunc(PluginName, FuncName)) {
|
||||
PlaceholderAPI::unregisterPlaceholder(PAPIName);
|
||||
if (isParameters(PAPIName)) {
|
||||
auto Call = RemoteCall::importAs<std::string()>(PluginName, FuncName);
|
||||
if (num == -1) {
|
||||
|
||||
+3
-3
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"format_version": 2,
|
||||
"tooth": "github.com/GroupMountain/GMLIB-LegacyRemoteCallApi",
|
||||
"version": "0.12.8",
|
||||
"version": "0.13.2",
|
||||
"info": {
|
||||
"name": "GMLIB-LegacyRemoteCallApi",
|
||||
"description": "Legacy RemoteCall API for GMLIB",
|
||||
@@ -14,9 +14,9 @@
|
||||
"library"
|
||||
]
|
||||
},
|
||||
"asset_url": "https://github.com/GroupMountain/GMLIB-LegacyRemoteCallApi/releases/download/v0.12.8/GMLIB-LegacyRemoteCallApi-windows-x64.zip",
|
||||
"asset_url": "https://github.com/GroupMountain/GMLIB-LegacyRemoteCallApi/releases/download/v0.13.2/GMLIB-LegacyRemoteCallApi-windows-x64.zip",
|
||||
"dependencies": {
|
||||
"github.com/GroupMountain/GMLIB": ">=0.12.8"
|
||||
"github.com/GroupMountain/GMLIB": ">=0.13.0"
|
||||
},
|
||||
"files": {
|
||||
"place": [
|
||||
|
||||
@@ -8,7 +8,7 @@ if not has_config("vs_runtime") then
|
||||
end
|
||||
|
||||
-- Option 1: Use the latest version of LeviLamina released on GitHub.
|
||||
add_requires("levilamina")
|
||||
add_requires("levilaminalibrary")
|
||||
add_requires("legacyremotecall")
|
||||
add_requires("gmlib")
|
||||
|
||||
@@ -59,7 +59,7 @@ target("GMLIB-LegacyRemoteCallApi") -- Change this to your plugin name.
|
||||
"src"
|
||||
)
|
||||
add_packages(
|
||||
"levilamina",
|
||||
"levilaminalibrary",
|
||||
"legacyremotecall",
|
||||
"gmlib"
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user