add dedicated server and readme
This commit is contained in:
parent
bb00b43b3c
commit
5867993997
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,3 +1,4 @@
|
||||
.vscode
|
||||
.idea/
|
||||
assets/
|
||||
data/
|
||||
|
||||
@ -13,9 +13,6 @@ link_directories(/usr/lib32)
|
||||
include_directories(/usr/include)
|
||||
set(X11_X11_LIB /usr/lib32/libX11.so)
|
||||
|
||||
#SET(CMAKE_CXX_COMPILER "g++-4.9")
|
||||
#SET(CMAKE_C_COMPILER "gcc-4.9")
|
||||
|
||||
find_package(Threads REQUIRED)
|
||||
find_package(ZLIB REQUIRED)
|
||||
find_package(X11 REQUIRED)
|
||||
@ -27,11 +24,19 @@ include_directories(${EGL_INCLUDE_DIRS})
|
||||
include_directories(eglut)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -D_GLIBCXX_USE_CXX11_ABI=0")
|
||||
|
||||
set(HYBRIS_DEFINES PRIVATE ANDROID_X86_LINKER _GNU_SOURCE LINKER_TEXT_BASE=0xB0000100 LINKER_AREA_SIZE=0x01000000 LINKER_DEBUG=1)
|
||||
set(HYBRIS_SOURCES hybris/src/cache.c hybris/src/dlfcn.c hybris/src/hooks.c hybris/src/hooks_shm.c hybris/src/logging.c hybris/src/properties.c hybris/src/strlcpy.c hybris/src/sysconf.c hybris/src/jb/dlfcn.c hybris/src/jb/linker.c hybris/src/jb/linker_environ.c hybris/src/jb/linker_format.c hybris/src/jb/rt.c)
|
||||
set(EGLUT_SOURCES eglut/eglut.c eglut/eglut_x11.c)
|
||||
|
||||
set(SOURCE_FILES src/main.cpp src/common.cpp src/hook.cpp src/amdfix.s src/LinuxAppPlatform.cpp mcpe/types.cpp mcpe/ImagePickingCallback.h mcpe/FilePickerSettings.h)
|
||||
add_executable(mcpelauncher ${HYBRIS_SOURCES} ${EGLUT_SOURCES} ${SOURCE_FILES})
|
||||
set(COMMON_SOURCE_FILES src/common.cpp src/hook.cpp src/linux_app_platform.cpp mcpe/types.cpp mcpe/string.cpp)
|
||||
set(CLIENT_SOURCE_FILES src/main.cpp src/amdfix.s)
|
||||
set(SERVER_SOURCE_FILES src/server.cpp src/server_properties.cpp)
|
||||
|
||||
add_executable(mcpelauncher ${HYBRIS_SOURCES} ${EGLUT_SOURCES} ${COMMON_SOURCE_FILES} ${CLIENT_SOURCE_FILES})
|
||||
target_link_libraries(mcpelauncher ${CMAKE_DL_LIBS} ${CMAKE_THREAD_LIBS_INIT} rt libEGL.so libGLESv2.so ${X11_X11_LIB} uuid)
|
||||
target_compile_definitions(mcpelauncher PRIVATE ANDROID_X86_LINKER _GNU_SOURCE LINKER_TEXT_BASE=0xB0000100 LINKER_AREA_SIZE=0x01000000 LINKER_DEBUG=1)
|
||||
target_compile_definitions(mcpelauncher ${HYBRIS_DEFINES})
|
||||
set_target_properties(mcpelauncher PROPERTIES COMPILE_FLAGS "-m32" LINK_FLAGS "-m32")
|
||||
|
||||
add_executable(server ${HYBRIS_SOURCES} ${COMMON_SOURCE_FILES} ${SERVER_SOURCE_FILES})
|
||||
target_link_libraries(server ${CMAKE_DL_LIBS} ${CMAKE_THREAD_LIBS_INIT} ${X11_X11_LIB} rt uuid z zip)
|
||||
target_compile_definitions(server ${HYBRIS_DEFINES} SERVER)
|
||||
53
FindEGL.cmake
Normal file
53
FindEGL.cmake
Normal file
@ -0,0 +1,53 @@
|
||||
# - Try to Find EGL
|
||||
# Once done, this will define
|
||||
#
|
||||
# EGL_FOUND - system has EGL installed.
|
||||
# EGL_INCLUDE_DIRS - directories which contain the EGL headers.
|
||||
# EGL_LIBRARIES - libraries required to link against EGL.
|
||||
# EGL_DEFINITIONS - Compiler switches required for using EGL.
|
||||
#
|
||||
# Copyright (C) 2012 Intel Corporation. All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND ITS CONTRIBUTORS ``AS
|
||||
# IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR ITS
|
||||
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
find_package(PkgConfig)
|
||||
|
||||
pkg_check_modules(PC_EGL egl)
|
||||
|
||||
if (PC_EGL_FOUND)
|
||||
set(EGL_DEFINITIONS ${PC_EGL_CFLAGS_OTHER})
|
||||
endif ()
|
||||
|
||||
find_path(EGL_INCLUDE_DIRS NAMES EGL/egl.h
|
||||
HINTS ${PC_EGL_INCLUDEDIR} ${PC_EGL_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
set(EGL_NAMES ${EGL_NAMES} egl EGL)
|
||||
find_library(EGL_LIBRARIES NAMES ${EGL_NAMES}
|
||||
HINTS ${PC_EGL_LIBDIR} ${PC_EGL_LIBRARY_DIRS}
|
||||
)
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(EGL DEFAULT_MSG EGL_INCLUDE_DIRS EGL_LIBRARIES)
|
||||
|
||||
mark_as_advanced(EGL_INCLUDE_DIRS EGL_LIBRARIES)
|
||||
50
README.md
50
README.md
@ -1,42 +1,62 @@
|
||||
MCPE Linux Launcher
|
||||
===================
|
||||
|
||||
## Required packages
|
||||
A fork of [mcpelauncher-linux](https://github.com/MCMrARM/mcpelauncher-linux) (commit from 2017, MCPE 1.1) with additional features and improvements
|
||||
|
||||
```
|
||||
sudo apt-get install cmake zlib1g-dev:i386 libncurses5-dev:i386 libgles2-mesa-dev gcc-multilib g++-multilib zlib1g-dev:i386 libx11-dev:i386 linux-libc-dev:i386 uuid-dev:i386 libpng-dev:i386 libx11-dev:i386 libxext6:i386
|
||||
## Features
|
||||
- Dedicated server support
|
||||
- Compatibility fixes for building with the latest GCC
|
||||
- Other quality-of-life improvements
|
||||
|
||||
## Required Packages
|
||||
|
||||
### Ubuntu / Debian
|
||||
Install the necessary dependencies with:
|
||||
|
||||
```bash
|
||||
sudo dpkg --add-architecture i386
|
||||
sudo apt-get update
|
||||
sudo apt-get install cmake zlib1g-dev:i386 libncurses5-dev:i386 \
|
||||
libgles2-mesa-dev libegl1-mesa-dev:i386 gcc-multilib g++-multilib \
|
||||
libx11-dev:i386 linux-libc-dev:i386 uuid-dev:i386 libpng-dev:i386 \
|
||||
libxext6:i386
|
||||
```
|
||||
|
||||
If g++-4.9 fails to install and you're using Ubuntu 14.04 you may need to add the repository ppa:ubuntu-toolchain-r/test.
|
||||
### Arch Linux
|
||||
Install the necessary dependencies with:
|
||||
|
||||
You'll also need to install 32-bit version of the graphic drivers (nvidia drivers ask you about that at installation, so
|
||||
you may need to reinstall/reconfigure them; if you use mesa you'll need to install the libgles2-mesa-dev:i386 and
|
||||
libegl1-mesa-dev:i386 packages)
|
||||
```bash
|
||||
sudo pacman -Syu base-devel cmake zlib libpng libx11 libxext libglvnd \
|
||||
libxrandr libxi mesa lib32-gcc-libs lib32-glibc lib32-mesa lib32-libx11 \
|
||||
lib32-libxext lib32-libxrandr lib32-libxi
|
||||
```
|
||||
|
||||
You may also need to do `sudo dpkg --add-architecture i386` if you have never installed i386 packages before.
|
||||
Make sure the multilib repo is enabled in `/etc/pacman.conf`.
|
||||
|
||||
## Compiling
|
||||
This app uses cmake so it is enough to do:
|
||||
|
||||
```
|
||||
cmake .
|
||||
mkdir build
|
||||
cmake ..
|
||||
make
|
||||
```
|
||||
|
||||
## Running
|
||||
1. Clone this repository
|
||||
2. Compile the launcher
|
||||
3. You'll need to obtain a x86 MCPE .apk. The easiest way to do so is to use the
|
||||
[Google Play downloader tool](https://github.com/MCMrARM/Google-Play-API) (it is an console app; remember that
|
||||
you need to type 'y' when you are asked if you want to use x86 as the architecture, and you must have purchased MCPE
|
||||
on the Google account you are logging in with; the package name of MCPE is `com.mojang.minecraftpe`)
|
||||
3. Obtain a x86 MCPE 1.1 apk file
|
||||
4. After you have downloaded MCPE, place it in the directory where you'll be running this app, and run ./extract.sh _filename_
|
||||
5. Run the launcher!
|
||||
|
||||
If the extract script fails with an error about the .apk not being x86, it means that you have provided it a bad .apk.
|
||||
You'll need to purchase MCPE on Google Play and use the downloader tool.
|
||||
|
||||
## Using the Dedicated Server
|
||||
1. Create a server.properties file and fill in your settings. An example is located in the root of this repository.
|
||||
2. Run the server binary that you built earlier
|
||||
|
||||
## License and thanks
|
||||
Most of the code in this repo is licensed under BSD. This project uses libc, libstdc++, libz and libm - libraries
|
||||
- Credit goes to [MCMrARM](https://github.com/MCMrARM) for the original source code
|
||||
- Most of the code in this repo is licensed under BSD. This project uses libc, libstdc++, libz and libm - libraries
|
||||
extracted from the Android OS. A modified version of libhybris is also included, which is licensed under GPL. This project
|
||||
also uses the EGLUT library and FMOD library (for sound).
|
||||
19
mcpe/Api.h
Normal file
19
mcpe/Api.h
Normal file
@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
namespace minecraft {
|
||||
namespace api {
|
||||
|
||||
class Api {
|
||||
|
||||
public:
|
||||
|
||||
void** vtable;
|
||||
mcpe::string envPath;
|
||||
void** playerIfaceVtable;
|
||||
void** entityIfaceVtable;
|
||||
void** networkIfaceVtable;
|
||||
void** playerInteractionsIfaceVtable;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
19
mcpe/AppResourceLoader.h
Normal file
19
mcpe/AppResourceLoader.h
Normal file
@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include "string.h"
|
||||
#include <functional>
|
||||
#include "Resource.h"
|
||||
|
||||
class AppResourceLoader : public ResourceLoader {
|
||||
|
||||
private:
|
||||
char filler[0x14];
|
||||
|
||||
public:
|
||||
static void (*AppResourceLoader_construct)(AppResourceLoader*, std::function<mcpe::string ()>);
|
||||
|
||||
AppResourceLoader(std::function<mcpe::string ()> f) {
|
||||
AppResourceLoader_construct(this, f);
|
||||
}
|
||||
|
||||
};
|
||||
22
mcpe/AutomationClient.h
Normal file
22
mcpe/AutomationClient.h
Normal file
@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#include "IMinecraftApp.h"
|
||||
|
||||
namespace Automation {
|
||||
|
||||
class AutomationClient {
|
||||
|
||||
public:
|
||||
|
||||
static void (*AutomationClient_construct)(AutomationClient*, IMinecraftApp&);
|
||||
|
||||
char filler[0x300];
|
||||
|
||||
AutomationClient(IMinecraftApp& a) {
|
||||
AutomationClient_construct(this, a);
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
16
mcpe/EntitlementManager.h
Normal file
16
mcpe/EntitlementManager.h
Normal file
@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
|
||||
namespace Social { class UserManager; }
|
||||
class MinecraftEventing;
|
||||
|
||||
class EntitlementManager {
|
||||
public:
|
||||
char filler[0x100];
|
||||
|
||||
static void (*EntitlementManager_construct)(EntitlementManager*, MinecraftEventing&, Social::UserManager&);
|
||||
|
||||
EntitlementManager(MinecraftEventing &evt, Social::UserManager &um) {
|
||||
EntitlementManager_construct(this, evt, um);
|
||||
}
|
||||
};
|
||||
70
mcpe/FilePathManager.h
Normal file
70
mcpe/FilePathManager.h
Normal file
@ -0,0 +1,70 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include "string.h"
|
||||
|
||||
class FilePathManager {
|
||||
|
||||
public:
|
||||
char filler[0x20];
|
||||
|
||||
static void (*FilePathManager_construct)(
|
||||
FilePathManager*,
|
||||
mcpe::string,
|
||||
bool
|
||||
);
|
||||
|
||||
static mcpe::string (*FilePathManager_getRootPath)(
|
||||
FilePathManager const*
|
||||
);
|
||||
|
||||
static mcpe::string (*FilePathManager_getUserDataPath)(
|
||||
FilePathManager const*
|
||||
);
|
||||
|
||||
static void (*FilePathManager_setPackagePath)(
|
||||
FilePathManager*,
|
||||
mcpe::string
|
||||
);
|
||||
|
||||
static mcpe::string (*FilePathManager_getPackagePath)(
|
||||
FilePathManager const*
|
||||
);
|
||||
|
||||
static void (*FilePathManager_setSettingsPath)(
|
||||
FilePathManager*,
|
||||
mcpe::string
|
||||
);
|
||||
|
||||
static mcpe::string (*FilePathManager_getSettingsPath)(
|
||||
FilePathManager const*
|
||||
);
|
||||
|
||||
FilePathManager(mcpe::string str, bool b) {
|
||||
FilePathManager_construct(this, std::move(str), b);
|
||||
}
|
||||
|
||||
mcpe::string getRootPath() const {
|
||||
return FilePathManager_getRootPath(this);
|
||||
}
|
||||
|
||||
mcpe::string getUserDataPath() const {
|
||||
return FilePathManager_getUserDataPath(this);
|
||||
}
|
||||
|
||||
void setPackagePath(mcpe::string s) {
|
||||
FilePathManager_setPackagePath(this, std::move(s));
|
||||
}
|
||||
|
||||
mcpe::string getPackagePath() const {
|
||||
return FilePathManager_getPackagePath(this);
|
||||
}
|
||||
|
||||
void setSettingsPath(mcpe::string s) {
|
||||
FilePathManager_setSettingsPath(this, std::move(s));
|
||||
}
|
||||
|
||||
mcpe::string getSettingsPath() const {
|
||||
return FilePathManager_getSettingsPath(this);
|
||||
}
|
||||
};
|
||||
@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include "string.h"
|
||||
#include <vector>
|
||||
#include <functional>
|
||||
|
||||
@ -10,15 +10,15 @@ struct FilePickerSettings {
|
||||
NONE, OPEN, SAVE
|
||||
};
|
||||
struct FileDescription {
|
||||
std::string ext, desc;
|
||||
mcpe::string ext, desc;
|
||||
};
|
||||
|
||||
char filler [0x20]; // 20
|
||||
std::function<void (FilePickerSettings&, std::string)> pickedCallback; // 30
|
||||
std::vector<FileDescription> fileDescriptions; // 3c
|
||||
int filler3; // 40
|
||||
PickerType type; // 44
|
||||
std::string defaultFileName; // 48
|
||||
std::string pickerTitle; // 52
|
||||
char filler [0x20];
|
||||
std::function<void (FilePickerSettings&, mcpe::string)> pickedCallback;
|
||||
std::vector<FileDescription> fileDescriptions;
|
||||
int filler3;
|
||||
PickerType type;
|
||||
mcpe::string defaultFileName;
|
||||
mcpe::string pickerTitle;
|
||||
|
||||
};
|
||||
21
mcpe/IMinecraftApp.h
Normal file
21
mcpe/IMinecraftApp.h
Normal file
@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
class Minecraft;
|
||||
|
||||
namespace Automation {
|
||||
class AutomationClient;
|
||||
}
|
||||
|
||||
class IMinecraftApp {
|
||||
|
||||
public:
|
||||
|
||||
virtual ~IMinecraftApp() { }
|
||||
virtual Minecraft* getPrimaryMinecraft() = 0;
|
||||
virtual Automation::AutomationClient* getAutomationClient() = 0;
|
||||
virtual bool isEduMode() = 0;
|
||||
virtual bool isDedicatedServer() = 0;
|
||||
virtual int getDefaultNetworkMaxPlayers() = 0;
|
||||
virtual void onNetworkMaxPlayersChanged(unsigned int) = 0;
|
||||
|
||||
};
|
||||
@ -6,7 +6,7 @@ class ImagePickingCallback {
|
||||
|
||||
public:
|
||||
virtual ~ImagePickingCallback();
|
||||
virtual void onImagePickingSuccess(const std::string&);
|
||||
virtual void onImagePickingSuccess(const mcpe::string&);
|
||||
virtual void onImagePickingCanceled();
|
||||
|
||||
};
|
||||
@ -9,7 +9,7 @@ class Keyboard {
|
||||
|
||||
public:
|
||||
|
||||
static void (*Keyboard_feedText)(const std::string&, bool, unsigned char);
|
||||
static void (*Keyboard_feedText)(const mcpe::string&, bool, unsigned char);
|
||||
|
||||
static std::vector<KeyboardAction>* inputs;
|
||||
static int* states;
|
||||
|
||||
25
mcpe/LevelSettings.h
Normal file
25
mcpe/LevelSettings.h
Normal file
@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
|
||||
class LevelSettings {
|
||||
public:
|
||||
static void (*LevelSettings_construct)(LevelSettings*);
|
||||
|
||||
int seed; // 4
|
||||
int gametype; // 8
|
||||
int difficulty; // c
|
||||
int forceGameType; // 10
|
||||
int generator; // 14
|
||||
bool hasAchievementsDisabled; // 18
|
||||
int dimension; // 1c
|
||||
int time; // 20
|
||||
bool edu; // 21
|
||||
float rainLevel, lightningLevel; // 28, 2c
|
||||
bool mpGame, lanBroadcast, xblBroadcast, commandsEnabled, texturepacksRequired, overrideSavedSettings; // 2d, 2e, 2f, 30, 31, 32~34
|
||||
char filler[0x300];
|
||||
|
||||
LevelSettings() {
|
||||
LevelSettings_construct(this);
|
||||
}
|
||||
};
|
||||
12
mcpe/MinecraftEventing.h
Normal file
12
mcpe/MinecraftEventing.h
Normal file
@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
class MinecraftEventing {
|
||||
public:
|
||||
char filler[0x200];
|
||||
|
||||
static void (*MinecraftEventing_construct)(MinecraftEventing*, mcpe::string const&);
|
||||
|
||||
MinecraftEventing(mcpe::string const& str) {
|
||||
MinecraftEventing_construct(this, str);
|
||||
}
|
||||
};
|
||||
@ -3,6 +3,9 @@
|
||||
#include "App.h"
|
||||
|
||||
class Options;
|
||||
class MinecraftEventing;
|
||||
class ResourcePackRepository;
|
||||
class ResourcePackManager;
|
||||
|
||||
class MinecraftGame : public App {
|
||||
|
||||
|
||||
12
mcpe/OpsList.h
Normal file
12
mcpe/OpsList.h
Normal file
@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
struct OpsList {
|
||||
|
||||
struct Entry {
|
||||
char filler[0x10];
|
||||
};
|
||||
|
||||
bool b;
|
||||
std::vector<Entry> entries;
|
||||
|
||||
};
|
||||
18
mcpe/Resource.h
Normal file
18
mcpe/Resource.h
Normal file
@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
||||
enum class ResourceFileSystem;
|
||||
|
||||
class ResourceLoader {
|
||||
};
|
||||
|
||||
class Resource {
|
||||
|
||||
public:
|
||||
static void (*Resource_registerLoader)(ResourceFileSystem, std::unique_ptr<ResourceLoader>);
|
||||
|
||||
static void registerLoader(ResourceFileSystem fs, std::unique_ptr<ResourceLoader> loader) {
|
||||
Resource_registerLoader(fs, std::move(loader));
|
||||
}
|
||||
};
|
||||
59
mcpe/ResourcePack.h
Normal file
59
mcpe/ResourcePack.h
Normal file
@ -0,0 +1,59 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <functional>
|
||||
|
||||
class MinecraftEventing;
|
||||
class FilePathManager;
|
||||
class ResourcePack;
|
||||
class ResourcePackStack;
|
||||
class ResourceLoader;
|
||||
enum class ResourcePackStackType;
|
||||
|
||||
class PackManifestFactory {
|
||||
|
||||
public:
|
||||
|
||||
char filler[4];
|
||||
|
||||
static void (*PackManifestFactory_construct)(PackManifestFactory*, MinecraftEventing&);
|
||||
|
||||
PackManifestFactory(MinecraftEventing& ev) {
|
||||
PackManifestFactory_construct(this, ev);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class ResourcePackRepository {
|
||||
|
||||
public:
|
||||
|
||||
char filler[0x1C];
|
||||
ResourcePack* vanillaPack;
|
||||
char filler2[0x200];
|
||||
|
||||
static void (*ResourcePackRepository_construct)(ResourcePackRepository*, MinecraftEventing&, PackManifestFactory&, EntitlementManager*, FilePathManager*);
|
||||
|
||||
ResourcePackRepository(MinecraftEventing& ev, PackManifestFactory& factory, EntitlementManager* em, FilePathManager* fpm) {
|
||||
ResourcePackRepository_construct(this, ev, factory, em, fpm);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class ResourcePackManager: public ResourceLoader {
|
||||
|
||||
public:
|
||||
|
||||
char filler[0x200];
|
||||
|
||||
static void (*ResourcePackManager_construct)(ResourcePackManager*, std::function<mcpe::string ()> const);
|
||||
static void (*ResourcePackManager_setStack)(ResourcePackManager*, std::unique_ptr<ResourcePackStack>, ResourcePackStackType, bool);
|
||||
|
||||
ResourcePackManager(std::function<mcpe::string ()> const& f) {
|
||||
ResourcePackManager_construct(this, f);
|
||||
}
|
||||
|
||||
void setStack(std::unique_ptr<ResourcePackStack>&& stackPtr, ResourcePackStackType stackType, bool b) {
|
||||
ResourcePackManager_setStack(this, std::move(stackPtr), stackType, b);
|
||||
}
|
||||
};
|
||||
24
mcpe/ResourcePackStack.h
Normal file
24
mcpe/ResourcePackStack.h
Normal file
@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstring>
|
||||
|
||||
class ResourcePack;
|
||||
class ResourcePackRepository;
|
||||
|
||||
struct ResourcePackStack {
|
||||
|
||||
static void** vtable_sym;
|
||||
static void (*ResourcePackStack_add)(ResourcePackStack*, ResourcePack*, ResourcePackRepository const&, bool);
|
||||
|
||||
void** vtable;
|
||||
char filler[0x30];
|
||||
|
||||
ResourcePackStack() {
|
||||
vtable = vtable_sym + 2;
|
||||
memset(filler, 0, sizeof(filler));
|
||||
}
|
||||
|
||||
void add(ResourcePack* resPack, ResourcePackRepository const& repo, bool b) {
|
||||
ResourcePackStack_add(this, resPack, repo, b);
|
||||
}
|
||||
};
|
||||
17
mcpe/Scheduler.h
Normal file
17
mcpe/Scheduler.h
Normal file
@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include <chrono>
|
||||
|
||||
struct Scheduler {
|
||||
|
||||
public:
|
||||
|
||||
static Scheduler* (*singleton)();
|
||||
static void (*Scheduler_processCoroutines)(Scheduler*, std::chrono::duration<long long>);
|
||||
|
||||
void processCoroutines(std::chrono::duration<long long> d) {
|
||||
Scheduler_processCoroutines(this, d);
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
64
mcpe/ServerInstance.h
Normal file
64
mcpe/ServerInstance.h
Normal file
@ -0,0 +1,64 @@
|
||||
#pragma once
|
||||
|
||||
#include <chrono>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <functional>
|
||||
|
||||
#include "string.h"
|
||||
|
||||
class IMinecraftApp;
|
||||
class Minecraft;
|
||||
class Whitelist;
|
||||
class OpsList;
|
||||
class LevelSettings;
|
||||
class FilePathManager;
|
||||
|
||||
namespace minecraft { namespace api { class Api; } }
|
||||
namespace mce { class UUID; }
|
||||
|
||||
class MinecraftEventing;
|
||||
class ResourcePackRepository;
|
||||
class ResourcePackManager;
|
||||
|
||||
class ServerInstance {
|
||||
|
||||
public:
|
||||
char filler[0x300];
|
||||
|
||||
static void (*ServerInstance_construct)(
|
||||
ServerInstance*,
|
||||
IMinecraftApp&,
|
||||
Whitelist const&,
|
||||
OpsList const&,
|
||||
FilePathManager*,
|
||||
std::chrono::duration<long long>,
|
||||
mcpe::string,
|
||||
mcpe::string,
|
||||
mcpe::string,
|
||||
mcpe::string,
|
||||
mcpe::string,
|
||||
LevelSettings*,
|
||||
minecraft::api::Api&,
|
||||
int,
|
||||
bool,
|
||||
int,
|
||||
int,
|
||||
int,
|
||||
bool,
|
||||
std::vector<mcpe::string> const&,
|
||||
mcpe::string,
|
||||
bool,
|
||||
mce::UUID const&,
|
||||
MinecraftEventing&,
|
||||
ResourcePackRepository&,
|
||||
ResourcePackManager&,
|
||||
ResourcePackManager*
|
||||
);
|
||||
|
||||
static void (*ServerInstance_update)(ServerInstance*);
|
||||
|
||||
void update() {
|
||||
ServerInstance_update(this);
|
||||
}
|
||||
};
|
||||
37
mcpe/Social.h
Normal file
37
mcpe/Social.h
Normal file
@ -0,0 +1,37 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <cstring>
|
||||
|
||||
class ScreenStack;
|
||||
|
||||
namespace Social {
|
||||
|
||||
class XboxLiveUserManager {
|
||||
public:
|
||||
char filler[0x100];
|
||||
|
||||
static void (*XboxLiveUserManager_construct)(XboxLiveUserManager*, ScreenStack*);
|
||||
|
||||
XboxLiveUserManager() {
|
||||
XboxLiveUserManager_construct(this, nullptr);
|
||||
}
|
||||
};
|
||||
|
||||
class UserManager {
|
||||
public:
|
||||
char filler[0x100];
|
||||
|
||||
static void (*UserManager_construct)(UserManager*);
|
||||
static void (*UserManager_addUser)(UserManager*, std::unique_ptr<Social::XboxLiveUserManager>, bool);
|
||||
|
||||
UserManager() {
|
||||
UserManager_construct(this);
|
||||
}
|
||||
|
||||
void addUser(std::unique_ptr<Social::XboxLiveUserManager> manager) {
|
||||
UserManager_addUser(this, std::move(manager), false);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
14
mcpe/UUID.h
Normal file
14
mcpe/UUID.h
Normal file
@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
namespace mce {
|
||||
|
||||
class UUID {
|
||||
|
||||
public:
|
||||
|
||||
static UUID* EMPTY;
|
||||
char filler[0x14];
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
11
mcpe/Whitelist.h
Normal file
11
mcpe/Whitelist.h
Normal file
@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
struct Whitelist {
|
||||
|
||||
struct Entry {
|
||||
char filler[0x20];
|
||||
};
|
||||
|
||||
std::vector<Entry> entries;
|
||||
|
||||
};
|
||||
@ -1,10 +1,11 @@
|
||||
#pragma once
|
||||
#include "string.h"
|
||||
|
||||
struct gl {
|
||||
static std::string (*getOpenGLVendor)();
|
||||
static std::string (*getOpenGLRenderer)();
|
||||
static std::string (*getOpenGLVersion)();
|
||||
static std::string (*getOpenGLExtensions)();
|
||||
static mcpe::string (*getOpenGLVendor)();
|
||||
static mcpe::string (*getOpenGLRenderer)();
|
||||
static mcpe::string (*getOpenGLVersion)();
|
||||
static mcpe::string (*getOpenGLExtensions)();
|
||||
};
|
||||
|
||||
namespace mce {
|
||||
|
||||
79
mcpe/string.cpp
Normal file
79
mcpe/string.cpp
Normal file
@ -0,0 +1,79 @@
|
||||
#define _GLIBCXX_USE_CXX11_ABI 0
|
||||
#include "string.h"
|
||||
|
||||
mcpe::string* mcpe::string::empty;
|
||||
|
||||
mcpe::string::string() {
|
||||
ptr = empty->ptr;
|
||||
}
|
||||
|
||||
mcpe::string::string(const char *str) {
|
||||
if (str[0] == '\0') {
|
||||
ptr = empty->ptr;
|
||||
} else {
|
||||
new (this) std::string(str);
|
||||
}
|
||||
}
|
||||
|
||||
mcpe::string::string(const char *str, size_t len) {
|
||||
if (len == 0) {
|
||||
ptr = empty->ptr;
|
||||
} else {
|
||||
new (this) std::string(str, len);
|
||||
}
|
||||
}
|
||||
|
||||
mcpe::string::string(const string &str) {
|
||||
if (str.ptr == empty->ptr) {
|
||||
ptr = empty->ptr;
|
||||
} else {
|
||||
new (this) std::string(*((const std::string *) &str));
|
||||
}
|
||||
}
|
||||
|
||||
mcpe::string::~string() {
|
||||
if (ptr == empty->ptr)
|
||||
return;
|
||||
((std::string*) this)->~basic_string<char>();
|
||||
}
|
||||
|
||||
size_t mcpe::string::length() const {
|
||||
if (ptr == empty->ptr)
|
||||
return 0;
|
||||
return ((std::string*) this)->length();
|
||||
}
|
||||
|
||||
mcpe::string mcpe::string::operator+(const string &str) {
|
||||
return *((std::string*) this) + *((std::string*) &str);
|
||||
}
|
||||
|
||||
mcpe::string& mcpe::string::operator=(const mcpe::string &str) {
|
||||
if (this == &str)
|
||||
return *this;
|
||||
|
||||
if (ptr != empty->ptr) {
|
||||
if (str.ptr == empty->ptr) {
|
||||
((std::string*) this)->~basic_string<char>();
|
||||
ptr = empty->ptr;
|
||||
} else {
|
||||
*((std::string*) this) = *((const std::string*) &str);
|
||||
}
|
||||
} else {
|
||||
if (str.ptr != empty->ptr) {
|
||||
new (this) std::string(*((const std::string*)&str));
|
||||
}
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
const char *mcpe::string::c_str() const {
|
||||
if (ptr == empty->ptr)
|
||||
return "";
|
||||
return ((std::string*) this)->c_str();
|
||||
}
|
||||
|
||||
std::ostream& operator<< (std::ostream& os, const mcpe::string& obj) {
|
||||
os << *((std::string const*) &obj);
|
||||
return os;
|
||||
}
|
||||
53
mcpe/string.h
Normal file
53
mcpe/string.h
Normal file
@ -0,0 +1,53 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
|
||||
namespace mcpe {
|
||||
|
||||
struct string {
|
||||
|
||||
private:
|
||||
void* ptr;
|
||||
|
||||
public:
|
||||
static mcpe::string* empty;
|
||||
|
||||
string();
|
||||
string(const char *str);
|
||||
string(const char *str, size_t len);
|
||||
string(const string &str);
|
||||
inline string(const std::string &str) : string(str.c_str(), str.length()) {}
|
||||
~string();
|
||||
|
||||
string &operator=(const string &str);
|
||||
|
||||
size_t length() const;
|
||||
const char *c_str() const;
|
||||
|
||||
string operator+(const string &str);
|
||||
|
||||
bool operator==(const string &s) const {
|
||||
if (s.ptr == ptr)
|
||||
return true;
|
||||
if (s.length() != length())
|
||||
return false;
|
||||
return (memcmp(c_str(), s.c_str(), length()) == 0);
|
||||
}
|
||||
|
||||
bool operator<(const string& s) const {
|
||||
int d = memcmp(c_str(), s.c_str(), std::min(length(), s.length()));
|
||||
if (d < 0) return true;
|
||||
if (d == 0) return length() < s.length();
|
||||
return false;
|
||||
}
|
||||
|
||||
inline std::string std() const {
|
||||
return std::string(c_str(), length());
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream&, const mcpe::string&);
|
||||
104
mcpe/types.cpp
104
mcpe/types.cpp
@ -28,10 +28,10 @@ void (*Options::Options_setFullscreen)(Options*, bool);
|
||||
|
||||
#include "gl.h"
|
||||
|
||||
std::string (*gl::getOpenGLVendor)();
|
||||
std::string (*gl::getOpenGLRenderer)();
|
||||
std::string (*gl::getOpenGLVersion)();
|
||||
std::string (*gl::getOpenGLExtensions)();
|
||||
mcpe::string (*gl::getOpenGLVendor)();
|
||||
mcpe::string (*gl::getOpenGLRenderer)();
|
||||
mcpe::string (*gl::getOpenGLVersion)();
|
||||
mcpe::string (*gl::getOpenGLExtensions)();
|
||||
void (*mce::Platform::OGL::OGL_initBindings)();
|
||||
|
||||
#include "Mouse.h"
|
||||
@ -40,6 +40,100 @@ void (*Mouse::feed)(char, char, short, short, short, short);
|
||||
|
||||
#include "Keyboard.h"
|
||||
|
||||
void (*Keyboard::Keyboard_feedText)(const std::string&, bool, unsigned char);
|
||||
void (*Keyboard::Keyboard_feedText)(const mcpe::string&, bool, unsigned char);
|
||||
std::vector<KeyboardAction>* Keyboard::inputs;
|
||||
int* Keyboard::states;
|
||||
|
||||
#include "FilePathManager.h"
|
||||
|
||||
void (*FilePathManager::FilePathManager_construct)(FilePathManager*, mcpe::string, bool);
|
||||
mcpe::string (*FilePathManager::FilePathManager_getRootPath)(FilePathManager const*);
|
||||
mcpe::string (*FilePathManager::FilePathManager_getUserDataPath)(FilePathManager const*);
|
||||
void (*FilePathManager::FilePathManager_setPackagePath)(FilePathManager*, mcpe::string);
|
||||
mcpe::string (*FilePathManager::FilePathManager_getPackagePath)(FilePathManager const*);
|
||||
void (*FilePathManager::FilePathManager_setSettingsPath)(FilePathManager*, mcpe::string);
|
||||
mcpe::string (*FilePathManager::FilePathManager_getSettingsPath)(FilePathManager const*);
|
||||
|
||||
#include "LevelSettings.h"
|
||||
|
||||
void (*LevelSettings::LevelSettings_construct)(LevelSettings*);
|
||||
|
||||
#include "Social.h"
|
||||
|
||||
void (*Social::UserManager::UserManager_construct)(Social::UserManager*);
|
||||
void (*Social::UserManager::UserManager_addUser)(UserManager*, std::unique_ptr<Social::XboxLiveUserManager>, bool);
|
||||
void (*Social::XboxLiveUserManager::XboxLiveUserManager_construct)(Social::XboxLiveUserManager*, ScreenStack*);
|
||||
|
||||
#include "MinecraftEventing.h"
|
||||
|
||||
void (*MinecraftEventing::MinecraftEventing_construct)(MinecraftEventing*, mcpe::string const&);
|
||||
|
||||
#include "EntitlementManager.h"
|
||||
|
||||
void (*EntitlementManager::EntitlementManager_construct)(EntitlementManager*, MinecraftEventing&, Social::UserManager&);
|
||||
|
||||
#include "Resource.h"
|
||||
|
||||
void (*Resource::Resource_registerLoader)(ResourceFileSystem, std::unique_ptr<ResourceLoader>);
|
||||
|
||||
#include "AppResourceLoader.h"
|
||||
|
||||
void (*AppResourceLoader::AppResourceLoader_construct)(AppResourceLoader*, std::function<mcpe::string ()>);
|
||||
|
||||
#include "ResourcePack.h"
|
||||
|
||||
void (*PackManifestFactory::PackManifestFactory_construct)(PackManifestFactory*, MinecraftEventing&);
|
||||
void (*ResourcePackRepository::ResourcePackRepository_construct)(ResourcePackRepository*, MinecraftEventing&, PackManifestFactory&, EntitlementManager*, FilePathManager*);
|
||||
void (*ResourcePackManager::ResourcePackManager_construct)(ResourcePackManager*, std::function<mcpe::string ()> const);
|
||||
void (*ResourcePackManager::ResourcePackManager_setStack)(ResourcePackManager*, std::unique_ptr<ResourcePackStack>, ResourcePackStackType, bool);
|
||||
|
||||
#include "AutomationClient.h"
|
||||
|
||||
void (*Automation::AutomationClient::AutomationClient_construct)(Automation::AutomationClient*, IMinecraftApp&);
|
||||
|
||||
#include "ServerInstance.h"
|
||||
|
||||
void (*ServerInstance::ServerInstance_construct)(
|
||||
ServerInstance*,
|
||||
IMinecraftApp&,
|
||||
Whitelist const&,
|
||||
OpsList const&,
|
||||
FilePathManager*,
|
||||
std::chrono::duration<long long>,
|
||||
mcpe::string,
|
||||
mcpe::string,
|
||||
mcpe::string,
|
||||
mcpe::string,
|
||||
mcpe::string,
|
||||
LevelSettings*,
|
||||
minecraft::api::Api&,
|
||||
int,
|
||||
bool,
|
||||
int,
|
||||
int,
|
||||
int,
|
||||
bool,
|
||||
std::vector<mcpe::string> const&,
|
||||
mcpe::string,
|
||||
bool,
|
||||
mce::UUID const&,
|
||||
MinecraftEventing&,
|
||||
ResourcePackRepository&,
|
||||
ResourcePackManager&,
|
||||
ResourcePackManager*
|
||||
);
|
||||
void (*ServerInstance::ServerInstance_update)(ServerInstance*);
|
||||
|
||||
#include "UUID.h"
|
||||
|
||||
mce::UUID* mce::UUID::EMPTY;
|
||||
|
||||
#include "ResourcePackStack.h"
|
||||
|
||||
void (*ResourcePackStack::ResourcePackStack_add)(ResourcePackStack*, ResourcePack*, ResourcePackRepository const&, bool);
|
||||
void** ResourcePackStack::vtable_sym;
|
||||
|
||||
#include "Scheduler.h"
|
||||
|
||||
Scheduler* (*Scheduler::singleton)();
|
||||
void (*Scheduler::Scheduler_processCoroutines)(Scheduler*, std::chrono::duration<long long>);
|
||||
12
server.properties
Normal file
12
server.properties
Normal file
@ -0,0 +1,12 @@
|
||||
motd=Test
|
||||
view-distance=22
|
||||
server-port=19132
|
||||
server-port-v6=19133
|
||||
max-players=20
|
||||
online-mode=false
|
||||
difficulty=1
|
||||
gamemode=0
|
||||
level-dir=oI8CAKp7BQA=
|
||||
level-name=My World
|
||||
level-seed=3986400852
|
||||
level-type=1
|
||||
@ -1,5 +1,6 @@
|
||||
#include "common.h"
|
||||
|
||||
#include <filesystem>
|
||||
#include <cstdio>
|
||||
#include <cstdarg>
|
||||
#include <cstring>
|
||||
@ -14,14 +15,25 @@ extern "C" {
|
||||
#include "../hybris/include/hybris/dlfcn.h"
|
||||
}
|
||||
|
||||
std::string getCWD() {
|
||||
char _cwd[MAXPATHLEN];
|
||||
getcwd(_cwd, MAXPATHLEN);
|
||||
return std::string(_cwd) + "/";
|
||||
std::string rootPath = "";
|
||||
|
||||
std::string getRootPath() {
|
||||
char resolved[PATH_MAX];
|
||||
const char* input = rootPath.empty() ? "." : rootPath.c_str();
|
||||
|
||||
if (realpath(input, resolved) == nullptr) {
|
||||
getcwd(resolved, PATH_MAX);
|
||||
}
|
||||
|
||||
std::string result(resolved);
|
||||
if (!result.empty() && result.back() != '/')
|
||||
result += '/';
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool loadLibrary(std::string path) {
|
||||
void* handle = hybris_dlopen((getCWD() + "libs/" + path).c_str(), RTLD_LAZY);
|
||||
void* handle = hybris_dlopen((getRootPath() + "libs/" + path).c_str(), RTLD_LAZY);
|
||||
if (handle == nullptr) {
|
||||
printf("failed to load library %s: %s\n", path.c_str(), hybris_dlerror());
|
||||
return false;
|
||||
@ -49,7 +61,7 @@ void* loadLibraryOS(std::string path, const char** symbols) {
|
||||
}
|
||||
|
||||
void* loadMod(std::string path) {
|
||||
void* handle = hybris_dlopen((getCWD() + "mods/" + path).c_str(), RTLD_LAZY);
|
||||
void* handle = hybris_dlopen((getRootPath() + "mods/" + path).c_str(), RTLD_LAZY);
|
||||
if (handle == nullptr) {
|
||||
printf("failed to load mod: %s\n", path.c_str());
|
||||
return nullptr;
|
||||
|
||||
@ -2,7 +2,9 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
std::string getCWD();
|
||||
extern std::string rootPath;
|
||||
|
||||
std::string getRootPath();
|
||||
bool loadLibrary(std::string path);
|
||||
void* loadLibraryOS(std::string path, const char** symbols);
|
||||
void* loadMod(std::string path);
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
#include "LinuxAppPlatform.h"
|
||||
#include "linux_app_platform.h"
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
@ -14,24 +14,25 @@
|
||||
#include "../hybris/src/jb/linker.h"
|
||||
|
||||
extern "C" {
|
||||
#ifndef SERVER
|
||||
#include <eglut.h>
|
||||
#endif
|
||||
#include "../hybris/include/hybris/dlfcn.h"
|
||||
}
|
||||
|
||||
void** LinuxAppPlatform::myVtable = nullptr;
|
||||
bool LinuxAppPlatform::mousePointerHidden = false;
|
||||
bool enablePocketGuis = false;
|
||||
bool serverMode = false;
|
||||
|
||||
LinuxAppPlatform::LinuxAppPlatform() : AppPlatform() {
|
||||
this->vtable = myVtable;
|
||||
internalStorage = "data/private/";
|
||||
externalStorage = "data/public/";
|
||||
currentStorage = "data/current/";
|
||||
userdata = "data/user/";
|
||||
userdataPathForLevels = "data/user/";
|
||||
internalStorage = getRootPath() + "data/private/";
|
||||
externalStorage = getRootPath() + "data/public/";
|
||||
currentStorage = getRootPath() + "data/current/";
|
||||
userdata = getRootPath() + "data/user/";
|
||||
userdataPathForLevels = getRootPath() + "data/user/";
|
||||
region = "0xdeadbeef";
|
||||
tmpPath = "tmp/";
|
||||
tmpPath = getRootPath() + "tmp/";
|
||||
}
|
||||
|
||||
#include <execinfo.h>
|
||||
@ -99,12 +100,16 @@ void LinuxAppPlatform::initVtable(void* lib) {
|
||||
|
||||
void LinuxAppPlatform::hideMousePointer() {
|
||||
mousePointerHidden = true;
|
||||
#ifndef SERVER
|
||||
moveMouseToCenter = true;
|
||||
eglutSetMousePointerVisiblity(EGLUT_POINTER_INVISIBLE);
|
||||
#endif
|
||||
}
|
||||
void LinuxAppPlatform::showMousePointer() {
|
||||
mousePointerHidden = false;
|
||||
#ifndef SERVER
|
||||
eglutSetMousePointerVisiblity(EGLUT_POINTER_VISIBLE);
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string LinuxAppPlatform::_pickFile(std::string commandLine) {
|
||||
@ -149,7 +154,7 @@ void LinuxAppPlatform::pickFile(FilePickerSettings &settings) {
|
||||
std::cout << " - " << d.ext << " " << d.desc << "\n";
|
||||
}
|
||||
std::stringstream ss;
|
||||
ss << "zenity --file-selection --title '" << replaceAll(settings.pickerTitle, "'", "\\'") << "'";
|
||||
//ss << "zenity --file-selection --title '" << replaceAll(settings.pickerTitle, "'", "\\'") << "'";
|
||||
if (settings.type == FilePickerSettings::PickerType::SAVE)
|
||||
ss << " --save";
|
||||
if (settings.fileDescriptions.size() > 0) {
|
||||
@ -170,9 +175,11 @@ void LinuxAppPlatform::pickFile(FilePickerSettings &settings) {
|
||||
|
||||
void LinuxAppPlatform::setFullscreenMode(int mode) {
|
||||
std::cout << "set fullscreen mode: " << mode << "\n";
|
||||
#ifndef SERVER
|
||||
int newMode = mode == 1 ? EGLUT_FULLSCREEN : EGLUT_WINDOWED;
|
||||
if (eglutGet(EGLUT_FULLSCREEN_MODE) != newMode)
|
||||
eglutToggleFullscreen();
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string LinuxAppPlatform::createUUID() {
|
||||
@ -6,6 +6,7 @@
|
||||
#include "../mcpe/gl.h"
|
||||
#include "../mcpe/AppPlatform.h"
|
||||
#include "../mcpe/ImagePickingCallback.h"
|
||||
#include "common.h"
|
||||
|
||||
class ImageData;
|
||||
class ImagePickingCallback;
|
||||
@ -13,7 +14,6 @@ class FilePickerSettings;
|
||||
|
||||
extern bool enablePocketGuis;
|
||||
extern bool moveMouseToCenter;
|
||||
extern bool serverMode;
|
||||
|
||||
class LinuxAppPlatform : public AppPlatform {
|
||||
|
||||
@ -35,15 +35,15 @@ public:
|
||||
|
||||
std::string getDataUrl() { // this is used only for sounds
|
||||
printf("get data url: assets/\n");
|
||||
return "assets/";
|
||||
return getRootPath() + "assets/";
|
||||
}
|
||||
std::string getUserDataUrl() { // this is used only for sounds
|
||||
printf("get user data url: data/user/\n");
|
||||
return "data/user/";
|
||||
return getRootPath() + "data/user/";
|
||||
}
|
||||
|
||||
std::string getPackagePath() {
|
||||
return "assets/";
|
||||
return getRootPath() + "assets/";
|
||||
}
|
||||
|
||||
void hideMousePointer();
|
||||
@ -88,7 +88,7 @@ public:
|
||||
}
|
||||
std::string getAssetFileFullPath(std::string const& s) {
|
||||
printf("get assert full path: %s\n", s.c_str());
|
||||
return "assets/" + s;
|
||||
return getRootPath() + "assets/" + s;
|
||||
}
|
||||
int getScreenType() {
|
||||
if (enablePocketGuis)
|
||||
44
src/main.cpp
44
src/main.cpp
@ -13,16 +13,23 @@
|
||||
#include "android_symbols.h"
|
||||
#include "egl_symbols.h"
|
||||
#include "fmod_symbols.h"
|
||||
#include "linux_app_platform.h"
|
||||
#include "LinuxStore.h"
|
||||
#include "common.h"
|
||||
#include "hook.h"
|
||||
|
||||
#include "../mcpe/gl.h"
|
||||
#include "../mcpe/AppPlatform.h"
|
||||
#include "../mcpe/MinecraftGame.h"
|
||||
#include "LinuxAppPlatform.h"
|
||||
#include "LinuxStore.h"
|
||||
#include "../mcpe/Mouse.h"
|
||||
#include "../mcpe/Keyboard.h"
|
||||
#include "../mcpe/Options.h"
|
||||
#include "common.h"
|
||||
#include "hook.h"
|
||||
#include "../mcpe/Whitelist.h"
|
||||
#include "../mcpe/OpsList.h"
|
||||
#include "../mcpe/LevelSettings.h"
|
||||
#include "../mcpe/UUID.h"
|
||||
#include "../mcpe/ServerInstance.h"
|
||||
#include "../mcpe/FilePathManager.h"
|
||||
|
||||
extern "C" {
|
||||
|
||||
@ -33,8 +40,6 @@ extern "C" {
|
||||
|
||||
}
|
||||
|
||||
void commonStub() {}
|
||||
|
||||
void androidStub() {
|
||||
std::cout << "warn: android call\n";
|
||||
}
|
||||
@ -218,28 +223,29 @@ int main(int argc, char *argv[]) {
|
||||
} else if (strcmp(argv[i], "-sw") == 0 || strcmp(argv[i], "--width") == 0) {
|
||||
i++;
|
||||
windowWidth = std::stoi(argv[i]);
|
||||
} else if (strcmp(argv[i], "-sh") == 0 || strcmp(argv[i], "--height") == 0) {
|
||||
} else if (strcmp(argv[i], "-sw") == 0 || strcmp(argv[i], "--width") == 0) {
|
||||
i++;
|
||||
windowHeight = std::stoi(argv[i]);
|
||||
windowWidth = std::stoi(argv[i]);
|
||||
} else if (strcmp(argv[i], "-r") == 0 || strcmp(argv[i], "--root-path") == 0) {
|
||||
i++;
|
||||
rootPath = argv[i];
|
||||
} else if (strcmp(argv[i], "-ns") == 0 || strcmp(argv[i], "--no-stacktrace") == 0) {
|
||||
enableStackTracePrinting = false;
|
||||
} else if (strcmp(argv[i], "--pocket-guis") == 0) {
|
||||
enablePocketGuis = true;
|
||||
} else if (strcmp(argv[i], "--server") == 0) {
|
||||
serverMode = true;
|
||||
} else if (strcmp(argv[i], "--amd-fix") == 0) {
|
||||
std::cout << "--amd-fix: Enabling AMD Workaround.\n";
|
||||
workaroundAMD = true;
|
||||
} else if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) {
|
||||
std::cout << "Help\n";
|
||||
std::cout << "--help Shows this help information\n";
|
||||
std::cout << "--root-path Sets the root path for game data\n";
|
||||
std::cout << "--scale <scale> Sets the pixel scale\n";
|
||||
std::cout << "--width <width> Sets the window width\n";
|
||||
std::cout << "--height <height> Sets the window height\n";
|
||||
std::cout << "--pocket-guis Switches to Pocket Edition GUIs\n";
|
||||
std::cout << "--no-stacktrace Disables stack trace printing\n";
|
||||
std::cout << "--amd-workaround Fixes crashes on pre-i686 and AMD CPUs\n\n";
|
||||
std::cout << "--server Enable dedicated server mode\n\n";
|
||||
std::cout << "EGL Options\n";
|
||||
std::cout << "-display <display> Sets the display\n";
|
||||
std::cout << "-info Shows info about the display\n\n";
|
||||
@ -258,7 +264,7 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
std::cout << "loading native libraries\n";
|
||||
void* glesLib = loadLibraryOS("libGLESv2.so", gles_symbols);
|
||||
void* fmodLib = loadLibraryOS((getCWD() + "libs/native/libfmod.so.8.2").c_str(), fmod_symbols);
|
||||
void* fmodLib = loadLibraryOS((getRootPath() + "libs/native/libfmod.so.8.2").c_str(), fmod_symbols);
|
||||
if (glesLib == nullptr || fmodLib == nullptr)
|
||||
return -1;
|
||||
|
||||
@ -277,7 +283,7 @@ int main(int argc, char *argv[]) {
|
||||
if (!loadLibrary("libmcpelauncher_mod.so"))
|
||||
return -1;
|
||||
std::cout << "loading MCPE\n";
|
||||
std::string mcpePath = getCWD() + "libs/libminecraftpe.so";
|
||||
std::string mcpePath = getRootPath() + "libs/libminecraftpe.so";
|
||||
void* handle = hybris_dlopen(mcpePath.c_str(), RTLD_LAZY);
|
||||
if (handle == nullptr) {
|
||||
std::cout << "failed to load MCPE: " << hybris_dlerror() << "\n";
|
||||
@ -309,6 +315,8 @@ int main(int argc, char *argv[]) {
|
||||
std::cout << "loaded " << mods.size() << " mods\n";
|
||||
}
|
||||
|
||||
mcpe::string::empty = (mcpe::string*) hybris_dlsym(handle, "_ZN4Util12EMPTY_STRINGE");
|
||||
|
||||
std::cout << "apply patches\n";
|
||||
|
||||
/*
|
||||
@ -373,10 +381,10 @@ int main(int argc, char *argv[]) {
|
||||
std::cout << "patches applied!\n";
|
||||
|
||||
// load symbols for gl
|
||||
gl::getOpenGLVendor = (std::string (*)()) hybris_dlsym(handle, "_ZN2gl15getOpenGLVendorEv");
|
||||
gl::getOpenGLRenderer = (std::string (*)()) hybris_dlsym(handle, "_ZN2gl17getOpenGLRendererEv");
|
||||
gl::getOpenGLVersion = (std::string (*)()) hybris_dlsym(handle, "_ZN2gl16getOpenGLVersionEv");
|
||||
gl::getOpenGLExtensions = (std::string (*)()) hybris_dlsym(handle, "_ZN2gl19getOpenGLExtensionsEv");
|
||||
gl::getOpenGLVendor = (mcpe::string (*)()) hybris_dlsym(handle, "_ZN2gl15getOpenGLVendorEv");
|
||||
gl::getOpenGLRenderer = (mcpe::string (*)()) hybris_dlsym(handle, "_ZN2gl17getOpenGLRendererEv");
|
||||
gl::getOpenGLVersion = (mcpe::string (*)()) hybris_dlsym(handle, "_ZN2gl16getOpenGLVersionEv");
|
||||
gl::getOpenGLExtensions = (mcpe::string (*)()) hybris_dlsym(handle, "_ZN2gl19getOpenGLExtensionsEv");
|
||||
mce::Platform::OGL::OGL_initBindings = (void (*)()) hybris_dlsym(handle, "_ZN3mce8Platform3OGL12InitBindingsEv");
|
||||
|
||||
// init linux app platform
|
||||
@ -399,7 +407,7 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
Keyboard::inputs = (std::vector<KeyboardAction>*) hybris_dlsym(handle, "_ZN8Keyboard7_inputsE");
|
||||
Keyboard::states = (int*) hybris_dlsym(handle, "_ZN8Keyboard7_statesE");
|
||||
Keyboard::Keyboard_feedText = (void (*)(const std::string&, bool, unsigned char)) hybris_dlsym(handle, "_ZN8Keyboard8feedTextERKSsbh");
|
||||
Keyboard::Keyboard_feedText = (void (*)(const mcpe::string&, bool, unsigned char)) hybris_dlsym(handle, "_ZN8Keyboard8feedTextERKSsbh");
|
||||
|
||||
Options::Options_getFullscreen = (bool (*)(Options*)) hybris_dlsym(handle, "_ZNK7Options13getFullscreenEv");
|
||||
Options::Options_setFullscreen = (void (*)(Options*, bool)) hybris_dlsym(handle, "_ZN7Options13setFullscreenEb");
|
||||
|
||||
297
src/server.cpp
297
src/server.cpp
@ -0,0 +1,297 @@
|
||||
#include <iostream>
|
||||
#include <dlfcn.h>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <chrono>
|
||||
#include <fstream>
|
||||
#include "gles_symbols.h"
|
||||
#include "android_symbols.h"
|
||||
#include "egl_symbols.h"
|
||||
#include "fmod_symbols.h"
|
||||
#include "linux_app_platform.h"
|
||||
#include "common.h"
|
||||
#include "hook.h"
|
||||
#include "server_minecraft_app.h"
|
||||
#include "server_properties.h"
|
||||
|
||||
#include "../mcpe/Api.h"
|
||||
#include "../mcpe/AppPlatform.h"
|
||||
#include "../mcpe/FilePathManager.h"
|
||||
#include "../mcpe/LevelSettings.h"
|
||||
#include "../mcpe/Social.h"
|
||||
#include "../mcpe/MinecraftEventing.h"
|
||||
#include "../mcpe/EntitlementManager.h"
|
||||
#include "../mcpe/AppResourceLoader.h"
|
||||
#include "../mcpe/Resource.h"
|
||||
#include "../mcpe/ResourcePack.h"
|
||||
#include "../mcpe/AutomationClient.h"
|
||||
#include "../mcpe/ServerInstance.h"
|
||||
#include "../mcpe/Whitelist.h"
|
||||
#include "../mcpe/OpsList.h"
|
||||
#include "../mcpe/UUID.h"
|
||||
#include "../mcpe/ResourcePackStack.h"
|
||||
#include "../mcpe/Scheduler.h"
|
||||
|
||||
extern "C" {
|
||||
|
||||
#include "../hybris/include/hybris/dlfcn.h"
|
||||
#include "../hybris/include/hybris/hook.h"
|
||||
#include "../hybris/src/jb/linker.h"
|
||||
|
||||
}
|
||||
|
||||
void stubFunc() {}
|
||||
|
||||
void detachFromJavaStub() {
|
||||
std::cout << "detach from java\n";
|
||||
}
|
||||
|
||||
void* getJVMEnvStub() {
|
||||
std::cout << "getjvmenv\n";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int getDifficultyStub() {
|
||||
return ServerProperties::instance().getInt("difficulty", 0);
|
||||
}
|
||||
|
||||
int getGameTypeStub() {
|
||||
return ServerProperties::instance().getInt("gamemode", 0);
|
||||
}
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
for (int i = 1; i < argc; i++) {
|
||||
if ((strcmp(argv[i], "-r") == 0 || strcmp(argv[i], "--root-path") == 0) && i + 1 < argc) {
|
||||
rootPath = argv[i + 1];
|
||||
i++;
|
||||
}
|
||||
}
|
||||
if (rootPath.empty()) {
|
||||
std::cout << "[*] No root path set, the current directory will be used to store game data\n";
|
||||
std::cout << "[*] It is recommended to set one by using the `--root-path` argument\n";
|
||||
}
|
||||
|
||||
// load properties
|
||||
std::ifstream propertiesFile(getRootPath() + "server.properties");
|
||||
if (propertiesFile) {
|
||||
ServerProperties::instance().load(propertiesFile);
|
||||
} else {
|
||||
std::cerr << "[!] No server.properties file found, cannot continue\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
registerCrashHandler();
|
||||
setenv("LC_ALL", "C", 1);
|
||||
|
||||
std::cout << "loading native libraries\n";
|
||||
void* glesLib = loadLibraryOS("libGLESv2.so", gles_symbols);
|
||||
void* fmodLib = loadLibraryOS((getRootPath() + "libs/native/libfmod.so.8.2").c_str(), fmod_symbols);
|
||||
if (glesLib == nullptr || fmodLib == nullptr)
|
||||
return -1;
|
||||
|
||||
std::cout << "loading hybris libraries\n";
|
||||
stubSymbols(android_symbols, (void*)stubFunc);
|
||||
stubSymbols(egl_symbols, (void*)stubFunc);
|
||||
stubSymbols(gles_symbols, (void*)stubFunc);
|
||||
stubSymbols(fmod_symbols, (void*)stubFunc);
|
||||
hybris_hook("eglGetProcAddress", (void*) stubFunc);
|
||||
hookAndroidLog();
|
||||
|
||||
if (!loadLibrary("libc.so") || !loadLibrary("libstdc++.so") || !loadLibrary("libm.so") || !loadLibrary("libz.so"))
|
||||
return -1;
|
||||
// load stub libraries
|
||||
if (!loadLibrary("libandroid.so") || !loadLibrary("liblog.so") || !loadLibrary("libEGL.so") || !loadLibrary("libGLESv2.so") || !loadLibrary("libOpenSLES.so") || !loadLibrary("libfmod.so") || !loadLibrary("libGLESv1_CM.so"))
|
||||
return -1;
|
||||
if (!loadLibrary("libmcpelauncher_mod.so"))
|
||||
return -1;
|
||||
std::cout << "loading MCPE\n";
|
||||
std::string mcpePath = getRootPath() + "libs/libminecraftpe.so";
|
||||
void* handle = hybris_dlopen(mcpePath.c_str(), RTLD_LAZY);
|
||||
if (handle == nullptr) {
|
||||
std::cout << "failed to load MCPE: " << hybris_dlerror() << "\n";
|
||||
return -1;
|
||||
}
|
||||
addHookLibrary(handle, mcpePath);
|
||||
|
||||
unsigned int libBase = ((soinfo*) handle)->base;
|
||||
std::cout << "loaded MCPE (at " << libBase << ")\n";
|
||||
|
||||
std::cout << "apply patches\n";
|
||||
|
||||
unsigned int patchOff = (unsigned int) hybris_dlsym(handle, "_ZN9crossplat10threadpool16detach_from_javaEPv");
|
||||
patchCallInstruction((void*) patchOff, (void*) &detachFromJavaStub, true);
|
||||
|
||||
patchOff = (unsigned int) hybris_dlsym(handle, "_ZN9crossplat11get_jvm_envEv");
|
||||
patchCallInstruction((void*) patchOff, (void*) &getJVMEnvStub, true);
|
||||
|
||||
// murdle: these functions seem to be returning garbage data and fucking stuff up so i will just stub them
|
||||
// it's probably something related to levelsettings but it is 4 am and i want to sleep
|
||||
// at this point it's easier to just do this than spend 3 more days debugging
|
||||
|
||||
patchOff = (unsigned int) hybris_dlsym(handle, "_ZNK5Level13getDifficultyEv");
|
||||
patchCallInstruction((void*) patchOff, (void*) &getDifficultyStub, true);
|
||||
|
||||
patchOff = (unsigned int) hybris_dlsym(handle, "_ZNK9LevelData11getGameTypeEv");
|
||||
patchCallInstruction((void*) patchOff, (void*) &getGameTypeStub, true);
|
||||
|
||||
mcpe::string::empty = (mcpe::string*) hybris_dlsym(handle, "_ZN4Util12EMPTY_STRINGE");
|
||||
|
||||
std::cout << "patches applied!\n";
|
||||
|
||||
// init linux app platform
|
||||
AppPlatform::myVtable = (void**) hybris_dlsym(handle, "_ZTV11AppPlatform");
|
||||
AppPlatform::_singleton = (AppPlatform**) hybris_dlsym(handle, "_ZN11AppPlatform10mSingletonE");
|
||||
AppPlatform::AppPlatform_construct = (void (*)(AppPlatform*)) hybris_dlsym(handle, "_ZN11AppPlatformC2Ev");
|
||||
AppPlatform::AppPlatform_initialize = (void (*)(AppPlatform*)) hybris_dlsym(handle, "_ZN11AppPlatform10initializeEv");
|
||||
AppPlatform::AppPlatform__fireAppFocusGained = (void (*)(AppPlatform*)) hybris_dlsym(handle, "_ZN11AppPlatform19_fireAppFocusGainedEv");
|
||||
|
||||
void** ptr = (void**) hybris_dlsym(handle, "_ZN9crossplat3JVME");
|
||||
*ptr = (void*) 1; // this just needs not to be null
|
||||
|
||||
// server functions
|
||||
((void*&) mce::UUID::EMPTY) = hybris_dlsym(handle, "_ZN3mce4UUID5EMPTYE");
|
||||
|
||||
((void*&) FilePathManager::FilePathManager_construct) = hybris_dlsym(handle, "_ZN15FilePathManagerC2ESsb");
|
||||
((void*&) FilePathManager::FilePathManager_getRootPath) = hybris_dlsym(handle, "_ZNK15FilePathManager11getRootPathEv");
|
||||
((void*&) FilePathManager::FilePathManager_getUserDataPath) = hybris_dlsym(handle, "_ZNK15FilePathManager15getUserDataPathEv");
|
||||
((void*&) FilePathManager::FilePathManager_setSettingsPath) = hybris_dlsym(handle, "_ZN15FilePathManager15setSettingsPathESs");
|
||||
((void*&) FilePathManager::FilePathManager_getSettingsPath) = hybris_dlsym(handle, "_ZNK15FilePathManager15getSettingsPathEv");
|
||||
((void*&) FilePathManager::FilePathManager_setPackagePath) = hybris_dlsym(handle, "_ZN15FilePathManager14setPackagePathESs");
|
||||
((void*&) FilePathManager::FilePathManager_getPackagePath) = hybris_dlsym(handle, "_ZNK15FilePathManager14getPackagePathEv");
|
||||
|
||||
((void*&) Social::XboxLiveUserManager::XboxLiveUserManager_construct) = hybris_dlsym(handle, "_ZN6Social19XboxLiveUserManagerC2ER11ScreenStack");
|
||||
((void*&) Social::UserManager::UserManager_construct) = hybris_dlsym(handle, "_ZN6Social11UserManagerC2Ev");
|
||||
((void*&) Social::UserManager::UserManager_addUser) = hybris_dlsym(handle, "_ZN6Social11UserManager7addUserESt10unique_ptrINS_19XboxLiveUserManagerESt14default_deleteIS2_EEi");
|
||||
|
||||
((void*&) MinecraftEventing::MinecraftEventing_construct) = hybris_dlsym(handle, "_ZN17MinecraftEventingC2ERKSs");
|
||||
((void*&) EntitlementManager::EntitlementManager_construct) = hybris_dlsym(handle, "_ZN18EntitlementManagerC2ER17MinecraftEventingRN6Social11UserManagerE");
|
||||
((void*&) Automation::AutomationClient::AutomationClient_construct) = hybris_dlsym(handle, "_ZN10Automation16AutomationClientC2ER13IMinecraftApp");
|
||||
((void*&) LevelSettings::LevelSettings_construct) = hybris_dlsym(handle, "_ZN13LevelSettingsC2Ev");
|
||||
|
||||
((void*&) Resource::Resource_registerLoader) = hybris_dlsym(handle, "_ZN8Resource14registerLoaderE18ResourceFileSystemSt10unique_ptrI14ResourceLoaderSt14default_deleteIS2_EE");
|
||||
((void*&) AppResourceLoader::AppResourceLoader_construct) = hybris_dlsym(handle, "_ZN17AppResourceLoaderC2ESt8functionIFSsvEE");
|
||||
|
||||
((void*&) PackManifestFactory::PackManifestFactory_construct) = hybris_dlsym(handle, "_ZN19PackManifestFactoryC2ER17MinecraftEventing");
|
||||
((void*&) ResourcePackManager::ResourcePackManager_construct) = hybris_dlsym(handle, "_ZN19ResourcePackManagerC2ESt8functionIFSsvEE");
|
||||
((void*&) ResourcePackManager::ResourcePackManager_setStack) = hybris_dlsym(handle, "_ZN19ResourcePackManager8setStackESt10unique_ptrI17ResourcePackStackSt14default_deleteIS1_EE21ResourcePackStackTypeb");
|
||||
|
||||
((void*&) ResourcePackStack::vtable_sym) = hybris_dlsym(handle, "_ZTV17ResourcePackStack");
|
||||
((void*&) ResourcePackStack::ResourcePackStack_add) = hybris_dlsym(handle, "_ZN17ResourcePackStack3addEP12ResourcePackRK22ResourcePackRepositoryb");
|
||||
((void*&) ResourcePackRepository::ResourcePackRepository_construct) = hybris_dlsym(handle, "_ZN22ResourcePackRepositoryC2ER17MinecraftEventingR19PackManifestFactoryP18EntitlementManagerP15FilePathManager");
|
||||
|
||||
((void*&) ServerInstance::ServerInstance_construct) = hybris_dlsym(handle, "_ZN14ServerInstanceC2ER13IMinecraftAppRK9WhitelistRK7OpsListP15FilePathManagerNSt6chrono8durationIxSt5ratioILx1ELx1EEEESsSsSsSsSs13LevelSettingsRN9minecraft3api3ApiEibiiibRKSt6vectorISsSaISsEESsbRKN3mce4UUIDER17MinecraftEventingR22ResourcePackRepositoryR19ResourcePackManagerPSX_");
|
||||
((void*&) ServerInstance::ServerInstance_update) = hybris_dlsym(handle, "_ZN14ServerInstance6updateEv");
|
||||
|
||||
((void*&) Scheduler::singleton) = hybris_dlsym(handle, "_ZN9Scheduler9singletonEv");
|
||||
((void*&) Scheduler::Scheduler_processCoroutines) = hybris_dlsym(handle, "_ZN9Scheduler17processCoroutinesEd");
|
||||
|
||||
std::cout << "init app platform vtable\n";
|
||||
LinuxAppPlatform::initVtable(handle);
|
||||
std::cout << "init app platform\n";
|
||||
LinuxAppPlatform* platform = new LinuxAppPlatform();
|
||||
std::cout << "app platform initialized\n";
|
||||
|
||||
platform->initialize();
|
||||
|
||||
Whitelist whitelist;
|
||||
OpsList ops;
|
||||
|
||||
minecraft::api::Api api;
|
||||
api.vtable = (void**)hybris_dlsym(handle, "_ZTVN9minecraft3api3ApiE") + 2;
|
||||
api.envPath = getRootPath();
|
||||
api.playerIfaceVtable = (void**) hybris_dlsym(handle, "_ZTVN9minecraft3api15PlayerInterfaceE") + 2;
|
||||
api.entityIfaceVtable = (void**) hybris_dlsym(handle, "_ZTVN9minecraft3api15EntityInterfaceE") + 2;
|
||||
api.networkIfaceVtable = (void**) hybris_dlsym(handle, "_ZTVN9minecraft3api16NetworkInterfaceE") + 2;
|
||||
api.playerInteractionsIfaceVtable = (void**) hybris_dlsym(handle, "_ZTVN9minecraft3api26PlayerInteractionInterfaceE") + 2;
|
||||
|
||||
FilePathManager pathmgr (platform->getCurrentStoragePath(), false);
|
||||
pathmgr.setPackagePath(platform->getPackagePath());
|
||||
pathmgr.setSettingsPath(pathmgr.getRootPath());
|
||||
|
||||
LevelSettings levelSettings;
|
||||
levelSettings.seed = ServerProperties::instance().getLong("level-seed", 0);
|
||||
levelSettings.gametype = ServerProperties::instance().getInt("gamemode", 0);
|
||||
levelSettings.forceGameType = ServerProperties::instance().getBool("force-gamemode", false);
|
||||
levelSettings.difficulty = ServerProperties::instance().getInt("difficulty", 0);
|
||||
levelSettings.dimension = 0;
|
||||
levelSettings.generator = ServerProperties::instance().getInt("level-type", 1);
|
||||
levelSettings.edu = false;
|
||||
levelSettings.mpGame = true;
|
||||
levelSettings.lanBroadcast = true;
|
||||
levelSettings.commandsEnabled = true;
|
||||
levelSettings.texturepacksRequired = false;
|
||||
|
||||
std::unique_ptr<Social::XboxLiveUserManager> xboxUserManager(
|
||||
new Social::XboxLiveUserManager()
|
||||
);
|
||||
Social::UserManager userManager;
|
||||
userManager.addUser(std::move(xboxUserManager));
|
||||
|
||||
MinecraftEventing eventing(pathmgr.getRootPath());
|
||||
EntitlementManager entManager(eventing, userManager);
|
||||
|
||||
Resource::registerLoader((ResourceFileSystem) 1, std::unique_ptr<ResourceLoader>(new AppResourceLoader([&pathmgr] { return pathmgr.getPackagePath(); })));
|
||||
Resource::registerLoader((ResourceFileSystem) 8, std::unique_ptr<ResourceLoader>(new AppResourceLoader([&pathmgr] { return pathmgr.getUserDataPath(); })));
|
||||
Resource::registerLoader((ResourceFileSystem) 4, std::unique_ptr<ResourceLoader>(new AppResourceLoader([&pathmgr] { return pathmgr.getSettingsPath(); })));
|
||||
|
||||
std::function<std::string()> rootPathFn =
|
||||
[&pathmgr]() -> std::string {
|
||||
return pathmgr.getRootPath().c_str();
|
||||
};
|
||||
|
||||
ResourcePackManager* resourcePackManager = new ResourcePackManager(rootPathFn);
|
||||
Resource::registerLoader((ResourceFileSystem) 0, std::unique_ptr<ResourceLoader>(resourcePackManager));
|
||||
|
||||
PackManifestFactory packManifestFactory(eventing);
|
||||
ResourcePackRepository resourcePackRepo(eventing, packManifestFactory, &entManager, &pathmgr);
|
||||
|
||||
std::unique_ptr<ResourcePackStack> stack(new ResourcePackStack());
|
||||
stack->add(resourcePackRepo.vanillaPack, resourcePackRepo, false);
|
||||
resourcePackManager->setStack(std::move(stack), (ResourcePackStackType) 3, false);
|
||||
|
||||
DedicatedServerMinecraftApp app;
|
||||
Automation::AutomationClient aclient (app);
|
||||
app.automationClient = &aclient;
|
||||
|
||||
ServerInstance server;
|
||||
ServerInstance::ServerInstance_construct(
|
||||
&server,
|
||||
app,
|
||||
whitelist,
|
||||
ops,
|
||||
&pathmgr,
|
||||
std::chrono::duration<long long>(0),
|
||||
ServerProperties::instance().getString("level-dir"),
|
||||
ServerProperties::instance().getString("level-name"),
|
||||
ServerProperties::instance().getString("motd"),
|
||||
"",
|
||||
"",
|
||||
&levelSettings,
|
||||
api,
|
||||
ServerProperties::instance().getInt("view-distance", 22),
|
||||
true,
|
||||
ServerProperties::instance().getInt("server-port", 19132),
|
||||
ServerProperties::instance().getInt("server-port-v6", 19133),
|
||||
ServerProperties::instance().getInt("max-players", 20),
|
||||
ServerProperties::instance().getBool("online-mode", false),
|
||||
{},
|
||||
"normal",
|
||||
false,
|
||||
*mce::UUID::EMPTY,
|
||||
eventing,
|
||||
resourcePackRepo,
|
||||
*resourcePackManager,
|
||||
resourcePackManager
|
||||
);
|
||||
|
||||
std::cout << "Server running\n";
|
||||
|
||||
while (true) {
|
||||
server.update();
|
||||
Scheduler::singleton()->processCoroutines(std::chrono::duration_cast<std::chrono::duration<long long>>(std::chrono::milliseconds(50)));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
17
src/server_minecraft_app.h
Normal file
17
src/server_minecraft_app.h
Normal file
@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include "../mcpe/IMinecraftApp.h"
|
||||
|
||||
class DedicatedServerMinecraftApp : public IMinecraftApp {
|
||||
|
||||
public:
|
||||
Automation::AutomationClient* automationClient;
|
||||
|
||||
virtual Minecraft* getPrimaryMinecraft() { return nullptr; }
|
||||
virtual Automation::AutomationClient* getAutomationClient() { return automationClient; }
|
||||
virtual bool isEduMode() { return false; }
|
||||
virtual bool isDedicatedServer() { return true; }
|
||||
virtual int getDefaultNetworkMaxPlayers() { return 20; }
|
||||
virtual void onNetworkMaxPlayersChanged(unsigned int max) {}
|
||||
|
||||
};
|
||||
41
src/server_properties.cpp
Normal file
41
src/server_properties.cpp
Normal file
@ -0,0 +1,41 @@
|
||||
#include "server_properties.h"
|
||||
|
||||
void ServerProperties::load(std::istream& stream) {
|
||||
std::string line;
|
||||
while (std::getline(stream, line)) {
|
||||
if (!line.empty() && line[0] == '#')
|
||||
continue;
|
||||
|
||||
size_t i = line.find('=');
|
||||
if (i == std::string::npos)
|
||||
continue;
|
||||
|
||||
properties[line.substr(0, i)] = line.substr(i + 1);
|
||||
}
|
||||
}
|
||||
|
||||
std::string ServerProperties::getString(const std::string& name, const std::string& def) {
|
||||
return properties.count(name) ? properties.at(name) : def;
|
||||
}
|
||||
|
||||
int ServerProperties::getInt(const std::string& name, int def) {
|
||||
return properties.count(name) ? std::stoi(properties.at(name)) : def;
|
||||
}
|
||||
|
||||
long long ServerProperties::getLong(const std::string& name, long long def) {
|
||||
auto it = properties.find(name);
|
||||
if (it == properties.end() || it->second.empty()) return def;
|
||||
return std::stoll(it->second);
|
||||
}
|
||||
|
||||
float ServerProperties::getFloat(const std::string& name, float def) {
|
||||
return properties.count(name) ? std::stof(properties.at(name)) : def;
|
||||
}
|
||||
|
||||
bool ServerProperties::getBool(const std::string& name, bool def) {
|
||||
if (properties.count(name)) {
|
||||
const std::string& val = properties.at(name);
|
||||
return val == "true" || val == "yes" || val == "1";
|
||||
}
|
||||
return def;
|
||||
}
|
||||
29
src/server_properties.h
Normal file
29
src/server_properties.h
Normal file
@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <istream>
|
||||
#include <map>
|
||||
|
||||
class ServerProperties {
|
||||
private:
|
||||
std::map<std::string, std::string> properties;
|
||||
|
||||
ServerProperties() = default;
|
||||
|
||||
public:
|
||||
ServerProperties(const ServerProperties&) = delete;
|
||||
ServerProperties& operator=(const ServerProperties&) = delete;
|
||||
|
||||
static ServerProperties& instance() {
|
||||
static ServerProperties instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
void load(std::istream& stream);
|
||||
|
||||
std::string getString(const std::string& name, const std::string& def = "");
|
||||
int getInt(const std::string& name, int def = 0);
|
||||
long long getLong(const std::string& name, long long def = 0);
|
||||
float getFloat(const std::string& name, float def = 0.f);
|
||||
bool getBool(const std::string& name, bool def = false);
|
||||
};
|
||||
Loading…
x
Reference in New Issue
Block a user