LiteLoaderBDS-1.16.40/ScriptEngine/API/PlayerAPI.cpp

2368 lines
70 KiB
C++

#include "APIHelp.h"
#include "BaseAPI.h"
#include "BlockAPI.h"
#include "DeviceAPI.h"
#include "EntityAPI.h"
#include "PlayerAPI.h"
#include "McAPI.h"
#include "ContainerAPI.h"
#include "ItemAPI.h"
#include "GuiAPI.h"
#include "NbtAPI.h"
#include "PacketAPI.h"
#include "NativeAPI.h"
#include <Engine/EngineOwnData.h>
#include <Engine/GlobalShareData.h>
#include <MC/Player.hpp>
#include <MC/NetworkIdentifier.hpp>
#include <MC/Actor.hpp>
#include <MC/Container.hpp>
#include <MC/SimpleContainer.hpp>
#include <MC/Scoreboard.hpp>
#include <MC/Objective.hpp>
#include <MC/ScoreboardId.hpp>
#include <MC/ListTag.hpp>
#include <MC/CompoundTag.hpp>
#include <MC/BlockSource.hpp>
#include <PlayerInfoAPI.h>
#include <SafeGuardRecord.h>
#include <string>
#include <vector>
#include <unordered_map>
#include <algorithm>
using namespace std;
//////////////////// Class Definition ////////////////////
ClassDefine<PlayerClass> PlayerClassBuilder =
defineClass<PlayerClass>("LLSE_Player")
.constructor(nullptr)
.instanceFunction("asPointer", &PlayerClass::asPointer)
.instanceProperty("name", &PlayerClass::getName)
.instanceProperty("pos", &PlayerClass::getPos)
.instanceProperty("blockPos", &PlayerClass::getBlockPos)
.instanceProperty("lastDeathPos", &PlayerClass::getLastDeathPos)
.instanceProperty("realName", &PlayerClass::getRealName)
.instanceProperty("xuid", &PlayerClass::getXuid)
.instanceProperty("uuid", &PlayerClass::getUuid)
.instanceProperty("permLevel", &PlayerClass::getPermLevel)
.instanceProperty("gameMode", &PlayerClass::getGameMode)
.instanceProperty("canSleep", &PlayerClass::getCanSleep)
.instanceProperty("canFly", &PlayerClass::getCanFly)
.instanceProperty("canBeSeenOnMap", &PlayerClass::getCanBeSeenOnMap)
.instanceProperty("canFreeze", &PlayerClass::getCanFreeze)
.instanceProperty("canSeeDaylight", &PlayerClass::getCanSeeDaylight)
.instanceProperty("canShowNameTag", &PlayerClass::getCanShowNameTag)
.instanceProperty("canStartSleepInBed", &PlayerClass::getCanStartSleepInBed)
.instanceProperty("canPickupItems", &PlayerClass::getCanPickupItems)
.instanceProperty("maxHealth", &PlayerClass::getMaxHealth)
.instanceProperty("health", &PlayerClass::getHealth)
.instanceProperty("inAir", &PlayerClass::getInAir)
.instanceProperty("inWater", &PlayerClass::getInWater)
.instanceProperty("inLava", &PlayerClass::getInLava)
.instanceProperty("inRain", &PlayerClass::getInRain)
.instanceProperty("inSnow", &PlayerClass::getInSnow)
.instanceProperty("inWall", &PlayerClass::getInWall)
.instanceProperty("inWaterOrRain", &PlayerClass::getInWaterOrRain)
.instanceProperty("inWorld", &PlayerClass::getInWorld)
.instanceProperty("inClouds", &PlayerClass::getInClouds)
.instanceProperty("sneaking", &PlayerClass::getSneaking)
.instanceProperty("speed", &PlayerClass::getSpeed)
.instanceProperty("direction", &PlayerClass::getDirection)
.instanceProperty("uniqueId", &PlayerClass::getUniqueID)
.instanceProperty("langCode", &PlayerClass::getLangCode)
.instanceProperty("isLoading", &PlayerClass::isLoading)
.instanceProperty("isInvisible", &PlayerClass::isInvisible)
.instanceProperty("isInsidePortal", &PlayerClass::isInsidePortal)
.instanceProperty("isHurt", &PlayerClass::isHurt)
.instanceProperty("isTrusting", &PlayerClass::isTrusting)
.instanceProperty("isTouchingDamageBlock", &PlayerClass::isTouchingDamageBlock)
.instanceProperty("isHungry", &PlayerClass::isHungry)
.instanceProperty("isOnFire", &PlayerClass::isOnFire)
.instanceProperty("isOnGround", &PlayerClass::isOnGround)
.instanceProperty("isOnHotBlock", &PlayerClass::isOnHotBlock)
.instanceProperty("isTrading", &PlayerClass::isTrading)
.instanceProperty("isAdventure", &PlayerClass::isAdventure)
.instanceProperty("isGliding", &PlayerClass::isGliding)
.instanceProperty("isSurvival", &PlayerClass::isSurvival)
// .instanceProperty("isSpectator", &PlayerClass::isSpectator)
.instanceProperty("isRiding", &PlayerClass::isRiding)
.instanceProperty("isDancing", &PlayerClass::isDancing)
.instanceProperty("isCreative", &PlayerClass::isCreative)
.instanceProperty("isFlying", &PlayerClass::isFlying)
.instanceProperty("isSleeping", &PlayerClass::isSleeping)
.instanceFunction("isOP", &PlayerClass::isOP)
.instanceFunction("setPermLevel", &PlayerClass::setPermLevel)
.instanceFunction("setGameMode", &PlayerClass::setGameMode)
.instanceFunction("runcmd", &PlayerClass::runcmd)
.instanceFunction("teleport", &PlayerClass::teleport)
.instanceFunction("kill", &PlayerClass::kill)
.instanceFunction("kick", &PlayerClass::kick)
.instanceFunction("disconnect", &PlayerClass::kick)
.instanceFunction("tell", &PlayerClass::tell)
.instanceFunction("talkAs", &PlayerClass::talkAs)
.instanceFunction("sendText", &PlayerClass::tell)
.instanceFunction("rename", &PlayerClass::rename)
.instanceFunction("setFire", &PlayerClass::setFire)
.instanceFunction("transServer", &PlayerClass::transServer)
.instanceFunction("crash", &PlayerClass::crash)
.instanceFunction("hurt", &PlayerClass::hurt)
// .instanceFunction("refreshChunks", &PlayerClass::refreshChunks)
.instanceFunction("giveItem", &PlayerClass::giveItem)
.instanceFunction("clearItem", &PlayerClass::clearItem)
.instanceFunction("isSprinting", &PlayerClass::isSprinting)
.instanceFunction("setSprinting", &PlayerClass::setSprinting)
// .instanceFunction("sendToast", &PlayerClass::sendToast)
.instanceFunction("getBlockStandingOn", &PlayerClass::getBlockStandingOn)
.instanceFunction("getDevice", &PlayerClass::getDevice)
.instanceFunction("getHand", &PlayerClass::getHand)
.instanceFunction("getOffHand", &PlayerClass::getOffHand)
.instanceFunction("getInventory", &PlayerClass::getInventory)
.instanceFunction("getArmor", &PlayerClass::getArmor)
.instanceFunction("getEnderChest", &PlayerClass::getEnderChest)
.instanceFunction("getRespawnPosition", &PlayerClass::getRespawnPosition)
.instanceFunction("setRespawnPosition", &PlayerClass::setRespawnPosition)
.instanceFunction("refreshItems", &PlayerClass::refreshItems)
.instanceFunction("getScore", &PlayerClass::getScore)
.instanceFunction("setScore", &PlayerClass::setScore)
.instanceFunction("addScore", &PlayerClass::addScore)
.instanceFunction("reduceScore", &PlayerClass::reduceScore)
.instanceFunction("deleteScore", &PlayerClass::deleteScore)
.instanceFunction("setSidebar", &PlayerClass::setSidebar)
.instanceFunction("removeSidebar", &PlayerClass::removeSidebar)
.instanceFunction("setBossBar", &PlayerClass::setBossBar)
.instanceFunction("removeBossBar", &PlayerClass::removeBossBar)
.instanceFunction("addLevel", &PlayerClass::addLevel)
.instanceFunction("reduceLevel", &PlayerClass::reduceLevel)
.instanceFunction("getLevel", &PlayerClass::getLevel)
.instanceFunction("setLevel", &PlayerClass::setLevel)
.instanceFunction("resetLevel", &PlayerClass::resetLevel)
.instanceFunction("addExperience", &PlayerClass::addExperience)
.instanceFunction("reduceExperience", &PlayerClass::reduceExperience)
.instanceFunction("getCurrentExperience", &PlayerClass::getCurrentExperience)
.instanceFunction("setCurrentExperience", &PlayerClass::setCurrentExperience)
.instanceFunction("getTotalExperience", &PlayerClass::getTotalExperience)
.instanceFunction("setTotalExperience", &PlayerClass::setTotalExperience)
.instanceFunction("getXpNeededForNextLevel", &PlayerClass::getXpNeededForNextLevel)
.instanceFunction("sendSimpleForm", &PlayerClass::sendSimpleForm)
.instanceFunction("sendModalForm", &PlayerClass::sendModalForm)
.instanceFunction("sendCustomForm", &PlayerClass::sendCustomForm)
.instanceFunction("sendForm", &PlayerClass::sendForm)
.instanceFunction("sendPacket",&PlayerClass::sendPacket)
.instanceFunction("setExtraData", &PlayerClass::setExtraData)
.instanceFunction("getExtraData", &PlayerClass::getExtraData)
.instanceFunction("delExtraData", &PlayerClass::delExtraData)
.instanceFunction("setNbt", &PlayerClass::setNbt)
.instanceFunction("getNbt", &PlayerClass::getNbt)
.instanceFunction("addTag", &PlayerClass::addTag)
// .instanceFunction("removeTag", &PlayerClass::removeTag)
.instanceFunction("hasTag", &PlayerClass::hasTag)
.instanceFunction("getAllTags", &PlayerClass::getAllTags)
.instanceFunction("getAbilities", &PlayerClass::getAbilities)
.instanceFunction("getAttributes", &PlayerClass::getAttributes)
.instanceFunction("getEntityFromViewVector", &PlayerClass::getEntityFromViewVector)
// .instanceFunction("getBlockFromViewVector", &PlayerClass::getBlockFromViewVector)
// .instanceFunction("quickEvalMolangScript", &PlayerClass::quickEvalMolangScript)
// SimulatedPlayer API
// .instanceFunction("isSimulatedPlayer", &PlayerClass::isSimulatedPlayer)
// .instanceFunction("simulateSneak", &PlayerClass::simulateSneak)
// .instanceFunction("simulateAttack", &PlayerClass::simulateAttack)
// .instanceFunction("simulateDestroy", &PlayerClass::simulateDestroy)
// .instanceFunction("simulateDisconnect", &PlayerClass::simulateDisconnect)
// .instanceFunction("simulateInteract", &PlayerClass::simulateInteract)
// .instanceFunction("simulateJump", &PlayerClass::simulateJump)
// .instanceFunction("simulateLocalMove", &PlayerClass::simulateLocalMove)
// .instanceFunction("simulateWorldMove", &PlayerClass::simulateWorldMove)
// .instanceFunction("simulateMoveTo", &PlayerClass::simulateMoveTo)
// .instanceFunction("simulateLookAt", &PlayerClass::simulateLookAt)
// .instanceFunction("simulateSetBodyRotation", &PlayerClass::simulateSetBodyRotation)
// .instanceFunction("simulateNavigateTo", &PlayerClass::simulateNavigateTo)
// .instanceFunction("simulateUseItem", &PlayerClass::simulateUseItem)
// .instanceFunction("simulateStopDestroyingBlock", &PlayerClass::simulateStopDestroyingBlock)
// .instanceFunction("simulateStopInteracting", &PlayerClass::simulateStopInteracting)
// .instanceFunction("simulateStopMoving", &PlayerClass::simulateStopMoving)
// .instanceFunction("simulateStopUsingItem", &PlayerClass::simulateStopUsingItem)
// .instanceFunction("simulateStopSneaking", &PlayerClass::simulateStopSneaking)
// For Compatibility
.instanceProperty("ip", &PlayerClass::getIP)
.instanceFunction("setTag", &PlayerClass::setNbt)
.instanceFunction("getTag", &PlayerClass::getNbt)
.instanceFunction("setOnFire", &PlayerClass::setOnFire)
.instanceFunction("removeItem", &PlayerClass::removeItem)
.instanceFunction("getAllItems", &PlayerClass::getAllItems)
.instanceFunction("removeScore", &PlayerClass::deleteScore)
.build();
//////////////////// Classes ////////////////////
//生成函数
PlayerClass::PlayerClass(Player* p)
: ScriptClass(ScriptClass::ConstructFromCpp<PlayerClass>{}) {
set(p);
}
Local<Object> PlayerClass::newPlayer(Player* p) {
auto newp = new PlayerClass(p);
return newp->getScriptObject();
}
Player* PlayerClass::extract(Local<Value> v) {
if (EngineScope::currentEngine()->isInstanceOf<PlayerClass>(v))
return EngineScope::currentEngine()->getNativeInstance<PlayerClass>(v)->get();
else
return nullptr;
}
//公用API
Local<Value> McClass::getPlayer(const Arguments& args) {
CHECK_ARGS_COUNT(args, 1)
CHECK_ARG_TYPE(args[0], ValueKind::kString)
try {
string target = args[0].toStr();
if (target.empty())
return Local<Value>();
transform(target.begin(), target.end(), target.begin(), ::tolower); // lower case the string
auto playerList = Level::getAllPlayers();
int delta = 2147483647; // c++ int max
Player* found = nullptr;
for (Player* p : playerList) {
if (p->getXuid() == target)
return PlayerClass::newPlayer(p);
string pName = p->getName();
transform(pName.begin(), pName.end(), pName.begin(), ::tolower);
if (pName.find(target) == 0) {
// 0 ís the index where the "target" appear in "pName"
int curDelta = pName.length() - target.length();
if (curDelta == 0)
return PlayerClass::newPlayer(p);
if (curDelta < delta) {
found = p;
delta = curDelta;
}
}
}
return found ? PlayerClass::newPlayer(found) : Local<Value>(); // Player/Null
}
CATCH("Fail in GetPlayer!")
}
Local<Value> McClass::getOnlinePlayers(const Arguments& args) {
try {
auto players = Level::getAllPlayers();
Local<Array> list = Array::newArray();
for (auto p : players)
list.add(PlayerClass::newPlayer(p));
return list;
}
CATCH("Fail in GetOnlinePlayers!")
}
Local<Value> McClass::broadcast(const Arguments& args) {
CHECK_ARGS_COUNT(args, 1)
CHECK_ARG_TYPE(args[0], ValueKind::kString)
try {
TextType type = TextType::RAW;
if (args.size() >= 2 && args[1].isNumber()) {
int newType = args[1].asNumber().toInt32();
if (newType >= 0 && newType <= 9)
type = (TextType)newType;
}
Level::broadcastText(args[0].toStr(), type);
return Boolean::newBoolean(true);
}
CATCH("Fail in Broadcast!")
}
//成员函数
void PlayerClass::set(Player* player) {
__try {
id = player->getUniqueID();
} __except (EXCEPTION_EXECUTE_HANDLER) {
isValid = false;
}
}
Player* PlayerClass::get() {
if (!isValid)
return nullptr;
else
return Global<Level>->getPlayer(id);
}
Local<Value> PlayerClass::getName() {
try {
Player* player = get();
if (!player)
return Local<Value>();
return String::newString(player->getName());
}
CATCH("Fail in getPlayerName!")
}
Local<Value> PlayerClass::getPos() {
try {
Player* player = get();
if (!player)
return Local<Value>();
return FloatPos::newPos(player->getPosition(), player->getDimensionId());
}
CATCH("Fail in getPlayerPos!")
}
Local<Value> PlayerClass::getBlockPos() {
try {
Player* player = get();
if (!player)
return Local<Value>();
return IntPos::newPos(player->getBlockPos(), player->getDimensionId());
}
CATCH("Fail in getPlayerBlockPos!")
}
//TODO 有函数没有
Local<Value> PlayerClass::getLastDeathPos() {
try {
// Player* player = get();
// if (!player || player->hasDiedBefore()) {
// return Local<Value>();
// }
//
// return IntPos::newPos(player->getLastDeathPos().value(), player->getLastDeathDimension().value());
return Boolean::newBoolean(-1);
}
CATCH("Fail in getLastDeathPos!")
}
Local<Value> PlayerClass::getXuid() {
try {
Player* player = get();
if (!player)
return Local<Value>();
string xuid;
try {
xuid = player->getXuid();
} catch (...) {
logger.debug("Fail in getXuid!");
xuid = PlayerInfo::getXuid(player->getRealName());
}
return String::newString(xuid);
}
CATCH("Fail in getXuid!")
}
Local<Value> PlayerClass::getUuid() {
try {
Player* player = get();
if (!player)
return Local<Value>();
string uuid;
try {
uuid = player->getUuid();
} catch (...) {
logger.debug("Fail in getUuid!");
uuid = PlayerInfo::getUUID(player->getRealName());
}
return String::newString(uuid);
}
CATCH("Fail in getUuid!")
}
Local<Value> PlayerClass::getRealName() {
try {
Player* player = get();
if (!player)
return Local<Value>();
return String::newString(player->getRealName());
}
CATCH("Fail in getRealName!")
}
Local<Value> PlayerClass::getIP() {
try {
Player* player = get();
if (!player)
return Local<Value>();
return String::newString(player->getNetworkIdentifier()->getIP());
}
CATCH("Fail in GetIP!")
}
Local<Value> PlayerClass::getPermLevel() {
try {
Player* player = get();
if (!player)
return Local<Value>();
return Number::newNumber(player->getCommandPermissionLevel());
}
CATCH("Fail in getPlayerPermLevel!")
}
//TODO 有函数没有
Local<Value> PlayerClass::getGameMode() {
try {
Player* player = get();
if (!player)
return Local<Value>();
// return Number::newNumber((int)player->getPlayerGameType()); //==========???
return Boolean::newBoolean(-1);
}
CATCH("Fail in getGameMode!")
}
//TODO 有函数没有
Local<Value> PlayerClass::getCanSleep() {
try {
Player* player = get();
if (!player)
return Local<Value>();
// return Boolean::newBoolean(player->canSleep());
return Boolean::newBoolean(-1);
}
CATCH("Fail in getCanSleep!")
}
//TODO 有函数没有
Local<Value> PlayerClass::getCanFly() {
try {
Player* player = get();
if (!player)
return Local<Value>();
// return Boolean::newBoolean(player->canFly());
return Boolean::newBoolean(-1);
}
CATCH("Fail in getCanFly!")
}
Local<Value> PlayerClass::getCanBeSeenOnMap() {
try {
Player* player = get();
if (!player) {
return Local<Value>();
}
return Boolean::newBoolean(player->canBeSeenOnMap());
}
CATCH("Fail in getCanBeSeenOnMap!")
}
//TODO 有函数没有
Local<Value> PlayerClass::getCanFreeze() {
try {
Player* player = get();
if (!player) {
return Local<Value>();
}
// return Boolean::newBoolean(player->canFreeze());
return Boolean::newBoolean(-1);
}
CATCH("Fail in getCanFreeze!")
}
//TODO 有函数没有
Local<Value> PlayerClass::getCanSeeDaylight() {
try {
Player* player = get();
if (!player) {
return Local<Value>();
}
// return Boolean::newBoolean(player->canSeeDaylight());
return Boolean::newBoolean(-1);
}
CATCH("Fail in getCanSeeDaylight!")
}
Local<Value> PlayerClass::getCanShowNameTag() {
try {
Player* player = get();
if (!player) {
return Local<Value>();
}
return Boolean::newBoolean(player->canShowNameTag());
}
CATCH("Fail in getCanShowNameTag!")
}
Local<Value> PlayerClass::getCanStartSleepInBed() {
try {
Player* player = get();
if (!player) {
return Local<Value>();
}
return Boolean::newBoolean(player->canStartSleepInBed());
}
CATCH("Fail in getCanStartSleepInBed!")
}
//TODO 有函数没有
Local<Value> PlayerClass::getCanPickupItems() {
try {
Player* player = get();
if (!player) {
return Local<Value>();
}
// return Boolean::newBoolean(player->getCanPickupItems());
return Boolean::newBoolean(-1);
}
CATCH("Fail in getCanPickupItems!")
}
Local<Value> PlayerClass::getSneaking() {
try {
Player* player = get();
if (!player)
return Local<Value>();
return Boolean::newBoolean(player->isSneaking());
}
CATCH("Fail in getSneaking!")
}
Local<Value> PlayerClass::getSpeed() {
try {
Player* player = get();
if (!player)
return Local<Value>();
return Number::newNumber(player->getSpeed());
}
CATCH("Fail in getSpeed!")
}
Local<Value> PlayerClass::getDirection() {
try {
Player* player = get();
if (!player)
return Local<Value>();
Vec2 rot = player->getRotation();
return DirectionAngle::newAngle(rot.x, rot.y);
}
CATCH("Fail in getDirection!")
}
//TODO 有函数没有
Local<Value> PlayerClass::getMaxHealth() {
try {
Player* player = get();
if (!player)
return Local<Value>();
// return Number::newNumber(player->getMaxHealth());
return Boolean::newBoolean(-1);
}
CATCH("Fail in GetMaxHealth!")
}
//TODO 有函数没有
Local<Value> PlayerClass::getHealth() {
try {
Player* player = get();
if (!player)
return Local<Value>();
// return Number::newNumber(player->getHealth());
return Boolean::newBoolean(-1);
}
CATCH("Fail in GetHealth!")
}
Local<Value> PlayerClass::getInAir() {
try {
Player* player = get();
if (!player)
return Local<Value>();
return Boolean::newBoolean(!player->isOnGround() && !player->isInWater());
}
CATCH("Fail in GetInAir!")
}
Local<Value> PlayerClass::getInWater() {
try {
Player* player = get();
if (!player)
return Local<Value>();
return Boolean::newBoolean(player->isInWater());
}
CATCH("Fail in getInWater!")
}
Local<Value> PlayerClass::getInLava() {
try {
Player* player = get();
if (!player)
return Local<Value>();
return Boolean::newBoolean(player->isInLava());
}
CATCH("Fail in getInLava!")
}
Local<Value> PlayerClass::getInRain() {
try {
Player* player = get();
if (!player)
return Local<Value>();
return Boolean::newBoolean(player->isInRain());
}
CATCH("Fail in getInRain!")
}
//TODO 有函数没有
Local<Value> PlayerClass::getInSnow() {
try {
Player* player = get();
if (!player)
return Local<Value>();
// return Boolean::newBoolean(player->isInSnow());
return Boolean::newBoolean(-1);
}
CATCH("Fail in getInSnow!")
}
Local<Value> PlayerClass::getInWall() {
try {
Player* player = get();
if (!player)
return Local<Value>();
return Boolean::newBoolean(player->isInWall());
}
CATCH("Fail in getInWall!")
}
Local<Value> PlayerClass::getInWaterOrRain() {
try {
Player* player = get();
if (!player)
return Local<Value>();
return Boolean::newBoolean(player->isInWaterOrRain());
}
CATCH("Fail in getInWaterOrRain!")
}
//TODO 有函数没有
Local<Value> PlayerClass::getInWorld() {
try {
Player* player = get();
if (!player)
return Local<Value>();
// return Boolean::newBoolean(player->isInWorld());
return Boolean::newBoolean(-1);
}
CATCH("Fail in getInWorld!")
}
//TODO 有函数没有
Local<Value> PlayerClass::getInClouds() {
try {
Player* player = get();
if (!player) {
return Local<Value>();
}
// return Boolean::newBoolean(player->isInClouds());
return Boolean::newBoolean(-1);
}
CATCH("Fail in getInClouds!")
}
Local<Value> PlayerClass::asPointer(const Arguments& args) {
try {
Player* player = get();
if (!player)
return Local<Value>();
else
return NativePointer::newNativePointer(player);
}
CATCH("Fail in asPointer!")
}
Local<Value> PlayerClass::getUniqueID() {
try {
Player* player = get();
if (!player)
return Local<Value>();
else
return String::newString(std::to_string(player->getUniqueID().id));
}
CATCH("Fail in getUniqueID!")
}
Local<Value> PlayerClass::getLangCode() {
try {
auto result = get()->getLanguageCode();
return String::newString(result);
}
CATCH("Fail in getLangCode!");
}
Local<Value> PlayerClass::isLoading() {
try {
Player* player = get();
if (!player) {
return Local<Value>();
}
return Boolean::newBoolean(player->isLoading());
}
CATCH("Fail in isLoading!")
}
Local<Value> PlayerClass::isInvisible() {
try {
Player* player = get();
if (!player) {
return Local<Value>();
}
return Boolean::newBoolean(player->isInvisible());
}
CATCH("Fail in isInvisible!")
}
//TODO 有函数没有
Local<Value> PlayerClass::isInsidePortal() {
try {
Player* player = get();
if (!player) {
return Local<Value>();
}
// return Boolean::newBoolean(player->isInsidePortal());
return Boolean::newBoolean(-1);
}
CATCH("Fail in isInsidePortal!")
}
//TODO 有函数没有
Local<Value> PlayerClass::isHurt() {
try {
Player* player = get();
if (!player) {
return Local<Value>();
}
// return Boolean::newBoolean(player->isHurt());
return Boolean::newBoolean(-1);
}
CATCH("Fail in isHurt!")
}
//TODO 有函数没有
Local<Value> PlayerClass::isTrusting() {
try {
Player* player = get();
if (!player) {
return Local<Value>();
}
// return Boolean::newBoolean(player->isTrusting());
return Boolean::newBoolean(-1);
}
CATCH("Fail in isTrusting!")
}
//TODO 有函数没有
Local<Value> PlayerClass::isTouchingDamageBlock() {
try {
Player* player = get();
if (!player) {
return Local<Value>();
}
// return Boolean::newBoolean(player->isTouchingDamageBlock());
return Boolean::newBoolean(-1);
}
CATCH("Fail in isTouchingDamageBlock!")
}
Local<Value> PlayerClass::isHungry() {
try {
Player* player = get();
if (!player) {
return Local<Value>();
}
return Boolean::newBoolean(player->isHungry());
}
CATCH("Fail in isHungry!")
}
Local<Value> PlayerClass::isOnFire() {
try {
Player* player = get();
if (!player) {
return Local<Value>();
}
return Boolean::newBoolean(player->isOnFire());
}
CATCH("Fail in isOnFire!")
}
Local<Value> PlayerClass::isOnGround() {
try {
Player* player = get();
if (!player) {
return Local<Value>();
}
return Boolean::newBoolean(player->isOnGround());
}
CATCH("Fail in isOnGround!")
}
Local<Value> PlayerClass::isOnHotBlock() {
try {
Player* player = get();
if (!player) {
return Local<Value>();
}
return Boolean::newBoolean(player->isOnHotBlock());
}
CATCH("Fail in isOnHotBlock!")
}
Local<Value> PlayerClass::isTrading() {
try {
Player* player = get();
if (!player) {
return Local<Value>();
}
return Boolean::newBoolean(player->isTrading());
}
CATCH("Fail in isTrading!")
}
Local<Value> PlayerClass::isAdventure() {
try {
Player* player = get();
if (!player) {
return Local<Value>();
}
return Boolean::newBoolean(player->isAdventure());
}
CATCH("Fail in isAdventure!")
}
Local<Value> PlayerClass::isGliding() {
try {
Player* player = get();
if (!player) {
return Local<Value>();
}
return Boolean::newBoolean(player->isGliding());
}
CATCH("Fail in isGliding!")
}
Local<Value> PlayerClass::isSurvival() {
try {
Player* player = get();
if (!player) {
return Local<Value>();
}
return Boolean::newBoolean(player->isSurvival());
}
CATCH("Fail in isSurvival!")
}
//1.16.40还没有完整的旁观模式
//Local<Value> PlayerClass::isSpectator() {
// try {
// Player* player = get();
// if (!player) {
// return Local<Value>();
// }
//
// return Boolean::newBoolean(player->isSpectator());
// }
// CATCH("Fail in isSpectator!")
//}
Local<Value> PlayerClass::isRiding() {
try {
Player* player = get();
if (!player) {
return Local<Value>();
}
return Boolean::newBoolean(player->isRiding());
}
CATCH("Fail in isRiding!")
}
Local<Value> PlayerClass::isDancing() {
try {
Player* player = get();
if (!player) {
return Local<Value>();
}
return Boolean::newBoolean(player->isDancing());
}
CATCH("Fail in isDancing!")
}
Local<Value> PlayerClass::isCreative() {
try {
Player* player = get();
if (!player) {
return Local<Value>();
}
return Boolean::newBoolean(player->isCreative());
}
CATCH("Fail in isCreative!")
}
Local<Value> PlayerClass::isFlying() {
try {
Player* player = get();
if (!player) {
return Local<Value>();
}
return Boolean::newBoolean(player->isFlying());
}
CATCH("Fail in isFlying!")
}
Local<Value> PlayerClass::isSleeping() {
try {
Player* player = get();
if (!player) {
return Local<Value>();
}
return Boolean::newBoolean(player->isSleeping());
}
CATCH("Fail in isSleeping!")
}
Local<Value> PlayerClass::teleport(const Arguments& args) {
CHECK_ARGS_COUNT(args, 1)
try {
FloatVec4 pos;
if (args.size() == 1) {
if (IsInstanceOf<IntPos>(args[0])) {
// IntPos
IntPos* posObj = IntPos::extractPos(args[0]);
if (posObj->dim < 0)
return Boolean::newBoolean(false);
else {
pos.x = posObj->x;
pos.y = posObj->y;
pos.z = posObj->z;
pos.dim = posObj->dim;
}
} else if (IsInstanceOf<FloatPos>(args[0])) {
// FloatPos
FloatPos* posObj = FloatPos::extractPos(args[0]);
if (posObj->dim < 0)
return Boolean::newBoolean(false);
else {
pos = *posObj;
}
} else {
LOG_WRONG_ARG_TYPE();
return Local<Value>();
}
} else if (args.size() == 4) {
// number pos
CHECK_ARG_TYPE(args[0], ValueKind::kNumber);
CHECK_ARG_TYPE(args[1], ValueKind::kNumber);
CHECK_ARG_TYPE(args[2], ValueKind::kNumber);
CHECK_ARG_TYPE(args[3], ValueKind::kNumber);
pos.x = args[0].asNumber().toFloat();
pos.y = args[1].asNumber().toFloat();
pos.z = args[2].asNumber().toFloat();
pos.dim = args[3].toInt();
} else {
LOG_WRONG_ARG_TYPE();
return Local<Value>();
}
Player* player = get();
if (!player)
return Local<Value>();
player->teleport(pos.getVec3(), pos.dim);
return Boolean::newBoolean(true); //=========???
}
CATCH("Fail in TeleportPlayer!")
}
Local<Value> PlayerClass::kill(const Arguments& args) {
try {
Player* player = get();
if (!player)
return Local<Value>();
player->kill();
return Boolean::newBoolean(true); //=======???
}
CATCH("Fail in KillPlayer!")
}
Local<Value> PlayerClass::isOP(const Arguments& args) {
try {
Player* player = get();
if (!player)
return Local<Value>();
return Boolean::newBoolean(player->isOperator());
}
CATCH("Fail in IsOP!")
}
Local<Value> PlayerClass::setPermLevel(const Arguments& args) {
CHECK_ARGS_COUNT(args, 1);
CHECK_ARG_TYPE(args[0], ValueKind::kNumber);
try {
Player* player = get();
if (!player)
return Local<Value>();
bool res = false;
int newPerm = args[0].asNumber().toInt32();
if (newPerm >= 0 || newPerm <= 4) {
RecordOperation(ENGINE_OWN_DATA()->pluginName, "Set Permission Level",
fmt::format("Set Player {} Permission Level as {}.", player->getRealName(), newPerm));
player->setPermissions((CommandPermissionLevel)newPerm);
res = true;
}
return Boolean::newBoolean(res);
}
CATCH("Fail in setPlayerPermLevel!");
}
Local<Value> PlayerClass::setGameMode(const Arguments& args) {
CHECK_ARGS_COUNT(args, 1);
CHECK_ARG_TYPE(args[0], ValueKind::kNumber);
try {
Player* player = get();
if (!player)
return Local<Value>();
bool res = false;
int newMode = args[0].asNumber().toInt32();
if (newMode >= 0 || newMode <= 3) {
player->setPlayerGameType((GameType)newMode);
res = true;
}
return Boolean::newBoolean(res);
}
CATCH("Fail in setGameMode!");
}
Local<Value> PlayerClass::runcmd(const Arguments& args) {
CHECK_ARGS_COUNT(args, 1);
CHECK_ARG_TYPE(args[0], ValueKind::kString);
try {
Player* player = get();
if (!player)
return Local<Value>();
return Boolean::newBoolean(player->runcmd(args[0].toStr()));
}
CATCH("Fail in runcmd!");
}
Local<Value> PlayerClass::kick(const Arguments& args) {
if (args.size() >= 1)
CHECK_ARG_TYPE(args[0], ValueKind::kString);
try {
Player* player = get();
if (!player)
return Local<Value>();
string msg = "disconnectionScreen.disconnected";
if (args.size() >= 1)
msg = args[0].toStr();
player->kick(msg);
return Boolean::newBoolean(true); //=======???
}
CATCH("Fail in kickPlayer!");
}
Local<Value> PlayerClass::tell(const Arguments& args) {
CHECK_ARGS_COUNT(args, 1);
CHECK_ARG_TYPE(args[0], ValueKind::kString);
try {
Player* player = get();
if (!player)
return Local<Value>();
TextType type = TextType::RAW;
if (args.size() >= 2 && args[1].isNumber()) {
int newType = args[1].asNumber().toInt32();
if (newType >= 0 && newType <= 9)
type = (TextType)newType;
}
player->sendTextPacket(args[0].toStr(), type);
return Boolean::newBoolean(true);
}
CATCH("Fail in tell!");
}
Local<Value> PlayerClass::talkAs(const Arguments& args) {
CHECK_ARGS_COUNT(args, 1);
CHECK_ARG_TYPE(args[0], ValueKind::kString);
try {
Player* player = get();
if (!player)
return Local<Value>();
player->sendTextTalkPacket(args[0].toStr(), nullptr);
return Boolean::newBoolean(true);
}
CATCH("Fail in talkAs!");
}
Local<Value> PlayerClass::talkTo(const Arguments& args) {
CHECK_ARGS_COUNT(args, 2);
CHECK_ARG_TYPE(args[0], ValueKind::kString);
try {
Player* target = PlayerClass::extract(args[1]);
if (!target)
return Local<Value>();
Player* player = get();
if (!player)
return Local<Value>();
player->sendTextTalkPacket(args[0].toStr(), target);
return Boolean::newBoolean(true);
}
CATCH("Fail in talkTo!");
}
Local<Value> PlayerClass::getHand(const Arguments& args) {
try {
Player* player = get();
if (!player)
return Local<Value>();
return ItemClass::newItem(player->getHandSlot());
}
CATCH("Fail in getHand!");
}
Local<Value> PlayerClass::getOffHand(const Arguments& args) {
try {
Player* player = get();
if (!player)
return Local<Value>();
return ItemClass::newItem((ItemStack*)&player->getOffhandSlot());
}
CATCH("Fail in getOffHand!");
}
Local<Value> PlayerClass::getInventory(const Arguments& args) {
try {
Player* player = get();
if (!player)
return Local<Value>();
return ContainerClass::newContainer(&player->getInventory());
}
CATCH("Fail in getInventory!");
}
Local<Value> PlayerClass::getArmor(const Arguments& args) {
try {
Player* player = get();
if (!player)
return Local<Value>();
return ContainerClass::newContainer(&player->getArmorContainer());
}
CATCH("Fail in getArmor!");
}
Local<Value> PlayerClass::getEnderChest(const Arguments& args) {
try {
Player* player = get();
if (!player)
return Local<Value>();
return ContainerClass::newContainer((Container*)player->getEnderChestContainer());
}
CATCH("Fail in getEnderChest!");
}
Local<Value> PlayerClass::getRespawnPosition(const Arguments& args) {
try {
Player* player = get();
if (!player)
return Local<Value>();
auto position = player->getRespawnPosition();
if (position.first.y == 32767) {
auto region = Level::getBlockSource(position.second);
if (region)
position.first = region->getHeightmapPos(position.first);
}
return IntPos::newPos(position.first, position.second);
}
CATCH("Fail in getRespawnPosition!")
}
Local<Value> PlayerClass::setRespawnPosition(const Arguments& args) {
try {
Player* player = get();
if (!player)
return Local<Value>();
IntVec4 pos;
if (args.size() == 1) {
// IntPos
if (IsInstanceOf<IntPos>(args[0])) {
// IntPos
IntPos* posObj = IntPos::extractPos(args[0]);
if (posObj->dim < 0)
return Boolean::newBoolean(false);
else {
pos = *posObj;
}
} else if (IsInstanceOf<FloatPos>(args[0])) {
// FloatPos
FloatPos* posObj = FloatPos::extractPos(args[0]);
if (posObj->dim < 0)
return Boolean::newBoolean(false);
else {
pos = posObj->toIntVec4();
}
} else {
LOG_WRONG_ARG_TYPE();
return Local<Value>();
}
} else if (args.size() == 4) {
// Number Pos
CHECK_ARG_TYPE(args[0], ValueKind::kNumber);
CHECK_ARG_TYPE(args[1], ValueKind::kNumber);
CHECK_ARG_TYPE(args[2], ValueKind::kNumber);
CHECK_ARG_TYPE(args[3], ValueKind::kNumber);
pos = {args[0].toInt(), args[1].toInt(), args[2].toInt(), args[3].toInt()};
} else {
LOG_WRONG_ARGS_COUNT();
return Local<Value>();
}
player->setRespawnPosition(pos.getBlockPos(), pos.dim);
return Boolean::newBoolean(true);
}
CATCH("Fail in setRespawnPosition!")
}
Local<Value> PlayerClass::refreshItems(const Arguments& args) {
try {
Player* player = get();
if (!player)
return Local<Value>();
return Boolean::newBoolean(player->refreshInventory());
}
CATCH("Fail in refreshItems!");
}
Local<Value> PlayerClass::rename(const Arguments& args) {
CHECK_ARGS_COUNT(args, 1);
CHECK_ARG_TYPE(args[0], ValueKind::kString);
try {
Player* player = get();
if (!player)
return Local<Value>();
return Boolean::newBoolean(player->rename(args[0].toStr()));
}
CATCH("Fail in RenamePlayer!");
}
Local<Value> PlayerClass::addLevel(const Arguments& args) {
CHECK_ARGS_COUNT(args, 1);
CHECK_ARG_TYPE(args[0], ValueKind::kNumber);
try {
Player* player = get();
if (!player)
return Local<Value>();
player->addLevels(args[0].toInt());
return Boolean::newBoolean(true);
}
CATCH("Fail in addLevel!");
}
Local<Value> PlayerClass::reduceLevel(const Arguments& args) {
CHECK_ARGS_COUNT(args, 1);
CHECK_ARG_TYPE(args[0], ValueKind::kNumber);
try {
Player* player = get();
if (!player) {
return Local<Value>();
}
player->addLevels(-args[0].toInt());
return Boolean::newBoolean(true);
}
CATCH("Fail in reduceLevel!");
}
Local<Value> PlayerClass::getLevel(const Arguments& args) {
try {
Player* player = get();
if (!player)
return Local<Value>();
return Number::newNumber(player->getPlayerLevel());
}
CATCH("Fail in getLevel!")
}
Local<Value> PlayerClass::setLevel(const Arguments& args) {
CHECK_ARGS_COUNT(args, 1);
CHECK_ARG_TYPE(args[0], ValueKind::kNumber);
try {
Player* player = get();
if (!player)
return Local<Value>();
player->addLevels(args[0].toInt() - player->getPlayerLevel());
return Boolean::newBoolean(true);
}
CATCH("Fail in setLevel!");
}
Local<Value> PlayerClass::resetLevel(const Arguments& args) {
try {
Player* player = get();
if (!player)
return Local<Value>();
player->resetPlayerLevel();
return Boolean::newBoolean(true);
}
CATCH("Fail in resetLevel!")
}
Local<Value> PlayerClass::addExperience(const Arguments& args) {
CHECK_ARGS_COUNT(args, 1);
CHECK_ARG_TYPE(args[0], ValueKind::kNumber);
try {
Player* player = get();
if (!player)
return Local<Value>();
player->addExperience(args[0].toInt());
return Boolean::newBoolean(true);
}
CATCH("Fail in addExperience!");
}
Local<Value> PlayerClass::reduceExperience(const Arguments& args) {
CHECK_ARGS_COUNT(args, 1);
CHECK_ARG_TYPE(args[0], ValueKind::kNumber);
try {
Player* player = get();
if (!player) {
return Local<Value>();
}
player->reduceExperience(args[0].toInt());
return Boolean::newBoolean(true);
}
CATCH("Fail in reduceExperience!");
}
Local<Value> PlayerClass::getCurrentExperience(const Arguments& arg) {
try {
Player* player = get();
if (!player) {
return Local<Value>();
}
return Number::newNumber(player->getCurrentExperience());
}
CATCH("Fail in getCurrentExperience!")
}
Local<Value> PlayerClass::setCurrentExperience(const Arguments& args) {
CHECK_ARGS_COUNT(args, 1);
CHECK_ARG_TYPE(args[0], ValueKind::kNumber);
try {
Player* player = get();
if (!player) {
return Local<Value>();
}
player->setCurrentExperience(args[0].toInt());
return Boolean::newBoolean(true);
}
CATCH("Fail in setCurrentExperience!");
}
Local<Value> PlayerClass::getTotalExperience(const Arguments& arg) {
try {
Player* player = get();
if (!player) {
return Local<Value>();
}
return Number::newNumber((int64_t)player->getTotalExperience());
}
CATCH("Fail in getTotalExperience!")
}
Local<Value> PlayerClass::setTotalExperience(const Arguments& args) {
CHECK_ARGS_COUNT(args, 1);
CHECK_ARG_TYPE(args[0], ValueKind::kNumber);
try {
Player* player = get();
if (!player) {
return Local<Value>();
}
player->setTotalExperience(args[0].asNumber().toInt64());
return Boolean::newBoolean(true);
}
CATCH("Fail in setTotalExperience!");
}
Local<Value> PlayerClass::getXpNeededForNextLevel(const Arguments& args) {
try {
Player* player = get();
if (!player) {
return Local<Value>();
}
return Number::newNumber(player->getXpNeededForNextLevel());
}
CATCH("Fail in getXpNeededForNextLevel!")
}
Local<Value> PlayerClass::transServer(const Arguments& args) {
CHECK_ARGS_COUNT(args, 2)
CHECK_ARG_TYPE(args[0], ValueKind::kString)
CHECK_ARG_TYPE(args[1], ValueKind::kNumber)
try {
Player* player = get();
if (!player)
return Local<Value>();
return Boolean::newBoolean(player->transferServer(args[0].toStr(), (short)args[1].toInt()));
}
CATCH("Fail in transServer!");
}
Local<Value> PlayerClass::crash(const Arguments& args) {
try {
Player* player = get();
if (!player)
return Local<Value>();
RecordOperation(ENGINE_OWN_DATA()->pluginName, "Crash Player",
"Execute player.crash() to crash player <" + player->getRealName() + ">");
return Boolean::newBoolean(player->crashClient());
}
CATCH("Fail in crashPlayer!");
}
Local<Value> PlayerClass::getBlockStandingOn(const Arguments& args) {
try {
Player* player = get();
if (!player)
return Local<Value>();
return BlockClass::newBlock(player->getBlockPosCurrentlyStandingOn(nullptr), player->getDimensionId());
}
CATCH("Fail in getBlockStandingOn!");
}
Local<Value> PlayerClass::getDevice(const Arguments& args) {
try {
Player* player = get();
if (!player)
return Local<Value>();
return DeviceClass::newDevice(player);
}
CATCH("Fail in getDevice!");
}
Local<Value> PlayerClass::getScore(const Arguments& args) {
CHECK_ARGS_COUNT(args, 1);
CHECK_ARG_TYPE(args[0], ValueKind::kString);
try {
Player* player = get();
if (!player)
return Local<Value>();
return Number::newNumber(::Global<Scoreboard>->getScore(player, args[0].toStr()));
}
CATCH("Fail in getScore!");
}
Local<Value> PlayerClass::setScore(const Arguments& args) {
CHECK_ARGS_COUNT(args, 2);
CHECK_ARG_TYPE(args[0], ValueKind::kString);
CHECK_ARG_TYPE(args[1], ValueKind::kNumber);
try {
Player* player = get();
if (!player)
return Local<Value>();
return Boolean::newBoolean(::Global<Scoreboard>->setScore(player, args[0].toStr(), args[1].toInt()));
}
CATCH("Fail in setScore!");
}
Local<Value> PlayerClass::addScore(const Arguments& args) {
CHECK_ARGS_COUNT(args, 2);
CHECK_ARG_TYPE(args[0], ValueKind::kString);
CHECK_ARG_TYPE(args[1], ValueKind::kNumber);
try {
Player* player = get();
if (!player)
return Local<Value>();
return Boolean::newBoolean(::Global<Scoreboard>->addScore(player, args[0].toStr(), args[1].toInt()));
}
CATCH("Fail in addScore!");
}
Local<Value> PlayerClass::reduceScore(const Arguments& args) {
CHECK_ARGS_COUNT(args, 1);
CHECK_ARG_TYPE(args[0], ValueKind::kString);
CHECK_ARG_TYPE(args[1], ValueKind::kNumber);
try {
Player* player = get();
if (!player)
return Local<Value>();
return Boolean::newBoolean(::Global<Scoreboard>->reduceScore(player, args[0].toStr(), args[1].toInt()));
}
CATCH("Fail in reduceScore!");
}
Local<Value> PlayerClass::deleteScore(const Arguments& args) {
CHECK_ARGS_COUNT(args, 1);
CHECK_ARG_TYPE(args[0], ValueKind::kString);
try {
Player* player = get();
if (!player)
return Local<Value>();
return Boolean::newBoolean(::Global<Scoreboard>->deleteScore(player, args[0].toStr()));
}
CATCH("Fail in deleteScore!");
}
Local<Value> PlayerClass::setSidebar(const Arguments& args) {
CHECK_ARGS_COUNT(args, 2);
CHECK_ARG_TYPE(args[0], ValueKind::kString);
CHECK_ARG_TYPE(args[1], ValueKind::kObject);
if (args.size() >= 3)
CHECK_ARG_TYPE(args[2], ValueKind::kNumber);
try {
Player* player = get();
if (!player)
return Local<Value>();
std::vector<std::pair<std::string, int>> data;
auto source = args[1].asObject();
auto keys = source.getKeyNames();
for (auto& key : keys) {
data.push_back(make_pair(key, source.get(key).toInt()));
}
int sortOrder = 1;
if (args.size() >= 3)
sortOrder = args[2].toInt();
return Boolean::newBoolean(player->setSidebar(args[0].toStr(), data, (ObjectiveSortOrder)sortOrder));
}
CATCH("Fail in setSidebar!")
}
Local<Value> PlayerClass::removeSidebar(const Arguments& args) {
try {
Player* player = get();
if (!player)
return Local<Value>();
return Boolean::newBoolean(player->removeSidebar());
}
CATCH("Fail in removeSidebar!")
}
Local<Value> PlayerClass::setBossBar(const Arguments& args) {
CHECK_ARGS_COUNT(args, 2);
if (args[0].getKind() == ValueKind::kNumber) {
CHECK_ARGS_COUNT(args, 4);
CHECK_ARG_TYPE(args[0], ValueKind::kNumber);
CHECK_ARG_TYPE(args[1], ValueKind::kString);
CHECK_ARG_TYPE(args[2], ValueKind::kNumber);
CHECK_ARG_TYPE(args[3], ValueKind::kNumber);
try {
Player* player = get();
if (!player)
return Local<Value>();
int64_t uid = args[0].asNumber().toInt64();
int percent = args[2].toInt();
if (percent < 0)
percent = 0;
else if (percent > 100)
percent = 100;
float value = (float)percent / 100;
BossEventColour colour = (BossEventColour)args[3].toInt();
player->updateBossEvent(uid, args[1].toStr(), value, colour);
return Boolean::newBoolean(true);
}
CATCH("Fail in addBossBar!")
}
CHECK_ARG_TYPE(args[0], ValueKind::kString);
CHECK_ARG_TYPE(args[1], ValueKind::kNumber);
if (args.size() >= 3)
CHECK_ARG_TYPE(args[2], ValueKind::kNumber);
try {
Player* player = get();
if (!player)
return Local<Value>();
int percent = args[1].toInt();
if (percent < 0)
percent = 0;
else if (percent > 100)
percent = 100;
float value = (float)percent / 100;
BossEventColour colour = BossEventColour::Red;
if (args.size() >= 3)
colour = (BossEventColour)args[2].toInt();
player->sendBossEventPacket(BossEvent::Show, args[0].toStr(), value, colour);
return Boolean::newBoolean(true);
}
CATCH("Fail in setBossBar!")
}
Local<Value> PlayerClass::removeBossBar(const Arguments& args) {
if (args.size() == 0) {
try {
Player* player = get();
if (!player)
return Local<Value>();
player->sendBossEventPacket(BossEvent::Hide, "", 0, BossEventColour::Red); // Remove
return Boolean::newBoolean(true);
}
CATCH("Fail in removeBossBar!")
} else {
CHECK_ARGS_COUNT(args, 1);
CHECK_ARG_TYPE(args[0], ValueKind::kNumber);
try {
Player* player = get();
if (!player)
return Local<Value>();
int64_t uid = args[0].asNumber().toInt64();
player->removeBossEvent(uid); // Remove
return Boolean::newBoolean(true);
}
CATCH("Fail in removeBossBar!")
}
}
Local<Value> PlayerClass::sendSimpleForm(const Arguments& args) {
CHECK_ARGS_COUNT(args, 4);
CHECK_ARG_TYPE(args[0], ValueKind::kString);
CHECK_ARG_TYPE(args[1], ValueKind::kString);
CHECK_ARG_TYPE(args[2], ValueKind::kArray);
CHECK_ARG_TYPE(args[3], ValueKind::kArray);
CHECK_ARG_TYPE(args[4], ValueKind::kFunction);
try {
Player* player = get();
if (!player)
return Local<Value>();
// 普通格式
auto textsArr = args[2].asArray();
if (textsArr.size() == 0 || !textsArr.get(0).isString())
return Local<Value>();
auto imagesArr = args[3].asArray();
if (imagesArr.size() != textsArr.size() || !imagesArr.get(0).isString())
return Local<Value>();
vector<string> texts, images;
for (int i = 0; i < textsArr.size(); ++i) {
texts.push_back(textsArr.get(i).toStr());
}
for (int i = 0; i < imagesArr.size(); ++i) {
images.push_back(imagesArr.get(i).toStr());
}
player->sendSimpleFormPacket(args[0].toStr(), args[1].toStr(), texts, images,
[id{player->getUniqueID()}, engine{EngineScope::currentEngine()},
callback{script::Global(args[4].asFunction())}](int chosen) {
if (LL::isServerStopping())
return;
if (!EngineManager::isValid(engine))
return;
Player* pl = Global<Level>->getPlayer(id);
if (!pl)
return;
EngineScope scope(engine);
try {
callback.get().call({}, PlayerClass::newPlayer(pl),
chosen >= 0 ? Number::newNumber(chosen) : Local<Value>());
}
CATCH_IN_CALLBACK("sendSimpleForm")
});
return Number::newNumber(1);
}
CATCH("Fail in sendSimpleForm!");
}
Local<Value> PlayerClass::sendModalForm(const Arguments& args) {
CHECK_ARGS_COUNT(args, 5);
CHECK_ARG_TYPE(args[0], ValueKind::kString);
CHECK_ARG_TYPE(args[1], ValueKind::kString);
CHECK_ARG_TYPE(args[2], ValueKind::kString);
CHECK_ARG_TYPE(args[3], ValueKind::kString);
CHECK_ARG_TYPE(args[4], ValueKind::kFunction);
try {
Player* player = get();
if (!player)
return Local<Value>();
player->sendModalFormPacket(args[0].toStr(), args[1].toStr(), args[2].toStr(), args[3].toStr(),
[id{player->getUniqueID()}, engine{EngineScope::currentEngine()},
callback{script::Global(args[4].asFunction())}](bool chosen) {
if (LL::isServerStopping())
return;
if (!EngineManager::isValid(engine))
return;
Player* pl = Global<Level>->getPlayer(id);
if (!pl)
return;
EngineScope scope(engine);
try {
callback.get().call({}, PlayerClass::newPlayer(pl),
chosen >= 0 ? Boolean::newBoolean(chosen) : Local<Value>());
}
CATCH_IN_CALLBACK("sendModalForm")
});
return Number::newNumber(2);
}
CATCH("Fail in sendModalForm!");
}
Local<Value> PlayerClass::sendCustomForm(const Arguments& args) {
CHECK_ARGS_COUNT(args, 2);
CHECK_ARG_TYPE(args[0], ValueKind::kString);
CHECK_ARG_TYPE(args[1], ValueKind::kFunction);
try {
Player* player = get();
if (!player)
return Local<Value>();
string data = fifo_json::parse(args[0].toStr()).dump();
player->sendCustomFormPacket(data,
[id{player->getUniqueID()}, engine{EngineScope::currentEngine()},
callback{script::Global(args[1].asFunction())}](string result) {
if (LL::isServerStopping())
return;
if (!EngineManager::isValid(engine))
return;
Player* pl = Global<Level>->getPlayer(id);
if (!pl)
return;
EngineScope scope(engine);
try {
callback.get().call({}, PlayerClass::newPlayer(pl),
result != "null" ? JsonToValue(result) : Local<Value>());
}
CATCH_IN_CALLBACK("sendCustomForm")
});
return Number::newNumber(3);
} catch (const fifo_json::exception& e) {
logger.error("Fail to parse Json string in sendCustomForm!");
logger.error(TextEncoding::toUTF8(e.what()));
PrintScriptStackTrace();
return Local<Value>();
}
CATCH("Fail in sendCustomForm!");
}
Local<Value> PlayerClass::sendForm(const Arguments& args) {
CHECK_ARGS_COUNT(args, 2);
CHECK_ARG_TYPE(args[1], ValueKind::kFunction);
try {
Player* player = get();
if (!player)
return Local<Value>();
bool res = false;
Form::SimpleForm* form = SimpleFormClass::extract(args[0]);
if (IsInstanceOf<SimpleFormClass>(args[0])) {
Local<Function> callback = args[1].asFunction();
res = SimpleFormClass::sendForm(SimpleFormClass::extract(args[0]), player, callback);
} else if (IsInstanceOf<CustomFormClass>(args[0])) {
Local<Function> callback = args[1].asFunction();
res = CustomFormClass::sendForm(CustomFormClass::extract(args[0]), player, callback);
} else {
LOG_WRONG_ARG_TYPE();
return Local<Value>();
}
return Boolean::newBoolean(res);
}
CATCH("Fail in sendForm!");
}
Local<Value> PlayerClass::sendPacket(const Arguments& args)
{
CHECK_ARGS_COUNT(args, 1);
CHECK_ARG_TYPE(args[0], ValueKind::kObject);
try
{
Player* player = get();
if (!player)
return Local<Value>();
auto pkt = PacketClass::extract(args[0]);
if (!pkt)
return Boolean::newBoolean(false);
player->sendNetworkPacket(*pkt);
return Boolean::newBoolean(true);
}
CATCH("Fail in sendPacket");
return Local<Value>();
}
Local<Value> PlayerClass::setExtraData(const Arguments& args) {
CHECK_ARGS_COUNT(args, 2);
CHECK_ARG_TYPE(args[0], ValueKind::kString);
try {
Player* player = get();
if (!player)
return Local<Value>();
string key = args[0].toStr();
if (key.empty())
return Boolean::newBoolean(false);
ENGINE_OWN_DATA()->playerDataDB[player->getRealName() + "-" + key] = args[1];
return Boolean::newBoolean(true);
}
CATCH("Fail in setExtraData!");
}
Local<Value> PlayerClass::getExtraData(const Arguments& args) {
CHECK_ARGS_COUNT(args, 1);
CHECK_ARG_TYPE(args[0], ValueKind::kString);
try {
Player* player = get();
if (!player)
return Local<Value>();
string key = args[0].toStr();
if (key.empty())
return Local<Value>();
auto& db = ENGINE_OWN_DATA()->playerDataDB;
auto res = db.find(player->getRealName() + "-" + key);
if (res == db.end() || res->second.isEmpty())
return Local<Value>();
else
return res->second.get();
}
CATCH("Fail in getExtraData!");
}
Local<Value> PlayerClass::delExtraData(const Arguments& args) {
CHECK_ARGS_COUNT(args, 1)
CHECK_ARG_TYPE(args[0], ValueKind::kString)
try {
Player* player = get();
if (!player)
return Local<Value>();
string key = args[0].toStr();
if (key.empty())
return Boolean::newBoolean(false);
ENGINE_OWN_DATA()->playerDataDB.erase(player->getRealName() + "-" + key);
return Boolean::newBoolean(true);
}
CATCH("Fail in delExtraData!")
}
Local<Value> PlayerClass::hurt(const Arguments& args) {
CHECK_ARGS_COUNT(args, 1);
CHECK_ARG_TYPE(args[0], ValueKind::kNumber);
try {
Player* player = get();
if (!player)
return Local<Value>();
int damage = args[0].toInt();
return Boolean::newBoolean(player->hurtEntity(damage));
}
CATCH("Fail in hurt!");
}
Local<Value> PlayerClass::setFire(const Arguments& args) {
CHECK_ARGS_COUNT(args, 2);
CHECK_ARG_TYPE(args[0], ValueKind::kNumber);
CHECK_ARG_TYPE(args[1], ValueKind::kBoolean);
try {
Player* player = get();
if (!player)
return Local<Value>();
int time = args[0].toInt();
bool isEffectValue = args[1].asBoolean().value();
player->setOnFire(time);
return Boolean::newBoolean(1);
}
CATCH("Fail in setOnFire!");
}
// For Compatibility
Local<Value> PlayerClass::setOnFire(const Arguments& args) {
CHECK_ARGS_COUNT(args, 1);
CHECK_ARG_TYPE(args[0], ValueKind::kNumber);
try {
Player* player = get();
if (!player)
return Local<Value>();
int time = args[0].toInt();
player->setOnFire(time);
return Boolean::newBoolean(1);
}
CATCH("Fail in setOnFire!");
}
//Local<Value> PlayerClass::refreshChunks(const Arguments& args) {
// try {
// Player* player = get();
// if (!player)
// return Local<Value>();
//
// player->resendAllChunks();
// return Boolean::newBoolean(true);
// }
// CATCH("Fail in refreshChunks!");
//}
Local<Value> PlayerClass::giveItem(const Arguments& args) {
CHECK_ARGS_COUNT(args, 1);
try {
Player* player = get();
if (!player)
return Local<Value>();
auto item = ItemClass::extract(args[0]);
if (!item)
return Local<Value>(); // Null
return Boolean::newBoolean(player->giveItem(item));
}
CATCH("Fail in giveItem!");
}
Local<Value> PlayerClass::clearItem(const Arguments& args) {
CHECK_ARGS_COUNT(args, 1);
CHECK_ARG_TYPE(args[0], ValueKind::kString);
try {
Player* player = get();
if (!player)
return Local<Value>();
return Number::newNumber(player->clearItem(args[0].toStr()));
}
CATCH("Fail in clearItem!");
}
Local<Value> PlayerClass::isSprinting(const Arguments& args) {
CHECK_ARGS_COUNT(args, 0);
try {
Player* player = get();
if (!player)
return Local<Value>();
return Boolean::newBoolean(player->isSprinting());
}
CATCH("Fail in isSprinting!");
}
Local<Value> PlayerClass::setSprinting(const Arguments& args) {
CHECK_ARGS_COUNT(args, 1);
CHECK_ARG_TYPE(args[0], ValueKind::kBoolean);
try {
Player* player = get();
if (!player)
return Local<Value>();
player->setSprinting(args[0].asBoolean().value());
return Boolean::newBoolean(true);
}
CATCH("Fail in setSprinting!");
}
Local<Value> PlayerClass::getNbt(const Arguments& args) {
try {
Player* player = get();
if (!player)
return Local<Value>();
return NbtCompoundClass::pack(player->getNbt());
}
CATCH("Fail in getNbt!")
}
Local<Value> PlayerClass::setNbt(const Arguments& args) {
CHECK_ARGS_COUNT(args, 1);
try {
Player* player = get();
if (!player)
return Local<Value>();
auto nbt = NbtCompoundClass::extract(args[0]);
if (!nbt)
return Local<Value>(); // Null
return Boolean::newBoolean(player->setNbt(nbt));
}
CATCH("Fail in setNbt!")
}
Local<Value> PlayerClass::addTag(const Arguments& args) {
CHECK_ARGS_COUNT(args, 1);
CHECK_ARG_TYPE(args[0], ValueKind::kString);
try {
Player* player = get();
if (!player)
return Local<Value>();
return Boolean::newBoolean(player->addTag(args[0].toStr()));
}
CATCH("Fail in addTag!");
}
//Local<Value> PlayerClass::removeTag(const Arguments& args) {
// CHECK_ARGS_COUNT(args, 1);
// CHECK_ARG_TYPE(args[0], ValueKind::kString);
//
// try {
// Player* player = get();
// if (!player)
// return Local<Value>();
//
// return Boolean::newBoolean(player->removeTag(args[0].toStr()));
// }
// CATCH("Fail in removeTag!");
//}
Local<Value> PlayerClass::hasTag(const Arguments& args) {
CHECK_ARGS_COUNT(args, 1);
CHECK_ARG_TYPE(args[0], ValueKind::kString);
try {
Player* player = get();
if (!player)
return Local<Value>();
return Boolean::newBoolean(player->hasTag(args[0].toStr()));
}
CATCH("Fail in hasTag!");
}
Local<Value> PlayerClass::getAllTags(const Arguments& args) {
try {
Player* player = get();
if (!player)
return Local<Value>();
auto res = player->getAllTags();
Local<Array> arr = Array::newArray();
for (auto& tag : res)
arr.add(String::newString(tag));
return arr;
}
CATCH("Fail in getAllTags!");
}
Local<Value> PlayerClass::getAbilities(const Arguments& args) {
try {
Player* player = get();
if (!player)
return Local<Value>();
auto list = player->getNbt();
try {
return Tag2Value((Tag*)list->getCompoundTag("abilities"), true);
} catch (...) {
return Object::newObject();
}
}
CATCH("Fail in getAbilities!");
}
Local<Value> PlayerClass::getAttributes(const Arguments& args) {
try {
Player* player = get();
if (!player)
return Local<Value>();
Local<Array> res = Array::newArray();
auto list = player->getNbt();
try {
ListTag* attr = (ListTag*)list->getListTag("Attributes");
Local<Array> arr = Array::newArray();
for (auto& tag : attr->value()) {
arr.add(Tag2Value(tag, true));
}
return arr;
} catch (...) {
return Array::newArray();
}
}
CATCH("Fail in getAttributes!");
}
Local<Value> PlayerClass::getEntityFromViewVector(const Arguments& args) {
try {
Player* player = get();
if (!player)
return Local<Value>();
float maxDistance = 5.25f;
if (args.size() > 0) {
CHECK_ARG_TYPE(args[0], ValueKind::kNumber);
maxDistance = args[0].asNumber().toFloat();
}
auto entity = player->getActorFromViewVector(maxDistance);
if (entity)
return EntityClass::newEntity(entity);
return Local<Value>();
}
CATCH("Fail in getEntityFromViewVector!");
}
//Local<Value> PlayerClass::getBlockFromViewVector(const Arguments& args) {
// try {
// Player* player = get();
// if (!player)
// return Local<Value>();
// bool includeLiquid = false;
// bool solidOnly = false;
// float maxDistance = 5.25f;
// bool ignoreBorderBlocks = true;
// bool fullOnly = false;
// if (args.size() > 0) {
// CHECK_ARG_TYPE(args[0], ValueKind::kBoolean);
// includeLiquid = args[0].asBoolean().value();
// }
// if (args.size() > 1) {
// CHECK_ARG_TYPE(args[1], ValueKind::kBoolean);
// solidOnly = args[1].asBoolean().value();
// }
// if (args.size() > 2) {
// CHECK_ARG_TYPE(args[2], ValueKind::kNumber);
// maxDistance = args[2].asNumber().toFloat();
// }
// if (args.size() > 3) {
// CHECK_ARG_TYPE(args[3], ValueKind::kBoolean);
// fullOnly = args[3].asBoolean().value();
// }
// auto blockInstance = player->getBlockFromViewVector(includeLiquid, solidOnly, maxDistance, ignoreBorderBlocks, fullOnly);
// if (blockInstance.isNull())
// return Local<Value>();
// return BlockClass::newBlock(std::move(blockInstance));
// }
// CATCH("Fail in getBlockFromViewVector!");
//}
//Local<Value> PlayerClass::isSimulatedPlayer(const Arguments& args) {
// try {
// return Boolean::newBoolean(get()->isSimulatedPlayer());
// }
// CATCH("Fail in isSimulatedPlayer!");
//}
//Local<Value> PlayerClass::quickEvalMolangScript(const Arguments& args) {
// CHECK_ARGS_COUNT(args, 1);
// CHECK_ARG_TYPE(args[0], ValueKind::kString);
// try {
// Player* actor = get();
// if (!actor)
// return Local<Value>();
// return Number::newNumber(actor->quickEvalMolangScript(args[0].toStr()));
// }
// CATCH("Fail in quickEvalMolangScript!");
//}
//////////////////// For Compatibility ////////////////////
Local<Value> PlayerClass::getAllItems(const Arguments& args) {
try {
Player* player = get();
if (!player)
return Local<Value>();
ItemStack* hand = player->getHandSlot();
ItemStack* offHand = (ItemStack*)&player->getOffhandSlot();
vector<const ItemStack*> inventory = player->getInventory().getAllSlots();
vector<const ItemStack*> armor = player->getArmorContainer().getAllSlots();
auto temp = (Container*)player->getEnderChestContainer();
vector<const ItemStack*> endChest = temp->getAllSlots();
Local<Object> result = Object::newObject();
// hand
result.set("hand", ItemClass::newItem(hand));
// offHand
result.set("offHand", ItemClass::newItem(offHand));
// inventory
Local<Array> inventoryArr = Array::newArray();
for (const ItemStack* item : inventory) {
inventoryArr.add(ItemClass::newItem((ItemStack*)item));
}
result.set("inventory", inventoryArr);
// armor
Local<Array> armorArr = Array::newArray();
for (const ItemStack* item : armor) {
armorArr.add(ItemClass::newItem((ItemStack*)item));
}
result.set("armor", armorArr);
// endChest
Local<Array> endChestArr = Array::newArray();
for (const ItemStack* item : endChest) {
endChestArr.add(ItemClass::newItem((ItemStack*)item));
}
result.set("endChest", endChestArr);
return result;
}
CATCH("Fail in getAllItems!")
}
Local<Value> PlayerClass::removeItem(const Arguments& args) {
CHECK_ARGS_COUNT(args, 2);
try {
Player* player = get();
if (!player)
return Local<Value>();
int inventoryId = args[0].toInt();
int count = args[1].toInt();
Container& container = player->getInventory();
if (inventoryId > container.getSize())
return Boolean::newBoolean(false);
container.removeItem(inventoryId, count);
return Boolean::newBoolean(true);
}
CATCH("Fail in removeItem!")
}
//Local<Value> PlayerClass::sendToast(const Arguments& args) {
// CHECK_ARGS_COUNT(args, 2);
// CHECK_ARG_TYPE(args[0], ValueKind::kString);
// CHECK_ARG_TYPE(args[1], ValueKind::kString);
// try {
// Player* player = get();
//
// if (!player)
// return Local<Value>();
//
// player->sendToastPacket(args[0].toStr(), args[1].toStr());
// return Boolean::newBoolean(true);
// }
// CATCH("Fail in sendToast!");
//}