mirror of
https://github.com/quizhizhe/LiteLoaderBDS-1.16.40.git
synced 2025-06-03 04:23:39 +00:00
至少不报错了,因函数实现未找到无法编译
This commit is contained in:
parent
861cccdf7e
commit
7ee5dfd7b5
@ -32,7 +32,7 @@ public:
|
||||
|
||||
LIAPI std::string getTypeName() const;
|
||||
LIAPI Vec3 getFeetPosition() const;
|
||||
//LIAPI BlockSource* getBlockSource() const;
|
||||
LIAPI BlockSource* getBlockSource() const;
|
||||
LIAPI Vec2* getDirection() const;
|
||||
LIAPI ActorUniqueID getActorUniqueId() const;
|
||||
LIAPI Vec3 getCameraPos() const;
|
||||
@ -79,6 +79,10 @@ public:
|
||||
inline bool isMoving() const{
|
||||
return getStatusFlag(ActorFlags::MOVING);
|
||||
};
|
||||
inline bool hasCategory(enum ActorCategory actorCategory) const{
|
||||
// IDA Player::take Line123
|
||||
return (dAccess<ActorCategory>(this, 79) & actorCategory) !=0;
|
||||
};
|
||||
|
||||
#undef AFTER_EXTRA
|
||||
#ifndef DISABLE_CONSTRUCTOR_PREVENTION_ACTOR
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include "../Global.h"
|
||||
|
||||
#define BEFORE_EXTRA
|
||||
|
||||
#include "MC/HashedString.hpp"
|
||||
#undef BEFORE_EXTRA
|
||||
|
||||
struct ActorDefinitionIdentifier {
|
||||
|
@ -10,7 +10,23 @@
|
||||
namespace Bedrock {
|
||||
|
||||
#define AFTER_EXTRA
|
||||
|
||||
// Add Member There
|
||||
struct PlatformRuntimeInfo {
|
||||
PlatformRuntimeInfo() = delete;
|
||||
PlatformRuntimeInfo(PlatformRuntimeInfo const&) = delete;
|
||||
PlatformRuntimeInfo(PlatformRuntimeInfo const&&) = delete;
|
||||
};
|
||||
class CrashTelemetryProcessor {
|
||||
public:
|
||||
CrashTelemetryProcessor() = delete;
|
||||
CrashTelemetryProcessor(CrashTelemetryProcessor const&) = delete;
|
||||
CrashTelemetryProcessor(CrashTelemetryProcessor const&&) = delete;
|
||||
};
|
||||
struct CrashUploadStatus {
|
||||
CrashUploadStatus() = delete;
|
||||
CrashUploadStatus(CrashUploadStatus const&) = delete;
|
||||
CrashUploadStatus(CrashUploadStatus const&&) = delete;
|
||||
};
|
||||
template <typename T0>
|
||||
class NonOwnerPointer {
|
||||
public:
|
||||
@ -19,7 +35,71 @@ public:
|
||||
NonOwnerPointer(T0& a1) {
|
||||
mPtr = std::make_shared<T0>(a1);
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
struct StorageMigration {
|
||||
enum StorageMigrationType;
|
||||
StorageMigration() = delete;
|
||||
StorageMigration(StorageMigration const&) = delete;
|
||||
StorageMigration(StorageMigration const&&) = delete;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
namespace PubSub {
|
||||
class Subscription {
|
||||
public:
|
||||
Subscription() = delete;
|
||||
Subscription(Subscription const&) = delete;
|
||||
Subscription(Subscription const&&) = delete;
|
||||
};
|
||||
} // namespace PubSub
|
||||
namespace Threading {
|
||||
enum AsyncStatus;
|
||||
template <typename T0>
|
||||
class UniqueLock;
|
||||
|
||||
class CountReference
|
||||
{
|
||||
public:
|
||||
CountReference() = delete;
|
||||
CountReference(CountReference const&) = delete;
|
||||
CountReference(CountReference const&&) = delete;
|
||||
};
|
||||
template <typename T0>
|
||||
class IAsyncResult {
|
||||
public:
|
||||
IAsyncResult() = delete;
|
||||
IAsyncResult(IAsyncResult const&) = delete;
|
||||
IAsyncResult(IAsyncResult const&&) = delete;
|
||||
};
|
||||
template <typename T0, typename T1>
|
||||
class ThreadLocalObject {
|
||||
public:
|
||||
ThreadLocalObject() = delete;
|
||||
ThreadLocalObject(ThreadLocalObject const&) = delete;
|
||||
ThreadLocalObject(ThreadLocalObject const&&) = delete;
|
||||
};
|
||||
//template <typename T>
|
||||
//class LockGuard
|
||||
//{
|
||||
// MCAPI LockGuard(T);
|
||||
// MCAPI ~LockGuard();
|
||||
//};
|
||||
} // namespace Threading
|
||||
|
||||
class ScopeExit;
|
||||
class Http {
|
||||
public:
|
||||
enum Implementation;
|
||||
};
|
||||
class SessionInfo
|
||||
{
|
||||
public:
|
||||
SessionInfo() = delete;
|
||||
SessionInfo(SessionInfo const&) = delete;
|
||||
SessionInfo(SessionInfo const&&) = delete;
|
||||
};
|
||||
|
||||
#undef AFTER_EXTRA
|
||||
|
@ -5,13 +5,28 @@
|
||||
#include "Core.hpp"
|
||||
|
||||
#define BEFORE_EXTRA
|
||||
|
||||
// Include Headers or Declare Types Here
|
||||
enum LogAreaID;
|
||||
#undef BEFORE_EXTRA
|
||||
|
||||
namespace BedrockLog {
|
||||
|
||||
#define AFTER_EXTRA
|
||||
|
||||
// Add Member There
|
||||
class LogAreaFilter {
|
||||
public:
|
||||
LogAreaFilter() = delete;
|
||||
LogAreaFilter(LogAreaFilter const&) = delete;
|
||||
LogAreaFilter(LogAreaFilter const&&) = delete;
|
||||
};
|
||||
enum LogChannel;
|
||||
enum LogRule;
|
||||
enum LogCategory;
|
||||
struct LogDetails {
|
||||
LogDetails() = delete;
|
||||
LogDetails(LogDetails const&) = delete;
|
||||
LogDetails(LogDetails const&&) = delete;
|
||||
};
|
||||
#undef AFTER_EXTRA
|
||||
MCAPI enum LogAreaID _areaFilterFromString(std::string const &);
|
||||
MCAPI bool _constructAreaFilterFromString(std::string const &, class BedrockLog::LogAreaFilter &);
|
||||
|
@ -8,7 +8,8 @@
|
||||
#include "Dimension.hpp"
|
||||
|
||||
#undef BEFORE_EXTRA
|
||||
|
||||
#include "MC/LevelChunk.hpp"
|
||||
#include "MC/ChunkPos.hpp"
|
||||
class BlockSource {
|
||||
|
||||
#define AFTER_EXTRA
|
||||
@ -20,11 +21,15 @@ public:
|
||||
// MCAPI static const std::function<bool(class Block const&)> CHECK_ALL_BLOCKS;
|
||||
// };
|
||||
LIAPI BlockInstance getBlockInstance(BlockPos);
|
||||
inline AutomaticID<Dimension, int> getDimensionId(){
|
||||
AutomaticID<class Dimension, int> getDimensionId(){
|
||||
//Dimension::onBlockEvent Line24
|
||||
Dimension* mDimension = dAccess< Dimension*>(this, 4);
|
||||
return dAccess<AutomaticID<Dimension, int>>(mDimension, 192);
|
||||
return dAccess<AutomaticID<class Dimension, int>>(mDimension, 192);
|
||||
};
|
||||
LevelChunk * getChunkAt(BlockPos& pos) const{
|
||||
ChunkPos chunkPos = ChunkPos(pos.x>>4, pos.z>>4);
|
||||
return getChunk(chunkPos);
|
||||
}
|
||||
|
||||
#undef AFTER_EXTRA
|
||||
#ifndef DISABLE_CONSTRUCTOR_PREVENTION_BLOCKSOURCE
|
||||
|
@ -10,7 +10,15 @@
|
||||
class ChunkPos {
|
||||
|
||||
#define AFTER_EXTRA
|
||||
|
||||
// Add Member There
|
||||
public:
|
||||
int x, z;
|
||||
long long hash() {
|
||||
return *((long long*)this);
|
||||
}
|
||||
ChunkPos(int ix, int iz)
|
||||
: x(ix)
|
||||
, z(iz){};
|
||||
#undef AFTER_EXTRA
|
||||
#ifndef DISABLE_CONSTRUCTOR_PREVENTION_CHUNKPOS
|
||||
public:
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include "../Global.h"
|
||||
|
||||
#define BEFORE_EXTRA
|
||||
|
||||
using namespace mce;
|
||||
#undef BEFORE_EXTRA
|
||||
|
||||
namespace ColorFormat {
|
||||
@ -45,8 +45,8 @@ LIAPI std::string& transferColorCodeToConsole(std::string& str, bool keepColorCo
|
||||
MCAPI extern std::string const BLACK;
|
||||
MCAPI extern std::string const BLUE;
|
||||
MCAPI extern std::string const BOLD;
|
||||
MCAPI std::string ColorCodeFromColor(class mce::Color const &);
|
||||
MCAPI class mce::Color const * ColorFromColorCode(std::string const &);
|
||||
MCAPI std::string ColorCodeFromColor(class Color const &);
|
||||
MCAPI class Color const * ColorFromColorCode(std::string const &);
|
||||
MCAPI extern std::string const DARK_AQUA;
|
||||
MCAPI extern std::string const DARK_BLUE;
|
||||
MCAPI extern std::string const DARK_GRAY;
|
||||
|
@ -4,13 +4,41 @@
|
||||
#include "../Global.h"
|
||||
|
||||
#define BEFORE_EXTRA
|
||||
|
||||
template <typename T>
|
||||
class typeid_t {
|
||||
public:
|
||||
typeid_t& operator=(typeid_t const&) = delete;
|
||||
typeid_t(typeid_t const&) = delete;
|
||||
};
|
||||
#undef BEFORE_EXTRA
|
||||
|
||||
class CommandRegistry {
|
||||
|
||||
#define AFTER_EXTRA
|
||||
public:
|
||||
struct ParseTable;
|
||||
class Symbol {
|
||||
Symbol& operator=(Symbol const&) = delete;
|
||||
Symbol(Symbol const&) = delete;
|
||||
};
|
||||
|
||||
struct ParseToken {
|
||||
ParseToken() = delete;
|
||||
ParseToken(ParseToken const&) = delete;
|
||||
ParseToken(ParseToken const&&) = delete;
|
||||
};
|
||||
|
||||
struct Overload {
|
||||
Overload() = delete;
|
||||
Overload(Overload const&) = delete;
|
||||
Overload(Overload const&&) = delete;
|
||||
};
|
||||
|
||||
struct Signature {
|
||||
Signature() = delete;
|
||||
Signature(Signature const&) = delete;
|
||||
Signature(Signature const&&) = delete;
|
||||
};
|
||||
#undef AFTER_EXTRA
|
||||
#ifndef DISABLE_CONSTRUCTOR_PREVENTION_COMMANDREGISTRY
|
||||
public:
|
||||
|
@ -8,13 +8,20 @@
|
||||
#include "LevelStorage.hpp"
|
||||
|
||||
#define BEFORE_EXTRA
|
||||
|
||||
// Include Headers or Declare Types Here
|
||||
#include "third-party/leveldb/status.h"
|
||||
#undef BEFORE_EXTRA
|
||||
|
||||
class DBStorage : public LevelStorage {
|
||||
|
||||
#define AFTER_EXTRA
|
||||
|
||||
// Add Member There
|
||||
public:
|
||||
struct PendingWriteResult {
|
||||
PendingWriteResult() = delete;
|
||||
PendingWriteResult(PendingWriteResult const&) = delete;
|
||||
PendingWriteResult(PendingWriteResult const&&) = delete;
|
||||
};
|
||||
#undef AFTER_EXTRA
|
||||
#ifndef DISABLE_CONSTRUCTOR_PREVENTION_DBSTORAGE
|
||||
public:
|
||||
|
@ -4,15 +4,15 @@
|
||||
#include "../Global.h"
|
||||
|
||||
#define BEFORE_EXTRA
|
||||
|
||||
#include "MC/BlockSource.hpp"
|
||||
#undef BEFORE_EXTRA
|
||||
|
||||
class Dimension {
|
||||
|
||||
#define AFTER_EXTRA
|
||||
public:
|
||||
LIAPI BlockSource& getBlockSourceFromMainChunkSource(){
|
||||
return dAccess<BlockSource&>(this, 96);
|
||||
BlockSource& getBlockSourceFromMainChunkSource() const{
|
||||
return *dAccess<BlockSource*>(this, 96);
|
||||
};
|
||||
#undef AFTER_EXTRA
|
||||
#ifndef DISABLE_CONSTRUCTOR_PREVENTION_DIMENSION
|
||||
|
@ -120,25 +120,25 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
LIAPI static bool executeCommandAs(Player* player, const string& cmd);
|
||||
LIAPI static std::pair<bool, string> executeCommandEx(const string& cmd);
|
||||
LIAPI static bool executeCommand(const string& cmd);
|
||||
// LIAPI static bool executeCommandAs(Player* player, const string& cmd);
|
||||
// LIAPI static std::pair<bool, string> executeCommandEx(const string& cmd);
|
||||
// LIAPI static bool executeCommand(const string& cmd);
|
||||
|
||||
|
||||
|
||||
//For compatibility
|
||||
LIAPI static bool runcmdAs(Player* pl, const string& cmd)
|
||||
{
|
||||
return executeCommandAs(pl, cmd);
|
||||
}
|
||||
LIAPI static std::pair<bool, string> runcmdEx(const string& cmd)
|
||||
{
|
||||
return executeCommandEx(cmd);
|
||||
}
|
||||
LIAPI static bool runcmd(const string& cmd)
|
||||
{
|
||||
return executeCommand(cmd);
|
||||
}
|
||||
// LIAPI static bool runcmdAs(Player* pl, const string& cmd)
|
||||
// {
|
||||
// return executeCommandAs(pl, cmd);
|
||||
// }
|
||||
// LIAPI static std::pair<bool, string> runcmdEx(const string& cmd)
|
||||
// {
|
||||
// return executeCommandEx(cmd);
|
||||
// }
|
||||
// LIAPI static bool runcmd(const string& cmd)
|
||||
// {
|
||||
// return executeCommand(cmd);
|
||||
// }
|
||||
|
||||
#undef AFTER_EXTRA
|
||||
#ifndef DISABLE_CONSTRUCTOR_PREVENTION_LEVEL
|
||||
|
@ -39,6 +39,11 @@ struct HardcodedSpawningArea {
|
||||
class BoundingBox aabb;
|
||||
enum HardcodedSpawnAreaType type;
|
||||
};
|
||||
public:
|
||||
struct Tick const & getLastTick() const{
|
||||
//CommandAreaFactory::_getArea Line156
|
||||
return *dAccess<Tick*>(this, 144);
|
||||
};
|
||||
#undef AFTER_EXTRA
|
||||
#ifndef DISABLE_CONSTRUCTOR_PREVENTION_LEVELCHUNK
|
||||
public:
|
||||
|
@ -10,7 +10,13 @@
|
||||
class LevelStorageWriteBatch {
|
||||
|
||||
#define AFTER_EXTRA
|
||||
|
||||
// Add Member There
|
||||
public:
|
||||
struct BatchEntry {
|
||||
BatchEntry() = delete;
|
||||
BatchEntry(BatchEntry const&) = delete;
|
||||
BatchEntry(BatchEntry const&&) = delete;
|
||||
};
|
||||
#undef AFTER_EXTRA
|
||||
#ifndef DISABLE_CONSTRUCTOR_PREVENTION_LEVELSTORAGEWRITEBATCH
|
||||
public:
|
||||
|
@ -10,7 +10,13 @@
|
||||
class MapItemTrackedActor {
|
||||
|
||||
#define AFTER_EXTRA
|
||||
|
||||
// Add Member There
|
||||
public:
|
||||
struct UniqueId {
|
||||
UniqueId() = delete;
|
||||
UniqueId(UniqueId const&) = delete;
|
||||
UniqueId(UniqueId const&&) = delete;
|
||||
};
|
||||
#undef AFTER_EXTRA
|
||||
#ifndef DISABLE_CONSTRUCTOR_PREVENTION_MAPITEMTRACKEDACTOR
|
||||
public:
|
||||
|
@ -10,7 +10,41 @@
|
||||
class NetworkPeer {
|
||||
|
||||
#define AFTER_EXTRA
|
||||
// Add Member There
|
||||
public:
|
||||
enum Reliability : int {
|
||||
Reliable = 0x0,
|
||||
ReliableOrdered = 0x1,
|
||||
Unreliable = 0x2,
|
||||
UnreliableSequenced = 0x3,
|
||||
};
|
||||
|
||||
enum DataStatus : int {
|
||||
HasData = 0x0,
|
||||
NoData = 0x1,
|
||||
BrokenData = 0x2,
|
||||
};
|
||||
|
||||
enum NetworkLoad : __int32 {
|
||||
Unrestricted = 0x0,
|
||||
Low = 0x1,
|
||||
Medium = 0x2,
|
||||
High = 0x3,
|
||||
};
|
||||
|
||||
struct NetworkStatus {
|
||||
NetworkLoad mLoad;
|
||||
int mCurrentPing;
|
||||
int mAveragePing;
|
||||
int mApproximateMaxBps;
|
||||
float mCurrentPacketLoss;
|
||||
float mAveragePacketLoss;
|
||||
unsigned __int64 mTotalBytesReceived;
|
||||
unsigned __int64 mTotalBytesSent;
|
||||
unsigned __int64 unk40;
|
||||
int unk48;
|
||||
bool unk52;
|
||||
};
|
||||
#undef AFTER_EXTRA
|
||||
#ifndef DISABLE_CONSTRUCTOR_PREVENTION_NETWORKPEER
|
||||
public:
|
||||
|
@ -46,9 +46,9 @@ class PlayerActionPacket : public Packet {
|
||||
// Add Member There
|
||||
public:
|
||||
BlockPos position; // 48
|
||||
FaceID blockFace; // 72
|
||||
PlayerActionType actionType; // 76
|
||||
ActorRuntimeID runtimeID; // 80
|
||||
FaceID blockFace; // 60
|
||||
PlayerActionType actionType; // 64
|
||||
ActorRuntimeID runtimeID; // 72
|
||||
|
||||
inline std::string toDebugString() {
|
||||
return fmt::format("{}: position: ({}), blockFace: {}, actionType: {}, runtimeID: {}",
|
||||
|
@ -10,7 +10,11 @@
|
||||
class PropertiesSettings {
|
||||
|
||||
#define AFTER_EXTRA
|
||||
|
||||
public:
|
||||
inline bool useOnlineAuthentication(){
|
||||
//PropertiesSettings::PropertiesSettings Line550;
|
||||
return dAccess<bool>(this, 417);
|
||||
}
|
||||
#undef AFTER_EXTRA
|
||||
#ifndef DISABLE_CONSTRUCTOR_PREVENTION_PROPERTIESSETTINGS
|
||||
public:
|
||||
|
@ -25,7 +25,7 @@ namespace RakNet {
|
||||
|
||||
struct SystemAddress {
|
||||
char filler[17 * 8]; // uncertain?
|
||||
MCAPI const char* ToString(bool, char) const;
|
||||
MCAPI void ToString_New(bool, char, char*);
|
||||
};
|
||||
struct RakNetGUID {
|
||||
uint64_t unk;
|
||||
|
@ -11,6 +11,12 @@
|
||||
class RakPeerHelper {
|
||||
|
||||
#define AFTER_EXTRA
|
||||
public:
|
||||
struct IPSupportInterface{
|
||||
IPSupportInterface() = delete;
|
||||
IPSupportInterface(struct IPSupportInterface&) = delete;
|
||||
IPSupportInterface(struct IPSupportInterface&&) = delete;
|
||||
};
|
||||
|
||||
#undef AFTER_EXTRA
|
||||
#ifndef DISABLE_CONSTRUCTOR_PREVENTION_RAKPEERHELPER
|
||||
|
@ -10,7 +10,11 @@
|
||||
class VarIntDataOutput {
|
||||
|
||||
#define AFTER_EXTRA
|
||||
|
||||
BinaryStream *mStream;
|
||||
public:
|
||||
VarIntDataOutput(BinaryStream *stream){
|
||||
mStream = stream;
|
||||
};
|
||||
#undef AFTER_EXTRA
|
||||
#ifndef DISABLE_CONSTRUCTOR_PREVENTION_VARINTDATAOUTPUT
|
||||
public:
|
||||
|
@ -1,87 +1,87 @@
|
||||
#pragma once
|
||||
#include "Global.h"
|
||||
#include "MC/Actor.hpp"
|
||||
#include "MC/Player.hpp"
|
||||
#include "MC/Command.hpp"
|
||||
#include "MC/CommandMessage.hpp"
|
||||
#include "MC/CommandOutput.hpp"
|
||||
#include "MC/CommandParameterData.hpp"
|
||||
#include "MC/CommandPosition.hpp"
|
||||
#include "MC/CommandSelector.hpp"
|
||||
#include "MC/CommandRegistry.hpp"
|
||||
#include <tuple>
|
||||
|
||||
namespace RegisterCommandHelper {
|
||||
template <typename Command, typename Type>
|
||||
static int getOffset(Type Command::*src) {
|
||||
union {
|
||||
Type Command::*src;
|
||||
int value;
|
||||
} u;
|
||||
u.src = src;
|
||||
return u.value;
|
||||
}
|
||||
|
||||
using ParseFn = bool (CommandRegistry::*)(
|
||||
void*, CommandRegistry::ParseToken const&, CommandOrigin const&, int, std::string&,
|
||||
std::vector<std::string>&) const;
|
||||
|
||||
template <typename Command, typename Type>
|
||||
static CommandParameterData makeMandatory(Type Command::*field, std::string name, bool Command::*isSet = nullptr) {
|
||||
|
||||
return {
|
||||
type_id<CommandRegistry, Type>(),
|
||||
CommandRegistry::getParseFn<Type>(),
|
||||
name,
|
||||
CommandParameterDataType::NORMAL,
|
||||
nullptr,
|
||||
getOffset(field),
|
||||
false,
|
||||
isSet ? getOffset(isSet) : -1,
|
||||
};
|
||||
}
|
||||
template <CommandParameterDataType DataType, typename Command, typename Type>
|
||||
static CommandParameterData
|
||||
makeMandatory(Type Command::*field, std::string name, char const* desc = nullptr, bool Command::*isSet = nullptr) {
|
||||
return {
|
||||
type_id<CommandRegistry, Type>(),
|
||||
CommandRegistry::getParseFn<Type>(),
|
||||
name,
|
||||
DataType,
|
||||
desc,
|
||||
getOffset(field),
|
||||
false,
|
||||
isSet ? getOffset(isSet) : -1,
|
||||
};
|
||||
}
|
||||
template <typename Command, typename Type>
|
||||
static CommandParameterData makeOptional(Type Command::*field, std::string name, bool Command::*isSet = nullptr) {
|
||||
typeid_t<CommandRegistry> tpid{0};
|
||||
|
||||
return {
|
||||
type_id<CommandRegistry, Type>(),
|
||||
CommandRegistry::getParseFn<Type>(),
|
||||
name,
|
||||
CommandParameterDataType::NORMAL,
|
||||
nullptr,
|
||||
getOffset(field),
|
||||
true,
|
||||
isSet ? getOffset(isSet) : -1,
|
||||
};
|
||||
}
|
||||
template <CommandParameterDataType DataType, typename Command, typename Type>
|
||||
static CommandParameterData
|
||||
makeOptional(Type Command::*field, std::string name, char const* desc = nullptr, bool Command::*isSet = nullptr) {
|
||||
|
||||
return {
|
||||
type_id<CommandRegistry, Type>(),
|
||||
CommandRegistry::getParseFn<Type>(),
|
||||
name,
|
||||
DataType,
|
||||
desc,
|
||||
getOffset(field),
|
||||
true,
|
||||
isSet ? getOffset(isSet) : -1,
|
||||
};
|
||||
}
|
||||
} // namespace RegisterCommandHelper
|
||||
//#pragma once
|
||||
//#include "Global.h"
|
||||
//#include "MC/Actor.hpp"
|
||||
//#include "MC/Player.hpp"
|
||||
//#include "MC/Command.hpp"
|
||||
//#include "MC/CommandMessage.hpp"
|
||||
//#include "MC/CommandOutput.hpp"
|
||||
//#include "MC/CommandParameterData.hpp"
|
||||
//#include "MC/CommandPosition.hpp"
|
||||
//#include "MC/CommandSelector.hpp"
|
||||
//#include "MC/CommandRegistry.hpp"
|
||||
//#include <tuple>
|
||||
//
|
||||
//namespace RegisterCommandHelper {
|
||||
//template <typename Command, typename Type>
|
||||
//static int getOffset(Type Command::*src) {
|
||||
// union {
|
||||
// Type Command::*src;
|
||||
// int value;
|
||||
// } u;
|
||||
// u.src = src;
|
||||
// return u.value;
|
||||
//}
|
||||
//
|
||||
//using ParseFn = bool (CommandRegistry::*)(
|
||||
// void*, CommandRegistry::ParseToken const&, CommandOrigin const&, int, std::string&,
|
||||
// std::vector<std::string>&) const;
|
||||
//
|
||||
//template <typename Command, typename Type>
|
||||
//static CommandParameterData makeMandatory(Type Command::*field, std::string name, bool Command::*isSet = nullptr) {
|
||||
//
|
||||
// return {
|
||||
// type_id<CommandRegistry, Type>(),
|
||||
// CommandRegistry::getParseFn<Type>(),
|
||||
// name,
|
||||
// CommandParameterDataType::NORMAL,
|
||||
// nullptr,
|
||||
// getOffset(field),
|
||||
// false,
|
||||
// isSet ? getOffset(isSet) : -1,
|
||||
// };
|
||||
//}
|
||||
//template <CommandParameterDataType DataType, typename Command, typename Type>
|
||||
//static CommandParameterData
|
||||
// makeMandatory(Type Command::*field, std::string name, char const* desc = nullptr, bool Command::*isSet = nullptr) {
|
||||
// return {
|
||||
// type_id<CommandRegistry, Type>(),
|
||||
// CommandRegistry::getParseFn<Type>(),
|
||||
// name,
|
||||
// DataType,
|
||||
// desc,
|
||||
// getOffset(field),
|
||||
// false,
|
||||
// isSet ? getOffset(isSet) : -1,
|
||||
// };
|
||||
//}
|
||||
//template <typename Command, typename Type>
|
||||
//static CommandParameterData makeOptional(Type Command::*field, std::string name, bool Command::*isSet = nullptr) {
|
||||
// typeid_t<CommandRegistry> tpid{0};
|
||||
//
|
||||
// return {
|
||||
// type_id<CommandRegistry, Type>(),
|
||||
// CommandRegistry::getParseFn<Type>(),
|
||||
// name,
|
||||
// CommandParameterDataType::NORMAL,
|
||||
// nullptr,
|
||||
// getOffset(field),
|
||||
// true,
|
||||
// isSet ? getOffset(isSet) : -1,
|
||||
// };
|
||||
//}
|
||||
//template <CommandParameterDataType DataType, typename Command, typename Type>
|
||||
//static CommandParameterData
|
||||
// makeOptional(Type Command::*field, std::string name, char const* desc = nullptr, bool Command::*isSet = nullptr) {
|
||||
//
|
||||
// return {
|
||||
// type_id<CommandRegistry, Type>(),
|
||||
// CommandRegistry::getParseFn<Type>(),
|
||||
// name,
|
||||
// DataType,
|
||||
// desc,
|
||||
// getOffset(field),
|
||||
// true,
|
||||
// isSet ? getOffset(isSet) : -1,
|
||||
// };
|
||||
//}
|
||||
//} // namespace RegisterCommandHelper
|
||||
|
@ -37,9 +37,9 @@ MCINLINE Vec3 Actor::getFeetPosition() const {
|
||||
return CommandUtils::getFeetPos(this);
|
||||
}
|
||||
|
||||
// BlockSource* Actor::getBlockSource() const {
|
||||
// return Level::getBlockSource((Actor*)this);
|
||||
// }
|
||||
BlockSource* Actor::getBlockSource() const {
|
||||
return Level::getBlockSource((Actor*)this);
|
||||
}
|
||||
|
||||
bool Actor::isPlayer(bool allowSimulatedPlayer) const {
|
||||
if (!this)
|
||||
@ -51,9 +51,9 @@ bool Actor::isPlayer(bool allowSimulatedPlayer) const {
|
||||
} catch (...) { return false; }
|
||||
}
|
||||
|
||||
// bool Actor::isItemActor() const {
|
||||
// return hasCategory((ActorCategory)1024); // IDA Player::take
|
||||
// }
|
||||
bool Actor::isItemActor() const {
|
||||
return hasCategory((ActorCategory)1024); // IDA Player::take
|
||||
}
|
||||
|
||||
bool Actor::isOnGround() const {
|
||||
return (dAccess<bool, 472>(this)); // IDA DirectActorProxyImpl<IMobMovementProxy>::isOnGround
|
||||
@ -169,16 +169,16 @@ Vec3 Actor::getCameraPos() const {
|
||||
return pos;
|
||||
}
|
||||
|
||||
// Tick* Actor::getLastTick() const {
|
||||
// auto bs = getBlockSource();
|
||||
// if (!bs)
|
||||
// return nullptr;
|
||||
// auto bpos = getPos().toBlockPos();
|
||||
// LevelChunk* lc = bs->getChunkAt(bpos);
|
||||
// if (!lc)
|
||||
// return nullptr;
|
||||
// return (Tick*)&lc->getLastTick();
|
||||
// }
|
||||
Tick* Actor::getLastTick() const {
|
||||
auto bs = getBlockSource();
|
||||
if (!bs)
|
||||
return nullptr;
|
||||
auto bpos = getPos().toBlockPos();
|
||||
LevelChunk* lc = bs->getChunkAt(bpos);
|
||||
if (!lc)
|
||||
return nullptr;
|
||||
return (Tick*)&lc->getLastTick();
|
||||
}
|
||||
//enum ActorLocation;
|
||||
|
||||
// BlockInstance Actor::getBlockFromViewVector(FaceID& face, bool includeLiquid, bool solidOnly, float maxDistance, bool ignoreBorderBlocks, bool fullOnly) const {
|
||||
|
@ -2,6 +2,7 @@
|
||||
#include <MC/RakNet.hpp>
|
||||
|
||||
string NetworkIdentifier::getIP() {
|
||||
string rv = Global<RakNet::RakPeer>->getAdr(*this).ToString(true, ':');
|
||||
string rv;
|
||||
Global<RakNet::RakPeer>->getAdr(*this).ToString_New(true, ':', rv.data());
|
||||
return rv.substr(0, rv.find('|'));
|
||||
}
|
@ -71,15 +71,9 @@ std::string& BinaryStream::getRaw() {
|
||||
return *dAccess<std::string*, 15>(this); // BinaryStream::getAndReleaseData
|
||||
}
|
||||
|
||||
struct IDataOutput{
|
||||
void* pVT;
|
||||
BinaryStream* pBinaryStream;
|
||||
};
|
||||
|
||||
void BinaryStream::writeCompoundTag(class CompoundTag const& tag) {
|
||||
//serialize<DataItem>::write in case 5
|
||||
IDataOutput pVTVarIntDataOutput;
|
||||
pVTVarIntDataOutput.pVT = dlsym("??_7VarIntDataOutput@@6B@");
|
||||
pVTVarIntDataOutput.pBinaryStream = this;
|
||||
NbtIo::write(&tag,pVTVarIntDataOutput);
|
||||
VarIntDataOutput pVTVarIntDataOutput = VarIntDataOutput(this);
|
||||
NbtIo::write(&tag,(IDataOutput&)pVTVarIntDataOutput);
|
||||
}
|
@ -845,7 +845,7 @@ static_assert(sizeof(MobArmorEquipmentPacket) == 0x198 || sizeof(MobArmorEquipme
|
||||
static_assert(sizeof(InteractPacket) == 0x50 || sizeof(InteractPacket) == 48, "size of InteractPacket should be 80 or 48(default)");
|
||||
static_assert(sizeof(BlockPickRequestPacket) == 0x40 || sizeof(BlockPickRequestPacket) == 48, "size of BlockPickRequestPacket should be 64 or 48(default)");
|
||||
static_assert(sizeof(ActorPickRequestPacket) == 0x40 || sizeof(ActorPickRequestPacket) == 48, "size of ActorPickRequestPacket should be 64 or 48(default)");
|
||||
static_assert(sizeof(PlayerActionPacket) == 0x58 || sizeof(PlayerActionPacket) == 48, "size of PlayerActionPacket should be 88 or 48(default)");
|
||||
static_assert(sizeof(PlayerActionPacket) == 0x50 || sizeof(PlayerActionPacket) == 48, "size of PlayerActionPacket should be 88 or 48(default)");
|
||||
static_assert(sizeof(HurtArmorPacket) == 0x40 || sizeof(HurtArmorPacket) == 48, "size of HurtArmorPacket should be 64 or 48(default)");
|
||||
static_assert(sizeof(SetActorDataPacket) == 0x58 || sizeof(SetActorDataPacket) == 48, "size of SetActorDataPacket should be 88 or 48(default)");
|
||||
static_assert(sizeof(SetActorMotionPacket) == 0x48 || sizeof(SetActorMotionPacket) == 48, "size of SetActorMotionPacket should be 72 or 48(default)");
|
||||
|
@ -9,11 +9,11 @@
|
||||
#include <MC/ResourcePackStack.hpp>
|
||||
#include <EventAPI.h>
|
||||
#include <MC/ResourcePackRepository.hpp>
|
||||
void InitParticle() {
|
||||
Event::ResourcePackInitEvent::subscribe([](const Event::ResourcePackInitEvent& ev) {
|
||||
ev.mRepo->setCustomResourcePackPath(PackType::PackType_Resources, R"(plugins/LiteLoader/ResourcePacks)");
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
ParticleAPI ParticleCUI::api{};
|
||||
//void InitParticle() {
|
||||
// Event::ResourcePackInitEvent::subscribe([](const Event::ResourcePackInitEvent& ev) {
|
||||
// ev.mRepo->setCustomResourcePackPath(PackType::PackType_Resources, R"(plugins/LiteLoader/ResourcePacks)");
|
||||
// return true;
|
||||
// });
|
||||
//}
|
||||
//
|
||||
//ParticleAPI ParticleCUI::api{};
|
@ -148,7 +148,7 @@ bool InitPlayerDatabase() {
|
||||
// return true;
|
||||
// });
|
||||
Event::PlayerJoinEvent::subscribe([](const Event::PlayerJoinEvent& e) {
|
||||
if (!e.mPlayer->isSimulatedPlayer()) {
|
||||
if (!e.mPlayer) {
|
||||
insert(e.mPlayer->getRealName(), e.mPlayer->getXuid(), e.mPlayer->getUuid());
|
||||
}
|
||||
return true;
|
||||
|
@ -28,5 +28,5 @@ bool Objective::setDisplay(const std::string& slotName, ObjectiveSortOrder sort)
|
||||
|
||||
std::string Objective::getName(){
|
||||
//ScoreboardCommand::applyPlayerOperation Line186
|
||||
return dAccess<std::string&>(this, 64);
|
||||
return dAccess<std::string>(this, 64);
|
||||
};
|
File diff suppressed because it is too large
Load Diff
@ -1,426 +1,426 @@
|
||||
#include <unordered_map>
|
||||
|
||||
#include <Main/Config.h>
|
||||
#include <Main/LiteLoader.h>
|
||||
#include <HookAPI.h>
|
||||
#include <LoggerAPI.h>
|
||||
|
||||
#include <MC/InventoryTransactionPacket.hpp>
|
||||
#include <MC/NetworkIdentifier.hpp>
|
||||
#include <MC/Player.hpp>
|
||||
#include <MC/ServerPlayer.hpp>
|
||||
#include <MC/ServerNetworkHandler.hpp>
|
||||
#include <MC/ClientCacheBlobStatusPacket.hpp>
|
||||
#include <MC/BinaryStream.hpp>
|
||||
#include <EventAPI.h>
|
||||
|
||||
#include <MC/SharedConstants.hpp>
|
||||
#include <MC/PropertiesSettings.hpp>
|
||||
#include <MC/ServerPlayer.hpp>
|
||||
#include <ScheduleAPI.h>
|
||||
|
||||
using namespace LL;
|
||||
|
||||
// Fix bug
|
||||
TClasslessInstanceHook(bool, "?_read@ClientCacheBlobStatusPacket@@EEAA?AW4StreamReadResult@@AEAVReadOnlyBinaryStream@@@Z",
|
||||
ReadOnlyBinaryStream* a2) {
|
||||
ReadOnlyBinaryStream pkt(a2->getData(), false);
|
||||
pkt.getUnsignedVarInt();
|
||||
if (pkt.getUnsignedVarInt() >= 0xfff)
|
||||
return false;
|
||||
if (pkt.getUnsignedVarInt() >= 0xfff)
|
||||
return false;
|
||||
return original(this, a2);
|
||||
}
|
||||
|
||||
// Fix bug
|
||||
TClasslessInstanceHook(void*, "?_read@PurchaseReceiptPacket@@EEAA?AW4StreamReadResult@@AEAVReadOnlyBinaryStream@@@Z",
|
||||
ReadOnlyBinaryStream* a2) {
|
||||
return (void*)1;
|
||||
}
|
||||
|
||||
// Fix bug
|
||||
TClasslessInstanceHook(void*, "?_read@EduUriResourcePacket@@EEAA?AW4StreamReadResult@@AEAVReadOnlyBinaryStream@@@Z",
|
||||
ReadOnlyBinaryStream* a2) {
|
||||
return (void*)1;
|
||||
}
|
||||
|
||||
// Fix the listening port twice
|
||||
TClasslessInstanceHook(__int64, "?LogIPSupport@RakPeerHelper@@AEAAXXZ") {
|
||||
static bool isFirstLog = true;
|
||||
if (globalConfig.enableFixListenPort) {
|
||||
if (isFirstLog) {
|
||||
isFirstLog = false;
|
||||
original(this);
|
||||
endTime = clock();
|
||||
Logger("Server").info("Done (" + fmt::format("{:.1f}", (endTime - startTime) * 1.0 / 1000) + "s)! For help, type \"help\" or \"?\"");
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
} else {
|
||||
original(this);
|
||||
if (!isFirstLog) {
|
||||
endTime = clock();
|
||||
Logger("Server").info("Done (" + fmt::format("{:.1f}", (endTime - startTime) * 1.0 / 1000) + "s)! For help, type \"help\" or \"?\"");
|
||||
}
|
||||
isFirstLog = false;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Fix abnormal items
|
||||
#include <MC/InventorySource.hpp>
|
||||
#include <MC/InventoryTransaction.hpp>
|
||||
#include <MC/InventoryAction.hpp>
|
||||
#include <MC/Level.hpp>
|
||||
#include <MC/ElementBlock.hpp>
|
||||
#include <MC/IContainerManager.hpp>
|
||||
#include <MC/ColorFormat.hpp>
|
||||
#include <magic_enum/magic_enum.hpp>
|
||||
|
||||
inline bool itemMayFromReducer(ItemStack const& item) {
|
||||
return item.isNull() || (ElementBlock::isElement(item) && !item.hasUserData());
|
||||
}
|
||||
|
||||
TInstanceHook(void, "?handle@ServerNetworkHandler@@UEAAXAEBVNetworkIdentifier@@AEBVInventoryTransactionPacket@@@Z",
|
||||
ServerNetworkHandler, NetworkIdentifier const& netid, InventoryTransactionPacket* pk) {
|
||||
if (globalConfig.enableAntiGive) {
|
||||
auto sp = (Player*)this->getServerPlayer(netid);
|
||||
auto& actions = pk->transaction->data.actions;
|
||||
bool abnormal = false;
|
||||
bool mayFromReducer = true;
|
||||
bool isContainer = false;
|
||||
for (auto& action : actions) {
|
||||
if (action.first.type == InventorySourceType::Container) {
|
||||
isContainer = true;
|
||||
if (abnormal) {
|
||||
logger.warn(tr("ll.antiAbnormalItem.detected", sp->getRealName()));
|
||||
mayFromReducer = false;
|
||||
}
|
||||
}
|
||||
if (action.first.type == InventorySourceType::NONIMPLEMENTEDTODO) {
|
||||
for (auto& a : action.second) {
|
||||
auto fromDesc = ItemStack::fromDescriptor(a.fromDescriptor, Global<Level>->getBlockPalette(), true);
|
||||
auto toDesc = ItemStack::fromDescriptor(a.fromDescriptor, Global<Level>->getBlockPalette(), true);
|
||||
if ( isContainer || !itemMayFromReducer(fromDesc) || !itemMayFromReducer(toDesc) || !itemMayFromReducer(a.fromItem) || !itemMayFromReducer(a.toItem)) {
|
||||
if (mayFromReducer) {
|
||||
logger.warn(tr("ll.antiAbnormalItem.detected", sp->getRealName()));
|
||||
}
|
||||
if (!toDesc.isNull()) {
|
||||
logger.warn(tr("ll.antiAbnormalItem.itemInfo", toDesc.toString()));
|
||||
}
|
||||
mayFromReducer = false;
|
||||
}
|
||||
}
|
||||
abnormal = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (abnormal && !mayFromReducer) {
|
||||
string cmd = globalConfig.antiGiveCommand;
|
||||
ReplaceStr(cmd, "{player}", "\"" + sp->getRealName() + "\"");
|
||||
Level::runcmd(cmd);
|
||||
return;
|
||||
}
|
||||
}
|
||||
return original(this, netid, pk);
|
||||
}
|
||||
|
||||
TInstanceHook(size_t, "??0PropertiesSettings@@QEAA@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z", PropertiesSettings, const std::string& file) {
|
||||
auto out = original(this, file);
|
||||
if (LL::globalConfig.enableUnoccupyPort19132) {
|
||||
// logger.warn("If you turn on this feature, your server will not be displayed on the LAN");
|
||||
DWORD v4Flag, v6Flag;
|
||||
VirtualProtect((void*)&SharedConstants::NetworkDefaultGamePort, 4, PAGE_READWRITE, &v4Flag);
|
||||
*(unsigned short*)&SharedConstants::NetworkDefaultGamePort = getServerPort();
|
||||
VirtualProtect((void*)&SharedConstants::NetworkDefaultGamePort, 4, v4Flag, NULL);
|
||||
|
||||
VirtualProtect((void*)&SharedConstants::NetworkDefaultGamePortv6, 4, PAGE_READWRITE, &v6Flag);
|
||||
*(unsigned short*)&SharedConstants::NetworkDefaultGamePortv6 = getServerPortv6();
|
||||
VirtualProtect((void*)&SharedConstants::NetworkDefaultGamePortv6, 4, v6Flag, NULL);
|
||||
}
|
||||
// Global service
|
||||
Global<PropertiesSettings> = this;
|
||||
return out;
|
||||
}
|
||||
|
||||
// Fix move view crash (ref PlayerAuthInput[MoveView])
|
||||
Player* movingViewPlayer = nullptr;
|
||||
TInstanceHook(void, "?moveView@Player@@UEAAXXZ",
|
||||
Player) {
|
||||
movingViewPlayer = this;
|
||||
original(this);
|
||||
movingViewPlayer = nullptr;
|
||||
}
|
||||
#include <MC/ChunkViewSource.hpp>
|
||||
inline bool Interval(int a1) {
|
||||
if (a1 < 0x5ffffff && a1 > -0x5ffffff)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
template <typename T>
|
||||
inline bool validPosition(T const& pos) {
|
||||
if (isnan(static_cast<float>(pos.x)) || isnan(static_cast<float>(pos.z)))
|
||||
return false;
|
||||
return Interval(static_cast<int>(pos.x)) && Interval(static_cast<int>(pos.y)) && Interval(static_cast<int>(pos.z));
|
||||
}
|
||||
inline void fixPlayerPosition(Player* pl, bool kick = true) {
|
||||
if (pl->isPlayer()) {
|
||||
logger.warn << "Player(" << pl->getRealName() << ") sent invalid MoveView Packet!" << Logger::endl;
|
||||
auto& pos = pl->getPosPrev();
|
||||
if (validPosition(pos))
|
||||
pl->setPos(pl->getPosition());
|
||||
else
|
||||
pl->setPos(Global<Level>->getDefaultSpawn().bottomCenter());
|
||||
if (kick)
|
||||
pl->kick("error move");
|
||||
}
|
||||
}
|
||||
TInstanceHook(void, "?moveSpawnView@Player@@QEAAXAEBVVec3@@V?$AutomaticID@VDimension@@H@@@Z",
|
||||
Player, class Vec3 const& pos, class AutomaticID<class Dimension, int> dimid) {
|
||||
if (validPosition(pos))
|
||||
return original(this, pos, dimid);
|
||||
fixPlayerPosition(this, false);
|
||||
}
|
||||
TClasslessInstanceHook(__int64, "?move@ChunkViewSource@@QEAAXAEBVBlockPos@@H_NW4ChunkSourceViewGenerateMode@ChunkSource@@V?$function@$$A6AXV?$buffer_span_mut@V?$shared_ptr@VLevelChunk@@@std@@@@V?$buffer_span@I@@@Z@std@@UActorUniqueID@@@Z",
|
||||
BlockPos a2, int a3, unsigned __int8 a4, int a5, __int64 a6, __int64 a7) {
|
||||
if (validPosition(a2))
|
||||
return original(this, a2, a3, a4,a5,a6,a7);
|
||||
fixPlayerPosition(movingViewPlayer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
TInstanceHook(void, "?move@Player@@UEAAXAEBVVec3@@@Z", Player, Vec3 pos) {
|
||||
if (validPosition(pos))
|
||||
return original(this, pos);
|
||||
logger.warn << "Player(" << this->getRealName() << ") sent invalid Move Packet!" << Logger::endl;
|
||||
this->kick("error move");
|
||||
return;
|
||||
}
|
||||
|
||||
#if false
|
||||
TInstanceHook(void, "?die@ServerPlayer@@UEAAXAEBVActorDamageSource@@@Z", ServerPlayer , ActorDamageSource* ds)
|
||||
{
|
||||
original(this, ds);
|
||||
if (LL::globalConfig.enableFixMcBug)
|
||||
{
|
||||
auto name = getRealName();
|
||||
Schedule::delay([name]() {
|
||||
auto pl = Global<Level>->getPlayer(name);
|
||||
if (pl)
|
||||
pl->kill();
|
||||
},1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Fix Fishing Hook changeDimension Crash
|
||||
TInstanceHook(__int64, "?changeDimension@Actor@@UEAAXV?$AutomaticID@VDimension@@H@@@Z", Actor, unsigned int a1) {
|
||||
if (!LL::globalConfig.enableFixMcBug)
|
||||
return original(this, a1);
|
||||
if ((int)this->getEntityTypeId() == 0x4D)
|
||||
return 0;
|
||||
return original(this, a1);
|
||||
}
|
||||
|
||||
TClasslessInstanceHook(__int64, "?teleportEntity@EndGatewayBlockActor@@QEAAXAEAVActor@@@Z", Actor* a1) {
|
||||
if (!LL::globalConfig.enableFixMcBug)
|
||||
return original(this, a1);
|
||||
if ((int)a1->getEntityTypeId() == 0x4D)
|
||||
return 0;
|
||||
return original(this, a1);
|
||||
}
|
||||
|
||||
// Fix wine stop
|
||||
TClasslessInstanceHook(void, "?leaveGameSync@ServerInstance@@QEAAXXZ") {
|
||||
original(this);
|
||||
if (IsWineEnvironment()) {
|
||||
std::cerr << "Quit correctly" << std::endl;
|
||||
auto proc = GetCurrentProcess();
|
||||
TerminateProcess(proc, 0);
|
||||
}
|
||||
}
|
||||
|
||||
TClasslessInstanceHook(enum StartupResult, "?Startup@RakPeer@RakNet@@UEAA?AW4StartupResult@2@IPEAUSocketDescriptor@2@IH@Z",
|
||||
unsigned int maxConnections, class SocketDescriptor* socketDescriptors, unsigned socketDescriptorCount, int threadPriority) {
|
||||
if (maxConnections > 0xFFFF) {
|
||||
maxConnections = 0xFFFF;
|
||||
}
|
||||
return original(this, maxConnections, socketDescriptors, socketDescriptorCount, threadPriority);
|
||||
}
|
||||
|
||||
// Fix command crash when server is stopping
|
||||
TClasslessInstanceHook(void, "?fireEventPlayerMessage@MinecraftEventing@@AEAAXAEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@000@Z",
|
||||
std::string const& a1, std::string const& a2, std::string const& a3, std::string const& a4) {
|
||||
if (LL::isServerStopping())
|
||||
return;
|
||||
original(this, a1, a2, a3, a4);
|
||||
}
|
||||
TClasslessInstanceHook(void, "?fireEventPlayerTransform@MinecraftEventing@@SAXAEAVPlayer@@@Z",
|
||||
class Player& a1) {
|
||||
if (LL::isServerStopping())
|
||||
return;
|
||||
original(this, a1);
|
||||
}
|
||||
|
||||
TClasslessInstanceHook(void, "?fireEventPlayerTravelled@MinecraftEventing@@UEAAXPEAVPlayer@@M@Z",
|
||||
class Player& a1, float a2) {
|
||||
if (LL::isServerStopping())
|
||||
return;
|
||||
original(this, a1, a2);
|
||||
}
|
||||
TClasslessInstanceHook(void, "?fireEventPlayerTeleported@MinecraftEventing@@SAXPEAVPlayer@@MW4TeleportationCause@1@H@Z",
|
||||
class Player* a1, float a2, int a3, int a4) {
|
||||
if (LL::isServerStopping())
|
||||
return;
|
||||
original(this, a1, a2, a3, a4);
|
||||
}
|
||||
|
||||
// Set stdin mode to text mode if in wine environment
|
||||
inline bool _tryFixConsoleInputMode() {
|
||||
if ((LL::globalConfig.enableFixMcBug && IsWineEnvironment()) || LL::globalConfig.enableForceUtf8Input) {
|
||||
int result = _setmode(_fileno(stdin), _O_U8TEXT);
|
||||
if (result == -1) {
|
||||
logger.error("Cannot set stdin to utf8 text mode");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Fix wine console input
|
||||
THook(std::wistream&,
|
||||
"??$getline@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@YAAEAV?$basic_istream@_WU?$char_traits@_W@std@@@0@$$"
|
||||
"QEAV10@AEAV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@0@_W@Z",
|
||||
std::wistream&& ret, std::wstring& a1, wchar_t a2) {
|
||||
if (&ret == &std::wcin) {
|
||||
static bool fixed = _tryFixConsoleInputMode();
|
||||
}
|
||||
return original(std::move(ret), a1, a2);
|
||||
}
|
||||
|
||||
// Fix server broadcast bug.
|
||||
TClasslessInstanceHook(bool, "?getLANBroadcast@LevelData@@QEBA_NXZ") {
|
||||
if (LL::globalConfig.enableFixBroadcastBug) {
|
||||
return true;
|
||||
}
|
||||
return original(this);
|
||||
}
|
||||
|
||||
TClasslessInstanceHook(bool, "?getLANBroadcastIntent@LevelData@@QEBA_NXZ") {
|
||||
if (LL::globalConfig.enableFixBroadcastBug) {
|
||||
return true;
|
||||
}
|
||||
return original(this);
|
||||
}
|
||||
|
||||
// Disable 'Running AutoCompaction...' log.
|
||||
bool pauseBLogging = false;
|
||||
THook(__int64, "std::_Func_impl_no_alloc<<lambda_bc4a73e92ba7b703b39f322d94bb55f6>,TaskResult>::_Do_call",
|
||||
__int64 a1, __int64 a2) {
|
||||
if (LL::globalConfig.disableAutoCompactionLog) {
|
||||
pauseBLogging = true;
|
||||
auto v = original(a1, a2);
|
||||
pauseBLogging = false;
|
||||
return v;
|
||||
}
|
||||
return original(a1, a2);
|
||||
}
|
||||
|
||||
TClasslessInstanceHook(char, "?log_va@BedrockLog@@YAXW4LogCategory@1@V?$bitset@$02@std@@W4LogRule@1@W4LogAreaID@@IPEBDH4PEAD@Z",
|
||||
char a2, int a3, int a4, unsigned int a5, __int64 a6, int a7, __int64 a8, __int64 a9) {
|
||||
if (LL::globalConfig.disableAutoCompactionLog && pauseBLogging) {
|
||||
return 0;
|
||||
}
|
||||
return original(this, a2, a3, a4, a5, a6, a7, a8, a9);
|
||||
}
|
||||
|
||||
|
||||
//Try Fix BDS Crash
|
||||
//Beta
|
||||
|
||||
THook(void*, "??0ScopedTimer@ImguiProfiler@@QEAA@PEBD0_N@Z",
|
||||
void* self, char* a2, char* a3, char a4) {
|
||||
if (LL::globalConfig.enableFixBDSCrash) {
|
||||
return nullptr;
|
||||
}
|
||||
return original(self, a2, a3, a4);
|
||||
}
|
||||
|
||||
THook(void, "??1ScopedTimer@ImguiProfiler@@UEAA@XZ",
|
||||
void* self) {
|
||||
if (LL::globalConfig.enableFixBDSCrash) {
|
||||
return;
|
||||
}
|
||||
return original(self);
|
||||
}
|
||||
|
||||
SHook2("_tickDimensionTransition", __int64, "40 53 55 41 56 41 57 48 ?? ?? ?? ?? ?? ?? 48 ?? ?? ?? ?? ?? ?? 48 33 "
|
||||
"C4 48 89 ?? ?? ?? 48 8B C2 4C 8B F9 48 8B C8 33 D2 49 8B D9 49 8B E8 E8 ?? ?? ?? ?? 4C 8B F0 48 85 C0",
|
||||
__int64 a1, ActorOwnerComponent* a2, __int64 a3, void* a4) {
|
||||
if (LL::globalConfig.enableFixBDSCrash) {
|
||||
auto ac = Actor::tryGetFromComponent(*a2, 0);
|
||||
if (ac) {
|
||||
auto bs = &ac->getRegionConst();
|
||||
if (bs == nullptr || !bs)
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return original(a1, a2, a3, a4);
|
||||
}
|
||||
|
||||
THook(void, "?_trackMovement@GameEventMovementTrackingSystem@@CAXAEAVActor@@AEAVGameEventMovementTrackingComponent@@@Z",
|
||||
Actor* a1, void* self) {
|
||||
if (LL::globalConfig.enableFixBDSCrash) {
|
||||
auto bs = &a1->getRegionConst();
|
||||
if (bs == nullptr || !bs) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
original(a1, self);
|
||||
}
|
||||
|
||||
#include <MC/LevelChunk.hpp>
|
||||
#include <MC/ChunkSource.hpp>
|
||||
|
||||
THook(LevelChunk*, "?getChunk@BlockSource@@QEBAPEAVLevelChunk@@AEBVChunkPos@@@Z",
|
||||
BlockSource* self, ChunkPos* a2) {
|
||||
if (LL::globalConfig.enableFixBDSCrash) {
|
||||
LevelChunk* ptr = nullptr;
|
||||
try {
|
||||
ptr = original(self, a2);
|
||||
} catch (...) {
|
||||
return nullptr;
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
return original(self, a2);
|
||||
}
|
||||
|
||||
|
||||
THook(__int64, "?getAvailableChunk@ChunkSource@@QEAA?AV?$shared_ptr@VLevelChunk@@@std@@AEBVChunkPos@@@Z",
|
||||
__int64 a1, __int64 a2) {
|
||||
if (LL::globalConfig.enableFixBDSCrash) {
|
||||
__int64 ptr = NULL;
|
||||
try {
|
||||
ptr = original(a1, a2);
|
||||
} catch (...) {
|
||||
return NULL;
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
return original(a1, a2);
|
||||
}
|
||||
|
||||
TInstanceHook(BlockSource*, "?getRegionConst@Actor@@QEBAAEBVBlockSource@@XZ",
|
||||
Actor) {
|
||||
|
||||
auto bs = original(this);
|
||||
if (LL::globalConfig.enableFixBDSCrash) {
|
||||
if (!bs) {
|
||||
return Level::getBlockSource(getDimensionId());
|
||||
}
|
||||
}
|
||||
return bs;
|
||||
}
|
||||
//#include <unordered_map>
|
||||
//
|
||||
//#include <Main/Config.h>
|
||||
//#include <Main/LiteLoader.h>
|
||||
//#include <HookAPI.h>
|
||||
//#include <LoggerAPI.h>
|
||||
//
|
||||
//#include <MC/InventoryTransactionPacket.hpp>
|
||||
//#include <MC/NetworkIdentifier.hpp>
|
||||
//#include <MC/Player.hpp>
|
||||
//#include <MC/ServerPlayer.hpp>
|
||||
//#include <MC/ServerNetworkHandler.hpp>
|
||||
//#include <MC/ClientCacheBlobStatusPacket.hpp>
|
||||
//#include <MC/BinaryStream.hpp>
|
||||
//#include <EventAPI.h>
|
||||
//
|
||||
//#include <MC/SharedConstants.hpp>
|
||||
//#include <MC/PropertiesSettings.hpp>
|
||||
//#include <MC/ServerPlayer.hpp>
|
||||
//#include <ScheduleAPI.h>
|
||||
//
|
||||
//using namespace LL;
|
||||
//
|
||||
//// Fix bug
|
||||
//TClasslessInstanceHook(bool, "?_read@ClientCacheBlobStatusPacket@@EEAA?AW4StreamReadResult@@AEAVReadOnlyBinaryStream@@@Z",
|
||||
// ReadOnlyBinaryStream* a2) {
|
||||
// ReadOnlyBinaryStream pkt(a2->getData(), false);
|
||||
// pkt.getUnsignedVarInt();
|
||||
// if (pkt.getUnsignedVarInt() >= 0xfff)
|
||||
// return false;
|
||||
// if (pkt.getUnsignedVarInt() >= 0xfff)
|
||||
// return false;
|
||||
// return original(this, a2);
|
||||
//}
|
||||
//
|
||||
//// Fix bug
|
||||
//TClasslessInstanceHook(void*, "?_read@PurchaseReceiptPacket@@EEAA?AW4StreamReadResult@@AEAVReadOnlyBinaryStream@@@Z",
|
||||
// ReadOnlyBinaryStream* a2) {
|
||||
// return (void*)1;
|
||||
//}
|
||||
//
|
||||
//// Fix bug
|
||||
//TClasslessInstanceHook(void*, "?_read@EduUriResourcePacket@@EEAA?AW4StreamReadResult@@AEAVReadOnlyBinaryStream@@@Z",
|
||||
// ReadOnlyBinaryStream* a2) {
|
||||
// return (void*)1;
|
||||
//}
|
||||
//
|
||||
//// Fix the listening port twice
|
||||
//TClasslessInstanceHook(__int64, "?LogIPSupport@RakPeerHelper@@AEAAXXZ") {
|
||||
// static bool isFirstLog = true;
|
||||
// if (globalConfig.enableFixListenPort) {
|
||||
// if (isFirstLog) {
|
||||
// isFirstLog = false;
|
||||
// original(this);
|
||||
// endTime = clock();
|
||||
// Logger("Server").info("Done (" + fmt::format("{:.1f}", (endTime - startTime) * 1.0 / 1000) + "s)! For help, type \"help\" or \"?\"");
|
||||
// return 1;
|
||||
// }
|
||||
// return 0;
|
||||
// } else {
|
||||
// original(this);
|
||||
// if (!isFirstLog) {
|
||||
// endTime = clock();
|
||||
// Logger("Server").info("Done (" + fmt::format("{:.1f}", (endTime - startTime) * 1.0 / 1000) + "s)! For help, type \"help\" or \"?\"");
|
||||
// }
|
||||
// isFirstLog = false;
|
||||
// return 1;
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//// Fix abnormal items
|
||||
//#include <MC/InventorySource.hpp>
|
||||
//#include <MC/InventoryTransaction.hpp>
|
||||
//#include <MC/InventoryAction.hpp>
|
||||
//#include <MC/Level.hpp>
|
||||
//#include <MC/ElementBlock.hpp>
|
||||
//#include <MC/IContainerManager.hpp>
|
||||
//#include <MC/ColorFormat.hpp>
|
||||
//#include <magic_enum/magic_enum.hpp>
|
||||
//
|
||||
//inline bool itemMayFromReducer(ItemStack const& item) {
|
||||
// return item.isNull() || (ElementBlock::isElement(item) && !item.hasUserData());
|
||||
//}
|
||||
//
|
||||
//TInstanceHook(void, "?handle@ServerNetworkHandler@@UEAAXAEBVNetworkIdentifier@@AEBVInventoryTransactionPacket@@@Z",
|
||||
// ServerNetworkHandler, NetworkIdentifier const& netid, InventoryTransactionPacket* pk) {
|
||||
// if (globalConfig.enableAntiGive) {
|
||||
// auto sp = (Player*)this->getServerPlayer(netid);
|
||||
// auto& actions = pk->transaction->data.actions;
|
||||
// bool abnormal = false;
|
||||
// bool mayFromReducer = true;
|
||||
// bool isContainer = false;
|
||||
// for (auto& action : actions) {
|
||||
// if (action.first.type == InventorySourceType::Container) {
|
||||
// isContainer = true;
|
||||
// if (abnormal) {
|
||||
// logger.warn(tr("ll.antiAbnormalItem.detected", sp->getRealName()));
|
||||
// mayFromReducer = false;
|
||||
// }
|
||||
// }
|
||||
// if (action.first.type == InventorySourceType::NONIMPLEMENTEDTODO) {
|
||||
// for (auto& a : action.second) {
|
||||
// auto fromDesc = ItemStack::fromDescriptor(a.fromDescriptor, Global<Level>->getBlockPalette(), true);
|
||||
// auto toDesc = ItemStack::fromDescriptor(a.fromDescriptor, Global<Level>->getBlockPalette(), true);
|
||||
// if ( isContainer || !itemMayFromReducer(fromDesc) || !itemMayFromReducer(toDesc) || !itemMayFromReducer(a.fromItem) || !itemMayFromReducer(a.toItem)) {
|
||||
// if (mayFromReducer) {
|
||||
// logger.warn(tr("ll.antiAbnormalItem.detected", sp->getRealName()));
|
||||
// }
|
||||
// if (!toDesc.isNull()) {
|
||||
// logger.warn(tr("ll.antiAbnormalItem.itemInfo", toDesc.toString()));
|
||||
// }
|
||||
// mayFromReducer = false;
|
||||
// }
|
||||
// }
|
||||
// abnormal = true;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (abnormal && !mayFromReducer) {
|
||||
// string cmd = globalConfig.antiGiveCommand;
|
||||
// ReplaceStr(cmd, "{player}", "\"" + sp->getRealName() + "\"");
|
||||
// Level::runcmd(cmd);
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
// return original(this, netid, pk);
|
||||
//}
|
||||
//
|
||||
//TInstanceHook(size_t, "??0PropertiesSettings@@QEAA@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z", PropertiesSettings, const std::string& file) {
|
||||
// auto out = original(this, file);
|
||||
// if (LL::globalConfig.enableUnoccupyPort19132) {
|
||||
// // logger.warn("If you turn on this feature, your server will not be displayed on the LAN");
|
||||
// DWORD v4Flag, v6Flag;
|
||||
// VirtualProtect((void*)&SharedConstants::NetworkDefaultGamePort, 4, PAGE_READWRITE, &v4Flag);
|
||||
// *(unsigned short*)&SharedConstants::NetworkDefaultGamePort = getServerPort();
|
||||
// VirtualProtect((void*)&SharedConstants::NetworkDefaultGamePort, 4, v4Flag, NULL);
|
||||
//
|
||||
// VirtualProtect((void*)&SharedConstants::NetworkDefaultGamePortv6, 4, PAGE_READWRITE, &v6Flag);
|
||||
// *(unsigned short*)&SharedConstants::NetworkDefaultGamePortv6 = getServerPortv6();
|
||||
// VirtualProtect((void*)&SharedConstants::NetworkDefaultGamePortv6, 4, v6Flag, NULL);
|
||||
// }
|
||||
// // Global service
|
||||
// Global<PropertiesSettings> = this;
|
||||
// return out;
|
||||
//}
|
||||
//
|
||||
//// Fix move view crash (ref PlayerAuthInput[MoveView])
|
||||
//Player* movingViewPlayer = nullptr;
|
||||
//TInstanceHook(void, "?moveView@Player@@UEAAXXZ",
|
||||
// Player) {
|
||||
// movingViewPlayer = this;
|
||||
// original(this);
|
||||
// movingViewPlayer = nullptr;
|
||||
//}
|
||||
//#include <MC/ChunkViewSource.hpp>
|
||||
//inline bool Interval(int a1) {
|
||||
// if (a1 < 0x5ffffff && a1 > -0x5ffffff)
|
||||
// return true;
|
||||
// return false;
|
||||
//}
|
||||
//template <typename T>
|
||||
//inline bool validPosition(T const& pos) {
|
||||
// if (isnan(static_cast<float>(pos.x)) || isnan(static_cast<float>(pos.z)))
|
||||
// return false;
|
||||
// return Interval(static_cast<int>(pos.x)) && Interval(static_cast<int>(pos.y)) && Interval(static_cast<int>(pos.z));
|
||||
//}
|
||||
//inline void fixPlayerPosition(Player* pl, bool kick = true) {
|
||||
// if (pl->isPlayer()) {
|
||||
// logger.warn << "Player(" << pl->getRealName() << ") sent invalid MoveView Packet!" << Logger::endl;
|
||||
// auto& pos = pl->getPosPrev();
|
||||
// if (validPosition(pos))
|
||||
// pl->setPos(pl->getPosition());
|
||||
// else
|
||||
// pl->setPos(Global<Level>->getDefaultSpawn().bottomCenter());
|
||||
// if (kick)
|
||||
// pl->kick("error move");
|
||||
// }
|
||||
//}
|
||||
//TInstanceHook(void, "?moveSpawnView@Player@@QEAAXAEBVVec3@@V?$AutomaticID@VDimension@@H@@@Z",
|
||||
// Player, class Vec3 const& pos, class AutomaticID<class Dimension, int> dimid) {
|
||||
// if (validPosition(pos))
|
||||
// return original(this, pos, dimid);
|
||||
// fixPlayerPosition(this, false);
|
||||
//}
|
||||
//TClasslessInstanceHook(__int64, "?move@ChunkViewSource@@QEAAXAEBVBlockPos@@H_NW4ChunkSourceViewGenerateMode@ChunkSource@@V?$function@$$A6AXV?$buffer_span_mut@V?$shared_ptr@VLevelChunk@@@std@@@@V?$buffer_span@I@@@Z@std@@UActorUniqueID@@@Z",
|
||||
// BlockPos a2, int a3, unsigned __int8 a4, int a5, __int64 a6, __int64 a7) {
|
||||
// if (validPosition(a2))
|
||||
// return original(this, a2, a3, a4,a5,a6,a7);
|
||||
// fixPlayerPosition(movingViewPlayer);
|
||||
// return 0;
|
||||
//}
|
||||
//
|
||||
//TInstanceHook(void, "?move@Player@@UEAAXAEBVVec3@@@Z", Player, Vec3 pos) {
|
||||
// if (validPosition(pos))
|
||||
// return original(this, pos);
|
||||
// logger.warn << "Player(" << this->getRealName() << ") sent invalid Move Packet!" << Logger::endl;
|
||||
// this->kick("error move");
|
||||
// return;
|
||||
//}
|
||||
//
|
||||
//#if false
|
||||
//TInstanceHook(void, "?die@ServerPlayer@@UEAAXAEBVActorDamageSource@@@Z", ServerPlayer , ActorDamageSource* ds)
|
||||
//{
|
||||
// original(this, ds);
|
||||
// if (LL::globalConfig.enableFixMcBug)
|
||||
// {
|
||||
// auto name = getRealName();
|
||||
// Schedule::delay([name]() {
|
||||
// auto pl = Global<Level>->getPlayer(name);
|
||||
// if (pl)
|
||||
// pl->kill();
|
||||
// },1);
|
||||
// }
|
||||
//}
|
||||
//#endif
|
||||
//
|
||||
//// Fix Fishing Hook changeDimension Crash
|
||||
//TInstanceHook(__int64, "?changeDimension@Actor@@UEAAXV?$AutomaticID@VDimension@@H@@@Z", Actor, unsigned int a1) {
|
||||
// if (!LL::globalConfig.enableFixMcBug)
|
||||
// return original(this, a1);
|
||||
// if ((int)this->getEntityTypeId() == 0x4D)
|
||||
// return 0;
|
||||
// return original(this, a1);
|
||||
//}
|
||||
//
|
||||
//TClasslessInstanceHook(__int64, "?teleportEntity@EndGatewayBlockActor@@QEAAXAEAVActor@@@Z", Actor* a1) {
|
||||
// if (!LL::globalConfig.enableFixMcBug)
|
||||
// return original(this, a1);
|
||||
// if ((int)a1->getEntityTypeId() == 0x4D)
|
||||
// return 0;
|
||||
// return original(this, a1);
|
||||
//}
|
||||
//
|
||||
//// Fix wine stop
|
||||
//TClasslessInstanceHook(void, "?leaveGameSync@ServerInstance@@QEAAXXZ") {
|
||||
// original(this);
|
||||
// if (IsWineEnvironment()) {
|
||||
// std::cerr << "Quit correctly" << std::endl;
|
||||
// auto proc = GetCurrentProcess();
|
||||
// TerminateProcess(proc, 0);
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//TClasslessInstanceHook(enum StartupResult, "?Startup@RakPeer@RakNet@@UEAA?AW4StartupResult@2@IPEAUSocketDescriptor@2@IH@Z",
|
||||
// unsigned int maxConnections, class SocketDescriptor* socketDescriptors, unsigned socketDescriptorCount, int threadPriority) {
|
||||
// if (maxConnections > 0xFFFF) {
|
||||
// maxConnections = 0xFFFF;
|
||||
// }
|
||||
// return original(this, maxConnections, socketDescriptors, socketDescriptorCount, threadPriority);
|
||||
//}
|
||||
//
|
||||
//// Fix command crash when server is stopping
|
||||
//TClasslessInstanceHook(void, "?fireEventPlayerMessage@MinecraftEventing@@AEAAXAEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@000@Z",
|
||||
// std::string const& a1, std::string const& a2, std::string const& a3, std::string const& a4) {
|
||||
// if (LL::isServerStopping())
|
||||
// return;
|
||||
// original(this, a1, a2, a3, a4);
|
||||
//}
|
||||
//TClasslessInstanceHook(void, "?fireEventPlayerTransform@MinecraftEventing@@SAXAEAVPlayer@@@Z",
|
||||
// class Player& a1) {
|
||||
// if (LL::isServerStopping())
|
||||
// return;
|
||||
// original(this, a1);
|
||||
//}
|
||||
//
|
||||
//TClasslessInstanceHook(void, "?fireEventPlayerTravelled@MinecraftEventing@@UEAAXPEAVPlayer@@M@Z",
|
||||
// class Player& a1, float a2) {
|
||||
// if (LL::isServerStopping())
|
||||
// return;
|
||||
// original(this, a1, a2);
|
||||
//}
|
||||
//TClasslessInstanceHook(void, "?fireEventPlayerTeleported@MinecraftEventing@@SAXPEAVPlayer@@MW4TeleportationCause@1@H@Z",
|
||||
// class Player* a1, float a2, int a3, int a4) {
|
||||
// if (LL::isServerStopping())
|
||||
// return;
|
||||
// original(this, a1, a2, a3, a4);
|
||||
//}
|
||||
//
|
||||
//// Set stdin mode to text mode if in wine environment
|
||||
//inline bool _tryFixConsoleInputMode() {
|
||||
// if ((LL::globalConfig.enableFixMcBug && IsWineEnvironment()) || LL::globalConfig.enableForceUtf8Input) {
|
||||
// int result = _setmode(_fileno(stdin), _O_U8TEXT);
|
||||
// if (result == -1) {
|
||||
// logger.error("Cannot set stdin to utf8 text mode");
|
||||
// return false;
|
||||
// }
|
||||
// return true;
|
||||
// }
|
||||
// return true;
|
||||
//}
|
||||
//
|
||||
//// Fix wine console input
|
||||
//THook(std::wistream&,
|
||||
// "??$getline@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@YAAEAV?$basic_istream@_WU?$char_traits@_W@std@@@0@$$"
|
||||
// "QEAV10@AEAV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@0@_W@Z",
|
||||
// std::wistream&& ret, std::wstring& a1, wchar_t a2) {
|
||||
// if (&ret == &std::wcin) {
|
||||
// static bool fixed = _tryFixConsoleInputMode();
|
||||
// }
|
||||
// return original(std::move(ret), a1, a2);
|
||||
//}
|
||||
//
|
||||
//// Fix server broadcast bug.
|
||||
//TClasslessInstanceHook(bool, "?getLANBroadcast@LevelData@@QEBA_NXZ") {
|
||||
// if (LL::globalConfig.enableFixBroadcastBug) {
|
||||
// return true;
|
||||
// }
|
||||
// return original(this);
|
||||
//}
|
||||
//
|
||||
//TClasslessInstanceHook(bool, "?getLANBroadcastIntent@LevelData@@QEBA_NXZ") {
|
||||
// if (LL::globalConfig.enableFixBroadcastBug) {
|
||||
// return true;
|
||||
// }
|
||||
// return original(this);
|
||||
//}
|
||||
//
|
||||
//// Disable 'Running AutoCompaction...' log.
|
||||
//bool pauseBLogging = false;
|
||||
//THook(__int64, "std::_Func_impl_no_alloc<<lambda_bc4a73e92ba7b703b39f322d94bb55f6>,TaskResult>::_Do_call",
|
||||
// __int64 a1, __int64 a2) {
|
||||
// if (LL::globalConfig.disableAutoCompactionLog) {
|
||||
// pauseBLogging = true;
|
||||
// auto v = original(a1, a2);
|
||||
// pauseBLogging = false;
|
||||
// return v;
|
||||
// }
|
||||
// return original(a1, a2);
|
||||
//}
|
||||
//
|
||||
//TClasslessInstanceHook(char, "?log_va@BedrockLog@@YAXW4LogCategory@1@V?$bitset@$02@std@@W4LogRule@1@W4LogAreaID@@IPEBDH4PEAD@Z",
|
||||
// char a2, int a3, int a4, unsigned int a5, __int64 a6, int a7, __int64 a8, __int64 a9) {
|
||||
// if (LL::globalConfig.disableAutoCompactionLog && pauseBLogging) {
|
||||
// return 0;
|
||||
// }
|
||||
// return original(this, a2, a3, a4, a5, a6, a7, a8, a9);
|
||||
//}
|
||||
//
|
||||
//
|
||||
////Try Fix BDS Crash
|
||||
////Beta
|
||||
//
|
||||
//THook(void*, "??0ScopedTimer@ImguiProfiler@@QEAA@PEBD0_N@Z",
|
||||
// void* self, char* a2, char* a3, char a4) {
|
||||
// if (LL::globalConfig.enableFixBDSCrash) {
|
||||
// return nullptr;
|
||||
// }
|
||||
// return original(self, a2, a3, a4);
|
||||
//}
|
||||
//
|
||||
//THook(void, "??1ScopedTimer@ImguiProfiler@@UEAA@XZ",
|
||||
// void* self) {
|
||||
// if (LL::globalConfig.enableFixBDSCrash) {
|
||||
// return;
|
||||
// }
|
||||
// return original(self);
|
||||
//}
|
||||
//
|
||||
//SHook2("_tickDimensionTransition", __int64, "40 53 55 41 56 41 57 48 ?? ?? ?? ?? ?? ?? 48 ?? ?? ?? ?? ?? ?? 48 33 "
|
||||
// "C4 48 89 ?? ?? ?? 48 8B C2 4C 8B F9 48 8B C8 33 D2 49 8B D9 49 8B E8 E8 ?? ?? ?? ?? 4C 8B F0 48 85 C0",
|
||||
// __int64 a1, ActorOwnerComponent* a2, __int64 a3, void* a4) {
|
||||
// if (LL::globalConfig.enableFixBDSCrash) {
|
||||
// auto ac = Actor::tryGetFromComponent(*a2, 0);
|
||||
// if (ac) {
|
||||
// auto bs = &ac->getRegionConst();
|
||||
// if (bs == nullptr || !bs)
|
||||
// return NULL;
|
||||
// }
|
||||
// }
|
||||
// return original(a1, a2, a3, a4);
|
||||
//}
|
||||
//
|
||||
//THook(void, "?_trackMovement@GameEventMovementTrackingSystem@@CAXAEAVActor@@AEAVGameEventMovementTrackingComponent@@@Z",
|
||||
// Actor* a1, void* self) {
|
||||
// if (LL::globalConfig.enableFixBDSCrash) {
|
||||
// auto bs = &a1->getRegionConst();
|
||||
// if (bs == nullptr || !bs) {
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
// original(a1, self);
|
||||
//}
|
||||
//
|
||||
//#include <MC/LevelChunk.hpp>
|
||||
//#include <MC/ChunkSource.hpp>
|
||||
//
|
||||
//THook(LevelChunk*, "?getChunk@BlockSource@@QEBAPEAVLevelChunk@@AEBVChunkPos@@@Z",
|
||||
// BlockSource* self, ChunkPos* a2) {
|
||||
// if (LL::globalConfig.enableFixBDSCrash) {
|
||||
// LevelChunk* ptr = nullptr;
|
||||
// try {
|
||||
// ptr = original(self, a2);
|
||||
// } catch (...) {
|
||||
// return nullptr;
|
||||
// }
|
||||
// return ptr;
|
||||
// }
|
||||
// return original(self, a2);
|
||||
//}
|
||||
//
|
||||
//
|
||||
//THook(__int64, "?getAvailableChunk@ChunkSource@@QEAA?AV?$shared_ptr@VLevelChunk@@@std@@AEBVChunkPos@@@Z",
|
||||
// __int64 a1, __int64 a2) {
|
||||
// if (LL::globalConfig.enableFixBDSCrash) {
|
||||
// __int64 ptr = NULL;
|
||||
// try {
|
||||
// ptr = original(a1, a2);
|
||||
// } catch (...) {
|
||||
// return NULL;
|
||||
// }
|
||||
// return ptr;
|
||||
// }
|
||||
// return original(a1, a2);
|
||||
//}
|
||||
//
|
||||
//TInstanceHook(BlockSource*, "?getRegionConst@Actor@@QEBAAEBVBlockSource@@XZ",
|
||||
// Actor) {
|
||||
//
|
||||
// auto bs = original(this);
|
||||
// if (LL::globalConfig.enableFixBDSCrash) {
|
||||
// if (!bs) {
|
||||
// return Level::getBlockSource(getDimensionId());
|
||||
// }
|
||||
// }
|
||||
// return bs;
|
||||
//}
|
@ -1,389 +1,389 @@
|
||||
#include <filesystem>
|
||||
#include <EventAPI.h>
|
||||
#include <LLAPI.h>
|
||||
#include <ServerAPI.h>
|
||||
#include <RegCommandAPI.h>
|
||||
#include <MC/CommandOrigin.hpp>
|
||||
#include <MC/CommandOutput.hpp>
|
||||
#include <MC/CommandPosition.hpp>
|
||||
#include <MC/CommandRegistry.hpp>
|
||||
#include <MC/Packet.hpp>
|
||||
#include <MC/ServerPlayer.hpp>
|
||||
#include <MC/VanillaDimensions.hpp>
|
||||
#include <Main/Config.h>
|
||||
#include <Main/PluginManager.h>
|
||||
#include "../ScriptEngine/Main/Configs.h"
|
||||
|
||||
using namespace RegisterCommandHelper;
|
||||
using namespace LL;
|
||||
|
||||
static_assert(sizeof(CommandSelector<Player>) == 200);
|
||||
|
||||
class TeleportDimensionCommand : public Command {
|
||||
|
||||
enum class DimensionType {
|
||||
OverWorld,
|
||||
Nether,
|
||||
TheEnd,
|
||||
} DimensionId;
|
||||
CommandSelector<Actor> Victim;
|
||||
CommandPosition CommandPos;
|
||||
bool Victim_isSet = false;
|
||||
bool CommandPos_isSet = false;
|
||||
|
||||
Vec3 getTargetPos(CommandOrigin const& ori, Actor* actor) const {
|
||||
if (CommandPos_isSet)
|
||||
return CommandPos.getPosition(ori, {0, 0, 0});
|
||||
auto pos = actor->getPosition();
|
||||
Vec3 result = pos;
|
||||
int actorDimensionId = actor->getDimensionId();
|
||||
switch (DimensionId) {
|
||||
case TeleportDimensionCommand::DimensionType::OverWorld:
|
||||
if (actorDimensionId == 1)
|
||||
result = {pos.x * 8, pos.y, pos.z * 8};
|
||||
break;
|
||||
case TeleportDimensionCommand::DimensionType::Nether:
|
||||
if (actorDimensionId != 1)
|
||||
result = {pos.x / 8, pos.y, pos.z / 8};
|
||||
break;
|
||||
case TeleportDimensionCommand::DimensionType::TheEnd:
|
||||
if (actorDimensionId != 2)
|
||||
result = {100, 50, 0};
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool teleportTarget(CommandOrigin const& ori, CommandOutput& output, Actor* actor) const {
|
||||
auto dim = VanillaDimensions::toString((int)DimensionId);
|
||||
auto pos = getTargetPos(ori, actor);
|
||||
actor->teleport(pos, (int)DimensionId);
|
||||
output.trSuccess("ll.cmd.tpdim.success", actor->getNameTag(), dim, pos.x, pos.y, pos.z);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool teleportTargets(CommandOrigin const& ori, CommandOutput& output, CommandSelectorResults<Actor>& actors) const {
|
||||
auto dim = VanillaDimensions::toString((int)DimensionId);
|
||||
std::string names;
|
||||
for (auto& actor : actors) {
|
||||
std::string actorName = actor->getNameTag();
|
||||
if (actorName.empty()) {
|
||||
actorName = actor->getTypeName();
|
||||
}
|
||||
names.append(", ").append(actorName);
|
||||
if (actor->teleport(getTargetPos(ori, actor), (int)DimensionId)) {
|
||||
output.success();
|
||||
}
|
||||
}
|
||||
if (output.getSuccessCount() == 0) {
|
||||
output.trError("ll.cmd.tpdim.error.noActorTeleported");
|
||||
return false;
|
||||
} else {
|
||||
std::string message = fmt::format("Teleported {} to {}", names.substr(2), dim);
|
||||
if (CommandPos_isSet) {
|
||||
auto pos = CommandPos.getPosition(ori, {0, 0, 0});
|
||||
message.append(fmt::format(" ({:2f}, {:2f}, {:2f})", pos.x, pos.y, pos.z));
|
||||
}
|
||||
output.addMessage(message);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
void execute(CommandOrigin const& ori, CommandOutput& output) const override {
|
||||
output.setLanguageCode(ori);
|
||||
if ((int)DimensionId < 0 || (int)DimensionId > 2) {
|
||||
output.trError("ll.cmd.tpdim.invalidDimid", (int)DimensionId);
|
||||
return;
|
||||
}
|
||||
if (Victim_isSet) {
|
||||
auto result = Victim.results(ori);
|
||||
if (result.empty())
|
||||
output.trError("ll.cmd.tpdim.error.noActorSpecified");
|
||||
else if (result.count() == 1)
|
||||
teleportTarget(ori, output, *result.begin());
|
||||
else
|
||||
teleportTargets(ori, output, result);
|
||||
} else {
|
||||
auto actor = ori.getEntity();
|
||||
if (!actor)
|
||||
output.trError("ll.cmd.tpdim.error.noActorSpecified");
|
||||
else
|
||||
teleportTarget(ori, output, actor);
|
||||
}
|
||||
}
|
||||
|
||||
static void setup(CommandRegistry* registry) {
|
||||
registry->registerCommand(
|
||||
"tpdim", "Teleport to Dimension", CommandPermissionLevel::GameMasters,
|
||||
{(CommandFlagValue)0}, {(CommandFlagValue)0x80});
|
||||
registry->addEnum<DimensionType>("DimensionType",
|
||||
{
|
||||
{"overworld", DimensionType::OverWorld},
|
||||
{"o", DimensionType::OverWorld},
|
||||
{"nether", DimensionType::Nether},
|
||||
{"n", DimensionType::Nether},
|
||||
{"end", DimensionType::TheEnd},
|
||||
{"e", DimensionType::TheEnd},
|
||||
});
|
||||
auto dimensionTypeParam = makeMandatory<CommandParameterDataType::ENUM>(&TeleportDimensionCommand::DimensionId,
|
||||
"Dimension", "DimensionType");
|
||||
auto dimensionIdParam = makeMandatory((int TeleportDimensionCommand::*)&TeleportDimensionCommand::DimensionId,
|
||||
"DimensionId");
|
||||
auto victimParam = makeMandatory(&TeleportDimensionCommand::Victim, "victim",
|
||||
&TeleportDimensionCommand::Victim_isSet);
|
||||
auto positionParam = makeOptional(&TeleportDimensionCommand::CommandPos,
|
||||
"Position", &TeleportDimensionCommand::CommandPos_isSet);
|
||||
|
||||
registry->registerOverload<TeleportDimensionCommand>(
|
||||
"tpdim", victimParam, dimensionTypeParam, positionParam);
|
||||
registry->registerOverload<TeleportDimensionCommand>(
|
||||
"tpdim", victimParam, dimensionIdParam, positionParam);
|
||||
// registry->registerOverload<TeleportDimensionCommand>(
|
||||
// "tpdim", dimensionTypeParam, positionParam);
|
||||
registry->registerOverload<TeleportDimensionCommand>(
|
||||
"tpdim", dimensionIdParam, positionParam);
|
||||
}
|
||||
};
|
||||
|
||||
void LLListPluginsCommand(CommandOutput& output) {
|
||||
auto plugins = LL::getAllPlugins();
|
||||
output.trSuccess("ll.cmd.listPlugin.overview", plugins.size());
|
||||
|
||||
std::ostringstream oss;
|
||||
for (auto& [name, plugin] : plugins) {
|
||||
string pluginName = name;
|
||||
if (pluginName.find("§") == string::npos)
|
||||
pluginName = "§b" + pluginName;
|
||||
string desc = plugin->desc;
|
||||
if (desc.find("§") == string::npos)
|
||||
desc = "§7" + desc;
|
||||
|
||||
auto fileName = UTF82String(std::filesystem::path(str2wstr(plugin->filePath)).filename().u8string());
|
||||
oss << fmt::format("- {} §a[v{}] §8({})\n {}\n",
|
||||
pluginName, plugin->version.toString(), fileName, desc);
|
||||
}
|
||||
output.success(oss.str() + '\n');
|
||||
output.trAddMessage("ll.cmd.listPlugin.tip");
|
||||
}
|
||||
|
||||
void LLPluginInfoCommand(CommandOutput& output, const string& pluginName) {
|
||||
auto plugin = LL::getPlugin(pluginName);
|
||||
if (plugin) {
|
||||
std::map<std::string, std::string> outs;
|
||||
std::ostringstream oss;
|
||||
auto fn = UTF82String(std::filesystem::path(str2wstr(plugin->filePath)).filename().u8string());
|
||||
string pluginType = plugin->type == Plugin::PluginType::ScriptPlugin ? "Script Plugin" : "DLL Plugin";
|
||||
|
||||
output.trAddMessage("ll.cmd.pluginInfo.title", pluginName);
|
||||
|
||||
outs.emplace("Name", fmt::format("{} ({})", plugin->name, fn));
|
||||
outs.emplace("Description", plugin->desc);
|
||||
outs.emplace("Version", "v" + plugin->version.toString(true));
|
||||
outs.emplace("Type", pluginType);
|
||||
outs.emplace("File Path", plugin->filePath);
|
||||
outs.merge(plugin->others);
|
||||
size_t width = 10;
|
||||
for (auto& [k, _] : outs)
|
||||
width = std::max(width, k.length());
|
||||
for (auto& [k, v] : outs) {
|
||||
if (k != "PluginType" && k != "PluginFilePath")
|
||||
oss << "- §l" << std::setw(width) << std::left << k << "§r: " << v << std::endl;
|
||||
}
|
||||
auto text = oss.str();
|
||||
text.pop_back();
|
||||
output.success(text, {});
|
||||
} else {
|
||||
output.trError("ll.cmd.pluginInfo.error.pluginNotFound", pluginName);
|
||||
}
|
||||
}
|
||||
|
||||
void LLVersionCommand(CommandOutput& output) {
|
||||
output.trSuccess("ll.cmd.version.msg", LL::getBdsVersion(), LL::getLoaderVersionString(), LL::getServerProtocolVersion());
|
||||
}
|
||||
|
||||
void LLHelpCommand(CommandOutput& output) {
|
||||
output.trSuccess("ll.cmd.help.msg");
|
||||
}
|
||||
|
||||
void LLLoadPluginCommand(CommandOutput& output, const string& path) {
|
||||
// if (!LL::isDebugMode())
|
||||
// return;
|
||||
if (PluginManager::loadPlugin(path, true)) {
|
||||
output.trSuccess("ll.cmd.loadPlugin.success", path);
|
||||
} else {
|
||||
output.trError("ll.cmd.loadPlugin.fail", path);
|
||||
}
|
||||
}
|
||||
|
||||
void LLUnloadPluginCommand(CommandOutput& output, const string& pluginName) {
|
||||
// if (!LL::isDebugMode())
|
||||
// return;
|
||||
if (PluginManager::unloadPlugin(pluginName, true)) {
|
||||
output.trSuccess("ll.cmd.unloadPlugin.success", pluginName);
|
||||
} else {
|
||||
output.trError("ll.cmd.unloadPlugin.fail", pluginName);
|
||||
}
|
||||
}
|
||||
|
||||
void LLReloadPluginCommand(CommandOutput& output, const string& pluginName, bool reloadAll) {
|
||||
// if (!LL::isDebugMode())
|
||||
// return;
|
||||
if (!reloadAll) {
|
||||
if (PluginManager::reloadPlugin(pluginName, true)) {
|
||||
output.trSuccess("ll.cmd.reloadPlugin.success", pluginName);
|
||||
} else {
|
||||
output.trError("ll.cmd.reloadPlugin.fail", pluginName);
|
||||
}
|
||||
} else {
|
||||
int cnt = PluginManager::reloadAllPlugins(true);
|
||||
if (cnt > 0) {
|
||||
output.trSuccess("ll.cmd.reloadAllPlugins.success", cnt);
|
||||
} else {
|
||||
output.trError("ll.cmd.reloadAllPlugins.fail");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class LLCommand : public Command {
|
||||
|
||||
enum class Operation {
|
||||
Version,
|
||||
List,
|
||||
Help,
|
||||
Load,
|
||||
Unload,
|
||||
Reload
|
||||
};
|
||||
|
||||
Operation operation;
|
||||
bool hasUpgradeOption, hasPluginNameSet;
|
||||
CommandRawText pluginNameToDoOperation;
|
||||
|
||||
public:
|
||||
void execute(CommandOrigin const& ori, CommandOutput& output) const override {
|
||||
output.setLanguageCode(ori);
|
||||
std::string pluginName = "";
|
||||
if (hasPluginNameSet) {
|
||||
pluginName = pluginNameToDoOperation;
|
||||
if (pluginName.size() > 1 && pluginName[0] == '"' && pluginName[pluginName.size() - 1] == '"' && pluginName[pluginName.size() - 2] != '\\') {
|
||||
pluginName.erase(0, 1);
|
||||
pluginName.pop_back();
|
||||
}
|
||||
}
|
||||
switch (operation) {
|
||||
case Operation::Version:
|
||||
LLVersionCommand(output);
|
||||
break;
|
||||
case Operation::List:
|
||||
if (!hasPluginNameSet)
|
||||
LLListPluginsCommand(output);
|
||||
else
|
||||
LLPluginInfoCommand(output, pluginName);
|
||||
break;
|
||||
case Operation::Load:
|
||||
if (hasPluginNameSet)
|
||||
LLLoadPluginCommand(output, pluginName);
|
||||
else
|
||||
output.trError("ll.cmd.error.noPathSpecified");
|
||||
break;
|
||||
case Operation::Unload:
|
||||
if (hasPluginNameSet)
|
||||
LLUnloadPluginCommand(output, pluginName);
|
||||
else
|
||||
output.trError("ll.cmd.error.noNameSpecified");
|
||||
break;
|
||||
case Operation::Reload:
|
||||
if (hasPluginNameSet)
|
||||
LLReloadPluginCommand(output, pluginName, false);
|
||||
else
|
||||
LLReloadPluginCommand(output, "", true);
|
||||
break;
|
||||
case Operation::Help:
|
||||
LLHelpCommand(output);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void setup(CommandRegistry* registry) {
|
||||
// Register Cmd
|
||||
registry->registerCommand("ll", "LiteLoaderBDS plugin operations",
|
||||
CommandPermissionLevel::Console, {(CommandFlagValue)0}, {(CommandFlagValue)0x80});
|
||||
|
||||
// Register softenum
|
||||
vector<string> pluginList;
|
||||
for (auto& [name, p] : LL::getAllPlugins()) {
|
||||
pluginList.push_back(name);
|
||||
}
|
||||
registry->addSoftEnum("PluginName", pluginList);
|
||||
|
||||
// ll version & help
|
||||
registry->addEnum<Operation>("Operation_Common", {{"version", Operation::Version},
|
||||
{"help", Operation::Help}});
|
||||
registry->registerOverload<LLCommand>(
|
||||
"ll",
|
||||
makeMandatory<CommandParameterDataType::ENUM>(&LLCommand::operation, "Operation", "Operation_Common").addOptions((CommandParameterOption)1));
|
||||
|
||||
// ll load
|
||||
registry->addEnum<Operation>("Operation_FreeFilePath", {
|
||||
{"load", Operation::Load},
|
||||
});
|
||||
registry->registerOverload<LLCommand>(
|
||||
"ll",
|
||||
makeMandatory<CommandParameterDataType::ENUM>(&LLCommand::operation, "Operation", "Operation_FreeFilePath").addOptions((CommandParameterOption)1),
|
||||
makeMandatory<CommandParameterDataType::NORMAL>(&LLCommand::pluginNameToDoOperation, "pluginPath", nullptr, &LLCommand::hasPluginNameSet));
|
||||
|
||||
// ll unload
|
||||
registry->addEnum<Operation>("Operation_MustPluginName", {
|
||||
{"unload", Operation::Unload},
|
||||
});
|
||||
registry->registerOverload<LLCommand>(
|
||||
"ll",
|
||||
makeMandatory<CommandParameterDataType::ENUM>(&LLCommand::operation, "Operation", "Operation_MustPluginName").addOptions((CommandParameterOption)1),
|
||||
makeMandatory<CommandParameterDataType::SOFT_ENUM>((std::string LLCommand::*)&LLCommand::pluginNameToDoOperation, "pluginName", "PluginName", &LLCommand::hasPluginNameSet));
|
||||
|
||||
// ll list & reload
|
||||
registry->addEnum<Operation>("Operation_OptionalPluginName", {
|
||||
{"list", Operation::List},
|
||||
{"plugins", Operation::List},
|
||||
{"reload", Operation::Reload},
|
||||
});
|
||||
registry->registerOverload<LLCommand>(
|
||||
"ll",
|
||||
makeMandatory<CommandParameterDataType::ENUM>(&LLCommand::operation, "Operation", "Operation_OptionalPluginName").addOptions((CommandParameterOption)1),
|
||||
makeOptional<CommandParameterDataType::SOFT_ENUM>((std::string LLCommand::*)&LLCommand::pluginNameToDoOperation, "pluginName", "PluginName", &LLCommand::hasPluginNameSet));
|
||||
}
|
||||
};
|
||||
|
||||
class VersionCommand : public Command {
|
||||
|
||||
public:
|
||||
void execute(CommandOrigin const& ori, CommandOutput& output) const override {
|
||||
output.setLanguageCode(ori);
|
||||
#ifdef DEBUG
|
||||
Logger("CommandOrigin").warn(ori.serialize().toSNBT());
|
||||
#endif // DEBUG
|
||||
LLVersionCommand(output);
|
||||
}
|
||||
|
||||
static void setup(CommandRegistry* registry) {
|
||||
registry->registerCommand("version", "Get the version of this server",
|
||||
CommandPermissionLevel::GameMasters, {(CommandFlagValue)0}, {(CommandFlagValue)0x80});
|
||||
registry->registerOverload<VersionCommand>("version");
|
||||
}
|
||||
};
|
||||
|
||||
void RegisterCommands() {
|
||||
Event::RegCmdEvent::subscribe([](Event::RegCmdEvent ev) { // Register commands
|
||||
LLCommand::setup(ev.mCommandRegistry);
|
||||
VersionCommand::setup(ev.mCommandRegistry);
|
||||
if (LL::globalConfig.enableTpdimCommand) {
|
||||
TeleportDimensionCommand::setup(ev.mCommandRegistry);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
//#include <filesystem>
|
||||
//#include <EventAPI.h>
|
||||
//#include <LLAPI.h>
|
||||
//#include <ServerAPI.h>
|
||||
//#include <RegCommandAPI.h>
|
||||
//#include <MC/CommandOrigin.hpp>
|
||||
//#include <MC/CommandOutput.hpp>
|
||||
//#include <MC/CommandPosition.hpp>
|
||||
//#include <MC/CommandRegistry.hpp>
|
||||
//#include <MC/Packet.hpp>
|
||||
//#include <MC/ServerPlayer.hpp>
|
||||
//#include <MC/VanillaDimensions.hpp>
|
||||
//#include <Main/Config.h>
|
||||
//#include <Main/PluginManager.h>
|
||||
//#include "../ScriptEngine/Main/Configs.h"
|
||||
//
|
||||
//using namespace RegisterCommandHelper;
|
||||
//using namespace LL;
|
||||
//
|
||||
//static_assert(sizeof(CommandSelector<Player>) == 200);
|
||||
//
|
||||
//class TeleportDimensionCommand : public Command {
|
||||
//
|
||||
// enum class DimensionType {
|
||||
// OverWorld,
|
||||
// Nether,
|
||||
// TheEnd,
|
||||
// } DimensionId;
|
||||
// CommandSelector<Actor> Victim;
|
||||
// CommandPosition CommandPos;
|
||||
// bool Victim_isSet = false;
|
||||
// bool CommandPos_isSet = false;
|
||||
//
|
||||
// Vec3 getTargetPos(CommandOrigin const& ori, Actor* actor) const {
|
||||
// if (CommandPos_isSet)
|
||||
// return CommandPos.getPosition(ori, {0, 0, 0});
|
||||
// auto pos = actor->getPosition();
|
||||
// Vec3 result = pos;
|
||||
// int actorDimensionId = actor->getDimensionId();
|
||||
// switch (DimensionId) {
|
||||
// case TeleportDimensionCommand::DimensionType::OverWorld:
|
||||
// if (actorDimensionId == 1)
|
||||
// result = {pos.x * 8, pos.y, pos.z * 8};
|
||||
// break;
|
||||
// case TeleportDimensionCommand::DimensionType::Nether:
|
||||
// if (actorDimensionId != 1)
|
||||
// result = {pos.x / 8, pos.y, pos.z / 8};
|
||||
// break;
|
||||
// case TeleportDimensionCommand::DimensionType::TheEnd:
|
||||
// if (actorDimensionId != 2)
|
||||
// result = {100, 50, 0};
|
||||
// break;
|
||||
// default:
|
||||
// break;
|
||||
// }
|
||||
// return result;
|
||||
// }
|
||||
//
|
||||
// bool teleportTarget(CommandOrigin const& ori, CommandOutput& output, Actor* actor) const {
|
||||
// auto dim = VanillaDimensions::toString((int)DimensionId);
|
||||
// auto pos = getTargetPos(ori, actor);
|
||||
// actor->teleport(pos, (int)DimensionId);
|
||||
// output.trSuccess("ll.cmd.tpdim.success", actor->getNameTag(), dim, pos.x, pos.y, pos.z);
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// bool teleportTargets(CommandOrigin const& ori, CommandOutput& output, CommandSelectorResults<Actor>& actors) const {
|
||||
// auto dim = VanillaDimensions::toString((int)DimensionId);
|
||||
// std::string names;
|
||||
// for (auto& actor : actors) {
|
||||
// std::string actorName = actor->getNameTag();
|
||||
// if (actorName.empty()) {
|
||||
// actorName = actor->getTypeName();
|
||||
// }
|
||||
// names.append(", ").append(actorName);
|
||||
// if (actor->teleport(getTargetPos(ori, actor), (int)DimensionId)) {
|
||||
// output.success();
|
||||
// }
|
||||
// }
|
||||
// if (output.getSuccessCount() == 0) {
|
||||
// output.trError("ll.cmd.tpdim.error.noActorTeleported");
|
||||
// return false;
|
||||
// } else {
|
||||
// std::string message = fmt::format("Teleported {} to {}", names.substr(2), dim);
|
||||
// if (CommandPos_isSet) {
|
||||
// auto pos = CommandPos.getPosition(ori, {0, 0, 0});
|
||||
// message.append(fmt::format(" ({:2f}, {:2f}, {:2f})", pos.x, pos.y, pos.z));
|
||||
// }
|
||||
// output.addMessage(message);
|
||||
// return true;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
//public:
|
||||
// void execute(CommandOrigin const& ori, CommandOutput& output) const override {
|
||||
// output.setLanguageCode(ori);
|
||||
// if ((int)DimensionId < 0 || (int)DimensionId > 2) {
|
||||
// output.trError("ll.cmd.tpdim.invalidDimid", (int)DimensionId);
|
||||
// return;
|
||||
// }
|
||||
// if (Victim_isSet) {
|
||||
// auto result = Victim.results(ori);
|
||||
// if (result.empty())
|
||||
// output.trError("ll.cmd.tpdim.error.noActorSpecified");
|
||||
// else if (result.count() == 1)
|
||||
// teleportTarget(ori, output, *result.begin());
|
||||
// else
|
||||
// teleportTargets(ori, output, result);
|
||||
// } else {
|
||||
// auto actor = ori.getEntity();
|
||||
// if (!actor)
|
||||
// output.trError("ll.cmd.tpdim.error.noActorSpecified");
|
||||
// else
|
||||
// teleportTarget(ori, output, actor);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// static void setup(CommandRegistry* registry) {
|
||||
// registry->registerCommand(
|
||||
// "tpdim", "Teleport to Dimension", CommandPermissionLevel::GameMasters,
|
||||
// {(CommandFlagValue)0}, {(CommandFlagValue)0x80});
|
||||
// registry->addEnum<DimensionType>("DimensionType",
|
||||
// {
|
||||
// {"overworld", DimensionType::OverWorld},
|
||||
// {"o", DimensionType::OverWorld},
|
||||
// {"nether", DimensionType::Nether},
|
||||
// {"n", DimensionType::Nether},
|
||||
// {"end", DimensionType::TheEnd},
|
||||
// {"e", DimensionType::TheEnd},
|
||||
// });
|
||||
// auto dimensionTypeParam = makeMandatory<CommandParameterDataType::ENUM>(&TeleportDimensionCommand::DimensionId,
|
||||
// "Dimension", "DimensionType");
|
||||
// auto dimensionIdParam = makeMandatory((int TeleportDimensionCommand::*)&TeleportDimensionCommand::DimensionId,
|
||||
// "DimensionId");
|
||||
// auto victimParam = makeMandatory(&TeleportDimensionCommand::Victim, "victim",
|
||||
// &TeleportDimensionCommand::Victim_isSet);
|
||||
// auto positionParam = makeOptional(&TeleportDimensionCommand::CommandPos,
|
||||
// "Position", &TeleportDimensionCommand::CommandPos_isSet);
|
||||
//
|
||||
// registry->registerOverload<TeleportDimensionCommand>(
|
||||
// "tpdim", victimParam, dimensionTypeParam, positionParam);
|
||||
// registry->registerOverload<TeleportDimensionCommand>(
|
||||
// "tpdim", victimParam, dimensionIdParam, positionParam);
|
||||
// // registry->registerOverload<TeleportDimensionCommand>(
|
||||
// // "tpdim", dimensionTypeParam, positionParam);
|
||||
// registry->registerOverload<TeleportDimensionCommand>(
|
||||
// "tpdim", dimensionIdParam, positionParam);
|
||||
// }
|
||||
//};
|
||||
//
|
||||
//void LLListPluginsCommand(CommandOutput& output) {
|
||||
// auto plugins = LL::getAllPlugins();
|
||||
// output.trSuccess("ll.cmd.listPlugin.overview", plugins.size());
|
||||
//
|
||||
// std::ostringstream oss;
|
||||
// for (auto& [name, plugin] : plugins) {
|
||||
// string pluginName = name;
|
||||
// if (pluginName.find("§") == string::npos)
|
||||
// pluginName = "§b" + pluginName;
|
||||
// string desc = plugin->desc;
|
||||
// if (desc.find("§") == string::npos)
|
||||
// desc = "§7" + desc;
|
||||
//
|
||||
// auto fileName = UTF82String(std::filesystem::path(str2wstr(plugin->filePath)).filename().u8string());
|
||||
// oss << fmt::format("- {} §a[v{}] §8({})\n {}\n",
|
||||
// pluginName, plugin->version.toString(), fileName, desc);
|
||||
// }
|
||||
// output.success(oss.str() + '\n');
|
||||
// output.trAddMessage("ll.cmd.listPlugin.tip");
|
||||
//}
|
||||
//
|
||||
//void LLPluginInfoCommand(CommandOutput& output, const string& pluginName) {
|
||||
// auto plugin = LL::getPlugin(pluginName);
|
||||
// if (plugin) {
|
||||
// std::map<std::string, std::string> outs;
|
||||
// std::ostringstream oss;
|
||||
// auto fn = UTF82String(std::filesystem::path(str2wstr(plugin->filePath)).filename().u8string());
|
||||
// string pluginType = plugin->type == Plugin::PluginType::ScriptPlugin ? "Script Plugin" : "DLL Plugin";
|
||||
//
|
||||
// output.trAddMessage("ll.cmd.pluginInfo.title", pluginName);
|
||||
//
|
||||
// outs.emplace("Name", fmt::format("{} ({})", plugin->name, fn));
|
||||
// outs.emplace("Description", plugin->desc);
|
||||
// outs.emplace("Version", "v" + plugin->version.toString(true));
|
||||
// outs.emplace("Type", pluginType);
|
||||
// outs.emplace("File Path", plugin->filePath);
|
||||
// outs.merge(plugin->others);
|
||||
// size_t width = 10;
|
||||
// for (auto& [k, _] : outs)
|
||||
// width = std::max(width, k.length());
|
||||
// for (auto& [k, v] : outs) {
|
||||
// if (k != "PluginType" && k != "PluginFilePath")
|
||||
// oss << "- §l" << std::setw(width) << std::left << k << "§r: " << v << std::endl;
|
||||
// }
|
||||
// auto text = oss.str();
|
||||
// text.pop_back();
|
||||
// output.success(text, {});
|
||||
// } else {
|
||||
// output.trError("ll.cmd.pluginInfo.error.pluginNotFound", pluginName);
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//void LLVersionCommand(CommandOutput& output) {
|
||||
// output.trSuccess("ll.cmd.version.msg", LL::getBdsVersion(), LL::getLoaderVersionString(), LL::getServerProtocolVersion());
|
||||
//}
|
||||
//
|
||||
//void LLHelpCommand(CommandOutput& output) {
|
||||
// output.trSuccess("ll.cmd.help.msg");
|
||||
//}
|
||||
//
|
||||
//void LLLoadPluginCommand(CommandOutput& output, const string& path) {
|
||||
// // if (!LL::isDebugMode())
|
||||
// // return;
|
||||
// if (PluginManager::loadPlugin(path, true)) {
|
||||
// output.trSuccess("ll.cmd.loadPlugin.success", path);
|
||||
// } else {
|
||||
// output.trError("ll.cmd.loadPlugin.fail", path);
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//void LLUnloadPluginCommand(CommandOutput& output, const string& pluginName) {
|
||||
// // if (!LL::isDebugMode())
|
||||
// // return;
|
||||
// if (PluginManager::unloadPlugin(pluginName, true)) {
|
||||
// output.trSuccess("ll.cmd.unloadPlugin.success", pluginName);
|
||||
// } else {
|
||||
// output.trError("ll.cmd.unloadPlugin.fail", pluginName);
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//void LLReloadPluginCommand(CommandOutput& output, const string& pluginName, bool reloadAll) {
|
||||
// // if (!LL::isDebugMode())
|
||||
// // return;
|
||||
// if (!reloadAll) {
|
||||
// if (PluginManager::reloadPlugin(pluginName, true)) {
|
||||
// output.trSuccess("ll.cmd.reloadPlugin.success", pluginName);
|
||||
// } else {
|
||||
// output.trError("ll.cmd.reloadPlugin.fail", pluginName);
|
||||
// }
|
||||
// } else {
|
||||
// int cnt = PluginManager::reloadAllPlugins(true);
|
||||
// if (cnt > 0) {
|
||||
// output.trSuccess("ll.cmd.reloadAllPlugins.success", cnt);
|
||||
// } else {
|
||||
// output.trError("ll.cmd.reloadAllPlugins.fail");
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//class LLCommand : public Command {
|
||||
//
|
||||
// enum class Operation {
|
||||
// Version,
|
||||
// List,
|
||||
// Help,
|
||||
// Load,
|
||||
// Unload,
|
||||
// Reload
|
||||
// };
|
||||
//
|
||||
// Operation operation;
|
||||
// bool hasUpgradeOption, hasPluginNameSet;
|
||||
// CommandRawText pluginNameToDoOperation;
|
||||
//
|
||||
//public:
|
||||
// void execute(CommandOrigin const& ori, CommandOutput& output) const override {
|
||||
// output.setLanguageCode(ori);
|
||||
// std::string pluginName = "";
|
||||
// if (hasPluginNameSet) {
|
||||
// pluginName = pluginNameToDoOperation;
|
||||
// if (pluginName.size() > 1 && pluginName[0] == '"' && pluginName[pluginName.size() - 1] == '"' && pluginName[pluginName.size() - 2] != '\\') {
|
||||
// pluginName.erase(0, 1);
|
||||
// pluginName.pop_back();
|
||||
// }
|
||||
// }
|
||||
// switch (operation) {
|
||||
// case Operation::Version:
|
||||
// LLVersionCommand(output);
|
||||
// break;
|
||||
// case Operation::List:
|
||||
// if (!hasPluginNameSet)
|
||||
// LLListPluginsCommand(output);
|
||||
// else
|
||||
// LLPluginInfoCommand(output, pluginName);
|
||||
// break;
|
||||
// case Operation::Load:
|
||||
// if (hasPluginNameSet)
|
||||
// LLLoadPluginCommand(output, pluginName);
|
||||
// else
|
||||
// output.trError("ll.cmd.error.noPathSpecified");
|
||||
// break;
|
||||
// case Operation::Unload:
|
||||
// if (hasPluginNameSet)
|
||||
// LLUnloadPluginCommand(output, pluginName);
|
||||
// else
|
||||
// output.trError("ll.cmd.error.noNameSpecified");
|
||||
// break;
|
||||
// case Operation::Reload:
|
||||
// if (hasPluginNameSet)
|
||||
// LLReloadPluginCommand(output, pluginName, false);
|
||||
// else
|
||||
// LLReloadPluginCommand(output, "", true);
|
||||
// break;
|
||||
// case Operation::Help:
|
||||
// LLHelpCommand(output);
|
||||
// break;
|
||||
// default:
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// static void setup(CommandRegistry* registry) {
|
||||
// // Register Cmd
|
||||
// registry->registerCommand("ll", "LiteLoaderBDS plugin operations",
|
||||
// CommandPermissionLevel::Console, {(CommandFlagValue)0}, {(CommandFlagValue)0x80});
|
||||
//
|
||||
// // Register softenum
|
||||
// vector<string> pluginList;
|
||||
// for (auto& [name, p] : LL::getAllPlugins()) {
|
||||
// pluginList.push_back(name);
|
||||
// }
|
||||
// registry->addSoftEnum("PluginName", pluginList);
|
||||
//
|
||||
// // ll version & help
|
||||
// registry->addEnum<Operation>("Operation_Common", {{"version", Operation::Version},
|
||||
// {"help", Operation::Help}});
|
||||
// registry->registerOverload<LLCommand>(
|
||||
// "ll",
|
||||
// makeMandatory<CommandParameterDataType::ENUM>(&LLCommand::operation, "Operation", "Operation_Common").addOptions((CommandParameterOption)1));
|
||||
//
|
||||
// // ll load
|
||||
// registry->addEnum<Operation>("Operation_FreeFilePath", {
|
||||
// {"load", Operation::Load},
|
||||
// });
|
||||
// registry->registerOverload<LLCommand>(
|
||||
// "ll",
|
||||
// makeMandatory<CommandParameterDataType::ENUM>(&LLCommand::operation, "Operation", "Operation_FreeFilePath").addOptions((CommandParameterOption)1),
|
||||
// makeMandatory<CommandParameterDataType::NORMAL>(&LLCommand::pluginNameToDoOperation, "pluginPath", nullptr, &LLCommand::hasPluginNameSet));
|
||||
//
|
||||
// // ll unload
|
||||
// registry->addEnum<Operation>("Operation_MustPluginName", {
|
||||
// {"unload", Operation::Unload},
|
||||
// });
|
||||
// registry->registerOverload<LLCommand>(
|
||||
// "ll",
|
||||
// makeMandatory<CommandParameterDataType::ENUM>(&LLCommand::operation, "Operation", "Operation_MustPluginName").addOptions((CommandParameterOption)1),
|
||||
// makeMandatory<CommandParameterDataType::SOFT_ENUM>((std::string LLCommand::*)&LLCommand::pluginNameToDoOperation, "pluginName", "PluginName", &LLCommand::hasPluginNameSet));
|
||||
//
|
||||
// // ll list & reload
|
||||
// registry->addEnum<Operation>("Operation_OptionalPluginName", {
|
||||
// {"list", Operation::List},
|
||||
// {"plugins", Operation::List},
|
||||
// {"reload", Operation::Reload},
|
||||
// });
|
||||
// registry->registerOverload<LLCommand>(
|
||||
// "ll",
|
||||
// makeMandatory<CommandParameterDataType::ENUM>(&LLCommand::operation, "Operation", "Operation_OptionalPluginName").addOptions((CommandParameterOption)1),
|
||||
// makeOptional<CommandParameterDataType::SOFT_ENUM>((std::string LLCommand::*)&LLCommand::pluginNameToDoOperation, "pluginName", "PluginName", &LLCommand::hasPluginNameSet));
|
||||
// }
|
||||
//};
|
||||
//
|
||||
//class VersionCommand : public Command {
|
||||
//
|
||||
//public:
|
||||
// void execute(CommandOrigin const& ori, CommandOutput& output) const override {
|
||||
// output.setLanguageCode(ori);
|
||||
//#ifdef DEBUG
|
||||
// Logger("CommandOrigin").warn(ori.serialize().toSNBT());
|
||||
//#endif // DEBUG
|
||||
// LLVersionCommand(output);
|
||||
// }
|
||||
//
|
||||
// static void setup(CommandRegistry* registry) {
|
||||
// registry->registerCommand("version", "Get the version of this server",
|
||||
// CommandPermissionLevel::GameMasters, {(CommandFlagValue)0}, {(CommandFlagValue)0x80});
|
||||
// registry->registerOverload<VersionCommand>("version");
|
||||
// }
|
||||
//};
|
||||
//
|
||||
//void RegisterCommands() {
|
||||
// Event::RegCmdEvent::subscribe([](Event::RegCmdEvent ev) { // Register commands
|
||||
// LLCommand::setup(ev.mCommandRegistry);
|
||||
// VersionCommand::setup(ev.mCommandRegistry);
|
||||
// if (LL::globalConfig.enableTpdimCommand) {
|
||||
// TeleportDimensionCommand::setup(ev.mCommandRegistry);
|
||||
// }
|
||||
// return true;
|
||||
// });
|
||||
//}
|
||||
|
@ -1,102 +1,102 @@
|
||||
#include "Global.h"
|
||||
#include <Main/Config.h>
|
||||
#include <MC/CommandParameterData.hpp>
|
||||
#include <LoggerAPI.h>
|
||||
/////////////////// Built in UnlockCmd ///////////////////
|
||||
|
||||
bool isUnlockCmdEnabled = true;
|
||||
|
||||
// ==> LiteLoader/Main/SimpleServerLogger.cpp
|
||||
void LogCommandRegistration(std::string const& name, char const* description, enum CommandPermissionLevel perm, short flag1, short flag2);
|
||||
|
||||
TInstanceHook(void, "?registerCommand@CommandRegistry@@QEAAXAEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@PEBDW4CommandPermissionLevel@@UCommandFlag@@3@Z",
|
||||
CommandRegistry, std::string const& name, char const* description, enum CommandPermissionLevel perm, short flag1, short flag2) {
|
||||
// For #643
|
||||
if (name.find(' ') == std::string::npos) { // If no space inside
|
||||
// Check whether command is already exists before registering
|
||||
if (this->findCommand(name)) {
|
||||
// throw to prevent setup function, then this exception can be caught by event handler
|
||||
throw std::runtime_error("There is already a command named " + name);
|
||||
}
|
||||
}
|
||||
if (LL::globalConfig.enableUnlockCmd) {
|
||||
flag1 |= 0x80;
|
||||
}
|
||||
if (LL::globalConfig.debugMode) {
|
||||
LogCommandRegistration(name, description, perm, flag1, flag2);
|
||||
}
|
||||
return original(this, name, description, perm, flag1, flag2);
|
||||
}
|
||||
|
||||
class CommandSelectorBase;
|
||||
class CommandOrigin;
|
||||
TClasslessInstanceHook(bool, "?isExpansionAllowed@CommandSelectorBase@@AEBA_NAEBVCommandOrigin@@@Z",
|
||||
CommandOrigin* a2) {
|
||||
if (LL::globalConfig.enableUnlockCmd) {
|
||||
original(this, a2);
|
||||
return true;
|
||||
}
|
||||
return original(this, a2);
|
||||
}
|
||||
|
||||
//#include <MC/AllowListCommand.hpp>
|
||||
//#include <MC/CommandVersion.hpp>
|
||||
//#include <MC/CommandRegistry.hpp>
|
||||
//#include "Global.h"
|
||||
//#include <Main/Config.h>
|
||||
//#include <MC/CommandParameterData.hpp>
|
||||
// inline void tryChangeStringToRawText(CommandParameterData& data)
|
||||
//{
|
||||
// if (false /* config.xxxx*/ && data.tid.value == type_id<CommandRegistry, std::string>().value)
|
||||
// {
|
||||
// data.tid = type_id<CommandRegistry, CommandRawText>();
|
||||
// data.parser = CommandRegistry::getParseFn<CommandRawText>();
|
||||
//#include <LoggerAPI.h>
|
||||
///////////////////// Built in UnlockCmd ///////////////////
|
||||
//
|
||||
//bool isUnlockCmdEnabled = true;
|
||||
//
|
||||
//// ==> LiteLoader/Main/SimpleServerLogger.cpp
|
||||
//void LogCommandRegistration(std::string const& name, char const* description, enum CommandPermissionLevel perm, short flag1, short flag2);
|
||||
//
|
||||
//TInstanceHook(void, "?registerCommand@CommandRegistry@@QEAAXAEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@PEBDW4CommandPermissionLevel@@UCommandFlag@@3@Z",
|
||||
// CommandRegistry, std::string const& name, char const* description, enum CommandPermissionLevel perm, short flag1, short flag2) {
|
||||
// // For #643
|
||||
// if (name.find(' ') == std::string::npos) { // If no space inside
|
||||
// // Check whether command is already exists before registering
|
||||
// if (this->findCommand(name)) {
|
||||
// // throw to prevent setup function, then this exception can be caught by event handler
|
||||
// throw std::runtime_error("There is already a command named " + name);
|
||||
// }
|
||||
// }
|
||||
// if (LL::globalConfig.enableUnlockCmd) {
|
||||
// flag1 |= 0x80;
|
||||
// }
|
||||
// if (LL::globalConfig.debugMode) {
|
||||
// LogCommandRegistration(name, description, perm, flag1, flag2);
|
||||
// }
|
||||
// return original(this, name, description, perm, flag1, flag2);
|
||||
//}
|
||||
//// allowlist
|
||||
// TInstanceHook(CommandRegistry::Overload*, "??$_registerOverload@VAllowListCommand@@VCommandParameterData@@V2@@CommandRegistry@@AEAAPEAUOverload@0@PEBDVCommandVersion@@AEBVCommandParameterData@@2@Z",
|
||||
// CommandRegistry, char const* unk, class CommandVersion version, class CommandParameterData const& operationParam, class CommandParameterData& nameParam)
|
||||
//{
|
||||
// tryChangeStringToRawText(nameParam);
|
||||
// return original(this, unk, version, operationParam, nameParam);
|
||||
// }
|
||||
//// op
|
||||
// TInstanceHook(CommandRegistry::Overload*, "??$_registerOverload@VOpCommand@@VCommandParameterData@@@CommandRegistry@@AEAAPEAUOverload@0@PEBDVCommandVersion@@AEBVCommandParameterData@@@Z",
|
||||
// CommandRegistry, char const* unk, class CommandVersion version, class CommandParameterData& nameParam)
|
||||
//{
|
||||
// tryChangeStringToRawText(nameParam);
|
||||
// return original(this, unk, version, nameParam);
|
||||
// }
|
||||
//// deop
|
||||
// TInstanceHook(CommandRegistry::Overload*, "??$_registerOverload@VDeOpCommand@@VCommandParameterData@@@CommandRegistry@@AEAAPEAUOverload@0@PEBDVCommandVersion@@AEBVCommandParameterData@@@Z",
|
||||
// CommandRegistry, char const* unk, class CommandVersion version, class CommandParameterData& nameParam)
|
||||
//{
|
||||
// tryChangeStringToRawText(nameParam);
|
||||
// return original(this, unk, version, nameParam);
|
||||
// }
|
||||
// bool unlockNewExecute = true;
|
||||
// TClasslessInstanceHook(bool, "?isEnabled@FeatureToggles@@QEBA_NW4FeatureOptionID@@@Z",
|
||||
// int feature)
|
||||
// {
|
||||
// if (feature == 54 && unlockNewExecute)
|
||||
// return true;
|
||||
// return original(this, feature);
|
||||
// }
|
||||
// TClasslessInstanceHook(void, "?addSemanticConstraint@CommandRegistry@@AEAAXW4SemanticConstraint@@@Z",
|
||||
// enum SemanticConstraint)
|
||||
//{
|
||||
// return;
|
||||
// }
|
||||
TClasslessInstanceHook(void, "?addEnumValueConstraints@CommandRegistry@@QEAAXAEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@AEBV?$vector@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V?$allocator@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@2@@3@W4SemanticConstraint@@@Z",
|
||||
std::string const& enumName, std::vector<std::string> const& enumValues, SemanticConstraint constraint) {
|
||||
if (!LL::globalConfig.enableUnlockCmd)
|
||||
return original(this, enumName, enumValues, constraint);
|
||||
if (constraint & SemanticConstraint::RequiresCheatsEnabled) {
|
||||
constraint = (SemanticConstraint)(constraint & (~SemanticConstraint::RequiresCheatsEnabled));
|
||||
constraint = (SemanticConstraint)(constraint | SemanticConstraint::RequiresElevatedPermissions);
|
||||
}
|
||||
// if (constraint & SemanticConstraint::RequiresHostPermissions)
|
||||
//{
|
||||
// constraint = (SemanticConstraint)(constraint & (~SemanticConstraint::RequiresHostPermissions));
|
||||
// constraint = (SemanticConstraint)(constraint | SemanticConstraint::RequiresElevatedPermissions);
|
||||
// }
|
||||
return original(this, enumName, enumValues, constraint);
|
||||
}
|
||||
//
|
||||
//class CommandSelectorBase;
|
||||
//class CommandOrigin;
|
||||
//TClasslessInstanceHook(bool, "?isExpansionAllowed@CommandSelectorBase@@AEBA_NAEBVCommandOrigin@@@Z",
|
||||
// CommandOrigin* a2) {
|
||||
// if (LL::globalConfig.enableUnlockCmd) {
|
||||
// original(this, a2);
|
||||
// return true;
|
||||
// }
|
||||
// return original(this, a2);
|
||||
//}
|
||||
//
|
||||
////#include <MC/AllowListCommand.hpp>
|
||||
////#include <MC/CommandVersion.hpp>
|
||||
////#include <MC/CommandRegistry.hpp>
|
||||
////#include <MC/CommandParameterData.hpp>
|
||||
//// inline void tryChangeStringToRawText(CommandParameterData& data)
|
||||
////{
|
||||
//// if (false /* config.xxxx*/ && data.tid.value == type_id<CommandRegistry, std::string>().value)
|
||||
//// {
|
||||
//// data.tid = type_id<CommandRegistry, CommandRawText>();
|
||||
//// data.parser = CommandRegistry::getParseFn<CommandRawText>();
|
||||
//// }
|
||||
////}
|
||||
////// allowlist
|
||||
//// TInstanceHook(CommandRegistry::Overload*, "??$_registerOverload@VAllowListCommand@@VCommandParameterData@@V2@@CommandRegistry@@AEAAPEAUOverload@0@PEBDVCommandVersion@@AEBVCommandParameterData@@2@Z",
|
||||
//// CommandRegistry, char const* unk, class CommandVersion version, class CommandParameterData const& operationParam, class CommandParameterData& nameParam)
|
||||
////{
|
||||
//// tryChangeStringToRawText(nameParam);
|
||||
//// return original(this, unk, version, operationParam, nameParam);
|
||||
//// }
|
||||
////// op
|
||||
//// TInstanceHook(CommandRegistry::Overload*, "??$_registerOverload@VOpCommand@@VCommandParameterData@@@CommandRegistry@@AEAAPEAUOverload@0@PEBDVCommandVersion@@AEBVCommandParameterData@@@Z",
|
||||
//// CommandRegistry, char const* unk, class CommandVersion version, class CommandParameterData& nameParam)
|
||||
////{
|
||||
//// tryChangeStringToRawText(nameParam);
|
||||
//// return original(this, unk, version, nameParam);
|
||||
//// }
|
||||
////// deop
|
||||
//// TInstanceHook(CommandRegistry::Overload*, "??$_registerOverload@VDeOpCommand@@VCommandParameterData@@@CommandRegistry@@AEAAPEAUOverload@0@PEBDVCommandVersion@@AEBVCommandParameterData@@@Z",
|
||||
//// CommandRegistry, char const* unk, class CommandVersion version, class CommandParameterData& nameParam)
|
||||
////{
|
||||
//// tryChangeStringToRawText(nameParam);
|
||||
//// return original(this, unk, version, nameParam);
|
||||
//// }
|
||||
//// bool unlockNewExecute = true;
|
||||
//// TClasslessInstanceHook(bool, "?isEnabled@FeatureToggles@@QEBA_NW4FeatureOptionID@@@Z",
|
||||
//// int feature)
|
||||
//// {
|
||||
//// if (feature == 54 && unlockNewExecute)
|
||||
//// return true;
|
||||
//// return original(this, feature);
|
||||
//// }
|
||||
//// TClasslessInstanceHook(void, "?addSemanticConstraint@CommandRegistry@@AEAAXW4SemanticConstraint@@@Z",
|
||||
//// enum SemanticConstraint)
|
||||
////{
|
||||
//// return;
|
||||
//// }
|
||||
//TClasslessInstanceHook(void, "?addEnumValueConstraints@CommandRegistry@@QEAAXAEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@AEBV?$vector@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V?$allocator@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@2@@3@W4SemanticConstraint@@@Z",
|
||||
// std::string const& enumName, std::vector<std::string> const& enumValues, SemanticConstraint constraint) {
|
||||
// if (!LL::globalConfig.enableUnlockCmd)
|
||||
// return original(this, enumName, enumValues, constraint);
|
||||
// if (constraint & SemanticConstraint::RequiresCheatsEnabled) {
|
||||
// constraint = (SemanticConstraint)(constraint & (~SemanticConstraint::RequiresCheatsEnabled));
|
||||
// constraint = (SemanticConstraint)(constraint | SemanticConstraint::RequiresElevatedPermissions);
|
||||
// }
|
||||
// // if (constraint & SemanticConstraint::RequiresHostPermissions)
|
||||
// //{
|
||||
// // constraint = (SemanticConstraint)(constraint & (~SemanticConstraint::RequiresHostPermissions));
|
||||
// // constraint = (SemanticConstraint)(constraint | SemanticConstraint::RequiresElevatedPermissions);
|
||||
// // }
|
||||
// return original(this, enumName, enumValues, constraint);
|
||||
//}
|
@ -196,34 +196,34 @@ void CheckProtocolVersion() {
|
||||
}
|
||||
}
|
||||
|
||||
BOOL WINAPI ConsoleExitHandler(DWORD CEvent) {
|
||||
switch (CEvent) {
|
||||
case CTRL_C_EVENT:
|
||||
case CTRL_CLOSE_EVENT:
|
||||
case CTRL_SHUTDOWN_EVENT: {
|
||||
if (Global<Minecraft>) {
|
||||
Global<Minecraft>->requestServerShutdown();
|
||||
} else {
|
||||
std::terminate();
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
//BOOL WINAPI ConsoleExitHandler(DWORD CEvent) {
|
||||
// switch (CEvent) {
|
||||
// case CTRL_C_EVENT:
|
||||
// case CTRL_CLOSE_EVENT:
|
||||
// case CTRL_SHUTDOWN_EVENT: {
|
||||
// if (Global<Minecraft>) {
|
||||
// Global<Minecraft>->requestServerShutdown();
|
||||
// } else {
|
||||
// std::terminate();
|
||||
// }
|
||||
// return TRUE;
|
||||
// }
|
||||
// }
|
||||
// return FALSE;
|
||||
//}
|
||||
|
||||
void UnixSignalHandler(int signum) {
|
||||
switch (signum) {
|
||||
case SIGINT:
|
||||
case SIGTERM: {
|
||||
if (Global<Minecraft>) {
|
||||
Global<Minecraft>->requestServerShutdown();
|
||||
} else {
|
||||
std::terminate();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//void UnixSignalHandler(int signum) {
|
||||
// switch (signum) {
|
||||
// case SIGINT:
|
||||
// case SIGTERM: {
|
||||
// if (Global<Minecraft>) {
|
||||
// Global<Minecraft>->requestServerShutdown();
|
||||
// } else {
|
||||
// std::terminate();
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
// extern
|
||||
extern void EndScheduleSystem();
|
||||
@ -294,9 +294,9 @@ void LLMain() {
|
||||
SetWindowText(hwnd, s.c_str());
|
||||
|
||||
// Register Exit Event Handler.
|
||||
SetConsoleCtrlHandler(ConsoleExitHandler, TRUE);
|
||||
signal(SIGTERM, UnixSignalHandler);
|
||||
signal(SIGINT, UnixSignalHandler);
|
||||
// SetConsoleCtrlHandler(ConsoleExitHandler, TRUE);
|
||||
// signal(SIGTERM, UnixSignalHandler);
|
||||
// signal(SIGINT, UnixSignalHandler);
|
||||
|
||||
// Welcome
|
||||
Welcome();
|
||||
@ -305,15 +305,15 @@ void LLMain() {
|
||||
CheckDevMode();
|
||||
|
||||
// Addon Helper
|
||||
if (LL::globalConfig.enableAddonsHelper) {
|
||||
InitAddonsHelper();
|
||||
}
|
||||
// if (LL::globalConfig.enableAddonsHelper) {
|
||||
// InitAddonsHelper();
|
||||
// }
|
||||
|
||||
// Load plugins
|
||||
LL::LoadMain();
|
||||
|
||||
// Register built-in commands
|
||||
RegisterCommands();
|
||||
//RegisterCommands();
|
||||
|
||||
// Register simple server logger
|
||||
RegisterSimpleServerLogger();
|
||||
|
@ -184,7 +184,7 @@ void LoadParticleAPI() {
|
||||
auto lib = LoadLibrary(str2wstr(path).c_str());
|
||||
if (lib) {
|
||||
logger.info(tr("ll.loader.loadParticleAPI.success"));
|
||||
ParticleCUI::init(lib);
|
||||
//ParticleCUI::init(lib);
|
||||
} else {
|
||||
logger.error("Fail to load ParticleAPI!");
|
||||
logger.error("Error: Code[{}] - {}", GetLastError(), GetLastErrorMessage());
|
||||
|
@ -79,50 +79,50 @@ THook(void, "?log@BedrockLog@@YAXW4LogCategory@1@V?$bitset@$02@std@@W4LogRule@1@
|
||||
return BedrockLog::log_va(a1, a2, a3, a4, a5, a6, a7, a8, va);
|
||||
}
|
||||
|
||||
#include <MC/ColorFormat.hpp>
|
||||
#include <MC/CommandOrigin.hpp>
|
||||
#include <MC/CommandOutput.hpp>
|
||||
extern std::unordered_map<CommandOrigin const*, string*> resultOfOrigin;
|
||||
TClasslessInstanceHook(void*, "?send@CommandOutputSender@@UEAAXAEBVCommandOrigin@@AEBVCommandOutput@@@Z",
|
||||
class CommandOrigin const& origin, class CommandOutput const& output) {
|
||||
std::stringbuf tmpBuf;
|
||||
auto oldBuf = std::cout.rdbuf();
|
||||
std::cout.rdbuf(&tmpBuf);
|
||||
auto rv = original(this, origin, output);
|
||||
std::cout.rdbuf(oldBuf);
|
||||
if (LL::isDebugMode() && LL::globalConfig.tickThreadId != std::this_thread::get_id()) {
|
||||
logger.warn("The thread executing the CommandOutputSender::send is not the \"MC_SERVER\" thread");
|
||||
logger.warn("Output: {}", tmpBuf.str());
|
||||
}
|
||||
|
||||
auto it = resultOfOrigin.find(&origin);
|
||||
if (it != resultOfOrigin.end()) {
|
||||
try {
|
||||
// May crash for incomprehensible reasons
|
||||
it->second->assign(tmpBuf.str());
|
||||
while (it->second->size() && (it->second->back() == '\n' || it->second->back() == '\r'))
|
||||
it->second->pop_back();
|
||||
it->second = nullptr;
|
||||
resultOfOrigin.erase(it);
|
||||
return rv;
|
||||
} catch (...) {
|
||||
if (LL::isDebugMode()) {
|
||||
logger.warn("Output: {}", tmpBuf.str());
|
||||
logger.warn("size of resultOfOrigin: {}", resultOfOrigin.size());
|
||||
}
|
||||
#ifdef DEBUG
|
||||
__debugbreak();
|
||||
#endif // DEBUG
|
||||
}
|
||||
}
|
||||
auto& log = output.getSuccessCount() > 0 ? serverLogger.info : serverLogger.error;
|
||||
std::istringstream iss(tmpBuf.str());
|
||||
string line;
|
||||
while (getline(iss, line)) {
|
||||
if (LL::globalConfig.colorLog)
|
||||
log << ColorFormat::convertToConsole(line, false) << Logger::endl;
|
||||
else
|
||||
log << ColorFormat::removeColorCode(line) << Logger::endl;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
//#include <MC/ColorFormat.hpp>
|
||||
//#include <MC/CommandOrigin.hpp>
|
||||
//#include <MC/CommandOutput.hpp>
|
||||
//extern std::unordered_map<CommandOrigin const*, string*> resultOfOrigin;
|
||||
//TClasslessInstanceHook(void*, "?send@CommandOutputSender@@UEAAXAEBVCommandOrigin@@AEBVCommandOutput@@@Z",
|
||||
// class CommandOrigin const& origin, class CommandOutput const& output) {
|
||||
// std::stringbuf tmpBuf;
|
||||
// auto oldBuf = std::cout.rdbuf();
|
||||
// std::cout.rdbuf(&tmpBuf);
|
||||
// auto rv = original(this, origin, output);
|
||||
// std::cout.rdbuf(oldBuf);
|
||||
// if (LL::isDebugMode() && LL::globalConfig.tickThreadId != std::this_thread::get_id()) {
|
||||
// logger.warn("The thread executing the CommandOutputSender::send is not the \"MC_SERVER\" thread");
|
||||
// logger.warn("Output: {}", tmpBuf.str());
|
||||
// }
|
||||
//
|
||||
// auto it = resultOfOrigin.find(&origin);
|
||||
// if (it != resultOfOrigin.end()) {
|
||||
// try {
|
||||
// // May crash for incomprehensible reasons
|
||||
// it->second->assign(tmpBuf.str());
|
||||
// while (it->second->size() && (it->second->back() == '\n' || it->second->back() == '\r'))
|
||||
// it->second->pop_back();
|
||||
// it->second = nullptr;
|
||||
// resultOfOrigin.erase(it);
|
||||
// return rv;
|
||||
// } catch (...) {
|
||||
// if (LL::isDebugMode()) {
|
||||
// logger.warn("Output: {}", tmpBuf.str());
|
||||
// logger.warn("size of resultOfOrigin: {}", resultOfOrigin.size());
|
||||
// }
|
||||
//#ifdef DEBUG
|
||||
// __debugbreak();
|
||||
//#endif // DEBUG
|
||||
// }
|
||||
// }
|
||||
// auto& log = output.getSuccessCount() > 0 ? serverLogger.info : serverLogger.error;
|
||||
// std::istringstream iss(tmpBuf.str());
|
||||
// string line;
|
||||
// while (getline(iss, line)) {
|
||||
// if (LL::globalConfig.colorLog)
|
||||
// log << ColorFormat::convertToConsole(line, false) << Logger::endl;
|
||||
// else
|
||||
// log << ColorFormat::removeColorCode(line) << Logger::endl;
|
||||
// }
|
||||
// return rv;
|
||||
//}
|
||||
|
@ -1,49 +1,48 @@
|
||||
#include <Global.h>
|
||||
#include <MC/Core.hpp>
|
||||
#include "LiteLoader.h"
|
||||
#include <MC/ResourcePack.hpp>
|
||||
#include <MC/Pack.hpp>
|
||||
#include <MC/ResourceLocation.hpp>
|
||||
#include <MC/ResourcePackRepository.hpp>
|
||||
#include <MC/Types.hpp>
|
||||
#include <MC/SemVersion.hpp>
|
||||
#include <MC/PackManifest.hpp>
|
||||
#include <MC/ResourcePackStack.hpp>
|
||||
#include <MC/PackSettingsFactory.hpp>
|
||||
#include <MC/PackSettings.hpp>
|
||||
#include <MC/PackInstance.hpp>
|
||||
#include <MC/IResourcePackRepository.hpp>
|
||||
#include <MC/PackIdVersion.hpp>
|
||||
|
||||
namespace ModifyPack {
|
||||
vector<PackIdVersion> PackListCache;
|
||||
}
|
||||
|
||||
THook(ResourcePack*, "??0ResourcePack@@QEAA@AEAVPack@@@Z",
|
||||
ResourcePack* self, Pack* a2) {
|
||||
auto Pack = original(self, a2);
|
||||
auto manifest = &Pack->getManifest();
|
||||
if (manifest && manifest->getPackOrigin() == PackOrigin::PackOrigin_Dev) {
|
||||
ModifyPack::PackListCache.push_back(a2->getManifest().getIdentity());
|
||||
}
|
||||
return Pack;
|
||||
}
|
||||
|
||||
THook(std::unique_ptr<ResourcePackStack>, "?deserialize@ResourcePackStack@@SA?AV?$unique_ptr@VResourcePackStack@@U?$default_delete@VResourcePackStack@@@std@@@std@@AEAV?$basic_istream@DU?$char_traits@D@std@@@3@AEBVIResourcePackRepository@@@Z",
|
||||
__int64 a2, ResourcePackRepository* a3) {
|
||||
auto Stack = original( a2, a3);
|
||||
for (auto& id : ModifyPack::PackListCache) {
|
||||
auto Pack = a3->getResourcePackForPackId(id);
|
||||
auto& SettingsFactory = a3->getPackSettingsFactory();
|
||||
auto settings = SettingsFactory.getPackSettings(Pack->getManifest());
|
||||
char gsl[16];
|
||||
auto gslPath = SymCall("??$?0PEAVResourcePack@@X@?$not_null@V?$NonOwnerPointer@VResourcePack@@@Bedrock@@@gsl@@QEAA@AEBV?$not_null@PEAVResourcePack@@@1@@Z",
|
||||
void*, char*, ResourcePack**)(gsl, &Pack);
|
||||
char size[480];
|
||||
auto Instance = SymCall("??0PackInstance@@QEAA@V?$not_null@V?$NonOwnerPointer@VResourcePack@@@Bedrock@@@gsl@@H_NPEAVPackSettings@@@Z",
|
||||
PackInstance*, char*, void*, int, bool, PackSettings*)(size, gslPath, 0, false, settings);
|
||||
Stack->add(*Instance, *(IResourcePackRepository*)a3, 0);
|
||||
}
|
||||
ModifyPack::PackListCache.clear();
|
||||
return Stack;
|
||||
}
|
||||
//#include <Global.h>
|
||||
//#include <MC/Core.hpp>
|
||||
//#include "LiteLoader.h"
|
||||
//#include <MC/ResourcePack.hpp>
|
||||
//#include <MC/Pack.hpp>
|
||||
//#include <MC/ResourceLocation.hpp>
|
||||
//#include <MC/ResourcePackRepository.hpp>
|
||||
//#include <MC/Types.hpp>
|
||||
//#include <MC/SemVersion.hpp>
|
||||
//#include <MC/PackManifest.hpp>
|
||||
//#include <MC/ResourcePackStack.hpp>
|
||||
//#include <MC/PackSettingsFactory.hpp>
|
||||
//#include <MC/PackSettings.hpp>
|
||||
//#include <MC/PackInstance.hpp>
|
||||
//#include <MC/PackIdVersion.hpp>
|
||||
//
|
||||
//namespace ModifyPack {
|
||||
// vector<PackIdVersion> PackListCache;
|
||||
//}
|
||||
//
|
||||
//THook(ResourcePack*, "??0ResourcePack@@QEAA@AEAVPack@@@Z",
|
||||
// ResourcePack* self, Pack* a2) {
|
||||
// auto Pack = original(self, a2);
|
||||
// auto manifest = &Pack->getManifest();
|
||||
// if (manifest && manifest->getPackOrigin() == PackOrigin::PackOrigin_Dev) {
|
||||
// ModifyPack::PackListCache.push_back(a2->getManifest().getIdentity());
|
||||
// }
|
||||
// return Pack;
|
||||
//}
|
||||
//
|
||||
//THook(std::unique_ptr<ResourcePackStack>, "?deserialize@ResourcePackStack@@SA?AV?$unique_ptr@VResourcePackStack@@U?$default_delete@VResourcePackStack@@@std@@@std@@AEAV?$basic_istream@DU?$char_traits@D@std@@@3@AEBVIResourcePackRepository@@@Z",
|
||||
// __int64 a2, ResourcePackRepository* a3) {
|
||||
// auto Stack = original( a2, a3);
|
||||
// for (auto& id : ModifyPack::PackListCache) {
|
||||
// auto Pack = a3->getResourcePackForPackId(id);
|
||||
// auto& SettingsFactory = a3->getPackSettingsFactory();
|
||||
// auto settings = SettingsFactory.getPackSettings(Pack->getManifest());
|
||||
// char gsl[16];
|
||||
// auto gslPath = SymCall("??$?0PEAVResourcePack@@X@?$not_null@V?$NonOwnerPointer@VResourcePack@@@Bedrock@@@gsl@@QEAA@AEBV?$not_null@PEAVResourcePack@@@1@@Z",
|
||||
// void*, char*, ResourcePack**)(gsl, &Pack);
|
||||
// char size[480];
|
||||
// auto Instance = SymCall("??0PackInstance@@QEAA@V?$not_null@V?$NonOwnerPointer@VResourcePack@@@Bedrock@@@gsl@@H_NPEAVPackSettings@@@Z",
|
||||
// PackInstance*, char*, void*, int, bool, PackSettings*)(size, gslPath, 0, false, settings);
|
||||
// Stack->add(*Instance, *(IResourcePackRepository*)a3, 0);
|
||||
// }
|
||||
// ModifyPack::PackListCache.clear();
|
||||
// return Stack;
|
||||
//}
|
Loading…
Reference in New Issue
Block a user