5 Commits

Author SHA1 Message Date
c62daa9c1c Merge branch 'plugins-support' of https://gitea.sffempire.ru/Kolyah35/minecraft-pe-0.6.1 into plugins-support 2026-07-22 23:28:17 +02:00
f6377bc5a2 lol 2026-07-22 23:27:50 +02:00
431b2a2704 add iostream 2026-07-23 00:26:44 +03:00
67acd7f9a6 update 2026-07-21 22:42:28 +02:00
6f1ca8fc3b begin 2026-07-20 14:49:38 +02:00
13 changed files with 251 additions and 23 deletions

View File

@@ -3,10 +3,10 @@ project(MinecraftPE)
include(cmake/CPM.cmake)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED TRUE)
set(CMAKE_POLICY_VERSION_MINIMUM 3.10)
add_definitions(-DLUA_USE_DLOPEN)
include(cmake/EnumOption.cmake)
if(EMSCRIPTEN)
@@ -95,6 +95,46 @@ else()
"GLFW_BUILD_TESTS OFF"
"GLFW_BUILD_DOCS OFF"
)
CPMAddPackage("gh:halx99/sol2#support-lua-5.5")
CPMAddPackage("gh:lua/lua#master")
add_library(
lua STATIC
${lua_SOURCE_DIR}/lapi.c
${lua_SOURCE_DIR}/lauxlib.c
${lua_SOURCE_DIR}/lbaselib.c
${lua_SOURCE_DIR}/lcode.c
${lua_SOURCE_DIR}/lcorolib.c
${lua_SOURCE_DIR}/lctype.c
${lua_SOURCE_DIR}/ldblib.c
${lua_SOURCE_DIR}/ldebug.c
${lua_SOURCE_DIR}/ldo.c
${lua_SOURCE_DIR}/ldump.c
${lua_SOURCE_DIR}/lfunc.c
${lua_SOURCE_DIR}/lgc.c
${lua_SOURCE_DIR}/linit.c
${lua_SOURCE_DIR}/liolib.c
${lua_SOURCE_DIR}/llex.c
${lua_SOURCE_DIR}/lmathlib.c
${lua_SOURCE_DIR}/lmem.c
${lua_SOURCE_DIR}/loadlib.c
${lua_SOURCE_DIR}/lobject.c
${lua_SOURCE_DIR}/lopcodes.c
${lua_SOURCE_DIR}/loslib.c
${lua_SOURCE_DIR}/lparser.c
${lua_SOURCE_DIR}/lstate.c
${lua_SOURCE_DIR}/lstring.c
${lua_SOURCE_DIR}/lstrlib.c
${lua_SOURCE_DIR}/ltable.c
${lua_SOURCE_DIR}/ltablib.c
${lua_SOURCE_DIR}/ltm.c
${lua_SOURCE_DIR}/lua.c
${lua_SOURCE_DIR}/lundump.c
${lua_SOURCE_DIR}/lutf8lib.c
${lua_SOURCE_DIR}/lvm.c
${lua_SOURCE_DIR}/lzio.c
)
endif()
CPMAddPackage(
@@ -215,6 +255,8 @@ file(GLOB SERVER_SOURCES
"src/world/phys/HitResult.cpp"
"src/commands/*.cpp"
"src/plugins/*.cpp"
)
file(GLOB CLIENT_SOURCES
@@ -300,6 +342,8 @@ file(GLOB CLIENT_SOURCES
"src/main.cpp"
"src/commands/*.cpp"
"src/plugins/*.cpp"
)
if (${PLATFORM} STREQUAL "Desktop")
@@ -308,17 +352,20 @@ endif()
# Server
add_executable("${PROJECT_NAME}-server" ${SERVER_SOURCES})
set_target_properties("${PROJECT_NAME}-server" PROPERTIES ENABLE_EXPORTS TRUE)
target_compile_definitions("${PROJECT_NAME}-server" PUBLIC "STANDALONE_SERVER" "SERVER_PROFILER")
target_include_directories("${PROJECT_NAME}-server" PUBLIC
"${CMAKE_SOURCE_DIR}/src/"
"${lua_SOURCE_DIR}/"
"project/lib_projects/raknet/jni/RaknetSources"
)
target_link_libraries("${PROJECT_NAME}-server" ${CMAKE_THREAD_LIBS_INIT} ${EXTRA_LIBS})
target_link_libraries("${PROJECT_NAME}-server" ${CMAKE_THREAD_LIBS_INIT} ${EXTRA_LIBS} lua sol2::sol2)
add_executable(${PROJECT_NAME} ${CLIENT_SOURCES})
set_target_properties(${PROJECT_NAME} PROPERTIES ENABLE_EXPORTS TRUE)
target_compile_definitions(${PROJECT_NAME} PUBLIC ${PLATFORM_CPP})
@@ -328,6 +375,8 @@ target_include_directories(${PROJECT_NAME} PUBLIC
"${openal_SOURCE_DIR}/include"
"${glfw_SOURCE_DIR}/include"
"lib/include"
"${lua_SOURCE_DIR}/"
)
if(${PLATFORM} MATCHES "Web")
@@ -375,7 +424,7 @@ endif()
# Client
target_compile_definitions(${PROJECT_NAME} PUBLIC "OPENGL_ES" "NO_EGL" ${PLATFORM})
target_link_libraries(${PROJECT_NAME} zlib ${PNG_LIB} OpenAL::OpenAL glfw ${EXTRA_LIBS})
target_link_libraries(${PROJECT_NAME} zlib ${PNG_LIB} OpenAL::OpenAL glfw ${EXTRA_LIBS} lua sol2::sol2)
if (OpenSSL_FOUND)
target_link_libraries(${PROJECT_NAME} OpenSSL::SSL OpenSSL::Crypto)

View File

@@ -142,8 +142,8 @@ void seedMT( unsigned int seed, unsigned int *state, unsigned int *&next, int &l
// so-- that's why the only change I made is to restrict to odd seeds.
//
register unsigned int x = ( seed | 1U ) & 0xFFFFFFFFU, *s = state;
register int j;
unsigned int x = ( seed | 1U ) & 0xFFFFFFFFU, *s = state;
int j;
for ( left = 0, *s++ = x, j = N; --j;
*s++ = ( x *= 69069U ) & 0xFFFFFFFFU )
@@ -154,8 +154,8 @@ void seedMT( unsigned int seed, unsigned int *state, unsigned int *&next, int &l
unsigned int reloadMT( unsigned int *state, unsigned int *&next, int &left )
{
register unsigned int * p0 = state, *p2 = state + 2, *pM = state + M, s0, s1;
register int j;
unsigned int * p0 = state, *p2 = state + 2, *pM = state + M, s0, s1;
int j;
if ( left < -1 )
seedMT( 4357U );

View File

@@ -1214,6 +1214,8 @@ void Minecraft::init()
checkGlError("Init complete");
#endif
PluginsManager::get().init(*this);
options.load();
setIsCreativeMode(false); // false means it's Survival Mode

View File

@@ -3,6 +3,8 @@
#include "Options.h"
#include "commands/CommandManager.hpp"
#include <plugins/PluginsManager.hpp>
#ifndef STANDALONE_SERVER
#include "MouseHandler.h"
#include "gui/Gui.h"

View File

@@ -15,15 +15,16 @@
#include "platform/time.h"
#include "SharedConstants.h"
#include "world/level/LevelConstants.h"
#include <plugins/PluginsManager.hpp>
#define MAIN_CLASS NinecraftApp
static App* g_app = 0;
static int g_exitCode = 0;
void signal_callback_handler(int signum) {
std::cout << "Signum caught: " << signum << std::endl;
if(signum == 2 || signum == 3){ // SIGINT || SIGQUIT
if(g_app != 0) {
if (signum == 2 || signum == 3) { // SIGINT || SIGQUIT
if (g_app != 0) {
g_app->quit();
} else {
exit(g_exitCode);
@@ -64,7 +65,6 @@ std::string findStringInConfig(std::string line, std::string config) {
return valueStr;
}
int main(int numArguments, char* pszArgs[]) {
std::ifstream serverProperties("server.properties");
@@ -148,7 +148,7 @@ int main(int numArguments, char* pszArgs[]) {
}
printf("Level Name: %s\n", levelName.c_str());
AppContext appContext;
appContext.platform = new AppPlatform();
App* app = new MAIN_CLASS();
@@ -162,6 +162,7 @@ int main(int numArguments, char* pszArgs[]) {
float startTime = getTimeS();
((MAIN_CLASS*)g_app)->selectLevel(levelDir, levelName, settings);
((MAIN_CLASS*)g_app)->hostMultiplayer(port);
PluginsManager::get().loadPlugins();
// Reading ops
std::ifstream ops("ops.txt");
@@ -204,6 +205,7 @@ int main(int numArguments, char* pszArgs[]) {
std::cout << "Level has been generated in " << getTimeS() - startTime << std::endl;
((MAIN_CLASS*)g_app)->level->saveLevelData();
std::cout << "Level has been saved!" << std::endl;
PluginsManager::get().emit("ServerLoaded");
while(!app->wantToQuit()) {
app->update();
@@ -238,6 +240,7 @@ int main(int numArguments, char* pszArgs[]) {
delete app;
appContext.platform->finish();
delete appContext.platform;
PluginsManager::get().emit("ServerShutdown");
std::cout << "Quit correctly" << std::endl;
return g_exitCode;

View File

@@ -39,6 +39,7 @@
#endif
#include "../server/ServerPlayer.h"
#include "../world/entity/item/FallingTile.h"
#include <plugins/LuaPlayer.hpp>
#define TIMES(x) for(int itc ## __LINE__ = 0; itc ## __LINE__ < x; ++ itc ## __LINE__)
@@ -163,12 +164,12 @@ void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, ChatPack
if (packet->message[0] == '/') {
// This is a command
ChatPacket resp(minecraft->commandManager().execute(*minecraft, *player, Util::stringTrim(packet->message.substr(1))));
return sendPrivate(resp, source);
}
displayGameMessage("<" + player->name + "> " + packet->message);
PluginsManager::get().emit("Message", LuaPlayer(source), packet->message);
}
void ServerSideNetworkHandler::onNewClient(const RakNet::RakNetGUID& clientGuid)
@@ -193,6 +194,7 @@ void ServerSideNetworkHandler::onDisconnect(const RakNet::RakNetGUID& guid)
std::string message = player->name;
message += " disconnected from the game";
displayGameMessage(message);
PluginsManager::get().emit("PlayerDisconnect", LuaPlayer(guid));
//RemoveEntityPacket packet(player->entityId);
//raknetInstance->send(packet);
@@ -226,7 +228,6 @@ void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, LoginPac
std::string nicknameLower = packet->clientName.C_String();
std::transform(nicknameLower.begin(), nicknameLower.end(), nicknameLower.begin(), ::tolower);
printf("%s lower \n", nicknameLower.c_str());
for (int i = 0; i < level->players.size(); i++) {
ServerPlayer* player = (ServerPlayer*) level->players.at(i);
@@ -306,8 +307,6 @@ void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, ReadyPac
if (packet->type == ReadyPacket::READY_REQUESTEDCHUNKS)
onReady_RequestedChunks(source);
LOGI("Ready player two ready ready player two!!\n ");
}
void ServerSideNetworkHandler::onReady_ClientGeneration(const RakNet::RakNetGUID& source)
@@ -352,6 +351,7 @@ void ServerSideNetworkHandler::onReady_ClientGeneration(const RakNet::RakNetGUID
#else
LOGW("%s joined the game\n", newPlayer->name.c_str());
#endif
PluginsManager::get().emit("PlayerJoin", LuaPlayer(source));
// Send all Entities to the new player
for (unsigned int i = 0; i < level->entities.size(); ++i) {
@@ -461,7 +461,7 @@ void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, MovePlay
}
}
void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, RemoveBlockPacket* packet){
void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, RemoveBlockPacket* packet) {
if (!level) return;
Player* player = getPlayer(source);

View File

@@ -66,7 +66,7 @@ public:
Player* popPendingPlayer(const RakNet::RakNetGUID& source);
void displayGameMessage(const std::string& message);
private:
/**
* @brief Send packet to all players
*/
@@ -78,6 +78,8 @@ private:
void sendPrivate(Packet& packet, const RakNet::RakNetGUID& source);
Player* getPlayer(const RakNet::RakNetGUID& source);
private:
Minecraft* minecraft;
Level* level;

54
src/plugins/LuaPlayer.hpp Normal file
View File

@@ -0,0 +1,54 @@
#pragma once
#include <cstdint>
#include <raknet/RakNetTypes.h>
#include <plugins/PluginsManager.hpp>
#include <network/ServerSideNetworkHandler.h>
#include <world/entity/player/Player.h>
#include <client/Minecraft.h>
class LuaPlayer {
public:
LuaPlayer(const RakNet::RakNetGUID source) : m_source(source) {}
std::string getNickname() {
auto mc = PluginsManager::get().getMinecraft();
ServerSideNetworkHandler* ss = (ServerSideNetworkHandler*) mc->netCallback;
auto plr = ss->getPlayer(m_source);
if (plr != nullptr) return plr->name;
return "";
}
float getX() {
auto mc = PluginsManager::get().getMinecraft();
ServerSideNetworkHandler* ss = (ServerSideNetworkHandler*) mc->netCallback;
auto plr = ss->getPlayer(m_source);
if (plr != nullptr) return plr->x;
return 0;
}
float getY() {
auto mc = PluginsManager::get().getMinecraft();
ServerSideNetworkHandler* ss = (ServerSideNetworkHandler*) mc->netCallback;
auto plr = ss->getPlayer(m_source);
if (plr != nullptr) return plr->y;
return 0;
}
float getZ() {
auto mc = PluginsManager::get().getMinecraft();
ServerSideNetworkHandler* ss = (ServerSideNetworkHandler*) mc->netCallback;
auto plr = ss->getPlayer(m_source);
if (plr != nullptr) return plr->z;
return 0;
}
private:
const RakNet::RakNetGUID m_source;
};

11
src/plugins/LuaServer.cpp Normal file
View File

@@ -0,0 +1,11 @@
#include <plugins/LuaServer.hpp>
#include <plugins/PluginsManager.hpp>
#include <network/ServerSideNetworkHandler.h>
#include <client/Minecraft.h>
void LuaServer::sendServerMessage(std::string msg) {
auto mc = PluginsManager::get().getMinecraft();
ServerSideNetworkHandler* ss = (ServerSideNetworkHandler*) mc->netCallback;
ss->displayGameMessage(msg);
}

View File

@@ -0,0 +1,7 @@
#pragma once
#include <string>
class LuaServer {
public:
void sendServerMessage(std::string msg);
};

View File

@@ -0,0 +1,48 @@
#include <plugins/PluginsManager.hpp>
#include <plugins/LuaPlayer.hpp>
#include <plugins/LuaServer.hpp>
#include <client/Minecraft.h>
#include <filesystem>
namespace fs = std::filesystem;
void PluginsManager::init(Minecraft& minecraft) {
m_lua.open_libraries(sol::lib::base, sol::lib::package, sol::lib::string, sol::lib::math, sol::lib::table);
registerTypes();
m_minecraft = &minecraft;
}
void PluginsManager::registerTypes() {
// @note you cant just do that, because lua doesnt have access to the class in this case
// m_lua.set_function("subscribe", &PluginsManager::subscribe);
m_lua.set_function("subscribe", [this](std::string event, sol::protected_function func) {
// @note: why the .at() not working?
m_callbacks[event].push_back(func);
});
m_lua.new_usertype<LuaServer>(
"Server",
"sendMessage", &LuaServer::sendServerMessage
);
m_lua.new_usertype<LuaPlayer>(
"Player",
"getNickname", &LuaPlayer::getNickname,
"getX", &LuaPlayer::getX,
"getY", &LuaPlayer::getY,
"getZ", &LuaPlayer::getZ
);
m_lua["Server"] = &m_srv;
}
void PluginsManager::loadPlugins() {
std::string path = "plugins/";
for (const auto & entry : fs::directory_iterator(path)) {
m_lua.script_file(entry.path().string());
}
}

View File

@@ -0,0 +1,50 @@
#pragma once
#include <unordered_map>
#include <sol/sol.hpp>
#include <vector>
#include <iostream>
#include <plugins/LuaServer.hpp>
class Minecraft;
class PluginsManager {
public:
static inline PluginsManager& get() {
static PluginsManager inst;
return inst;
}
void init(Minecraft& minecraft);
void registerTypes();
void loadPlugins();
// @ai @note maybe we should rewrite it...
// problem that i dont know how to pass args in sol::function dynamically
// so i used ai
// sry :(
template<typename... Args>
void emit(std::string event, Args&&... args) {
auto it = m_callbacks.find(event);
if (it == m_callbacks.end()) return;
for (auto& callback : it->second) {
sol::protected_function_result result = callback(std::forward<Args>(args)...);
if (!result.valid()) {
sol::error err = result;
std::cout << err.what() << std::endl;
}
}
}
Minecraft* getMinecraft() { return m_minecraft; }
private:
std::unordered_map<std::string, std::vector<sol::function>> m_callbacks;
LuaServer m_srv;
sol::state m_lua;
Minecraft* m_minecraft;
};

View File

@@ -142,8 +142,8 @@ void seedMT( unsigned int seed, unsigned int *state, unsigned int *&next, int &l
// so-- that's why the only change I made is to restrict to odd seeds.
//
register unsigned int x = ( seed | 1U ) & 0xFFFFFFFFU, *s = state;
register int j;
unsigned int x = ( seed | 1U ) & 0xFFFFFFFFU, *s = state;
int j;
for ( left = 0, *s++ = x, j = N; --j;
*s++ = ( x *= 69069U ) & 0xFFFFFFFFU )
@@ -154,8 +154,8 @@ void seedMT( unsigned int seed, unsigned int *state, unsigned int *&next, int &l
unsigned int reloadMT( unsigned int *state, unsigned int *&next, int &left )
{
register unsigned int * p0 = state, *p2 = state + 2, *pM = state + M, s0, s1;
register int j;
unsigned int * p0 = state, *p2 = state + 2, *pM = state + M, s0, s1;
int j;
if ( left < -1 )
seedMT( 4357U );