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/
|
.idea/
|
||||||
assets/
|
assets/
|
||||||
data/
|
data/
|
||||||
|
|||||||
@ -13,9 +13,6 @@ link_directories(/usr/lib32)
|
|||||||
include_directories(/usr/include)
|
include_directories(/usr/include)
|
||||||
set(X11_X11_LIB /usr/lib32/libX11.so)
|
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(Threads REQUIRED)
|
||||||
find_package(ZLIB REQUIRED)
|
find_package(ZLIB REQUIRED)
|
||||||
find_package(X11 REQUIRED)
|
find_package(X11 REQUIRED)
|
||||||
@ -27,11 +24,19 @@ include_directories(${EGL_INCLUDE_DIRS})
|
|||||||
include_directories(eglut)
|
include_directories(eglut)
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -D_GLIBCXX_USE_CXX11_ABI=0")
|
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(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(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)
|
set(COMMON_SOURCE_FILES src/common.cpp src/hook.cpp src/linux_app_platform.cpp mcpe/types.cpp mcpe/string.cpp)
|
||||||
add_executable(mcpelauncher ${HYBRIS_SOURCES} ${EGLUT_SOURCES} ${SOURCE_FILES})
|
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_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")
|
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
|
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
|
||||||
|
|
||||||
```
|
## Features
|
||||||
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
|
- 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
|
```bash
|
||||||
you may need to reinstall/reconfigure them; if you use mesa you'll need to install the libgles2-mesa-dev:i386 and
|
sudo pacman -Syu base-devel cmake zlib libpng libx11 libxext libglvnd \
|
||||||
libegl1-mesa-dev:i386 packages)
|
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
|
## Compiling
|
||||||
This app uses cmake so it is enough to do:
|
This app uses cmake so it is enough to do:
|
||||||
|
|
||||||
```
|
```
|
||||||
cmake .
|
mkdir build
|
||||||
|
cmake ..
|
||||||
make
|
make
|
||||||
```
|
```
|
||||||
|
|
||||||
## Running
|
## Running
|
||||||
1. Clone this repository
|
1. Clone this repository
|
||||||
2. Compile the launcher
|
2. Compile the launcher
|
||||||
3. You'll need to obtain a x86 MCPE .apk. The easiest way to do so is to use the
|
3. Obtain a x86 MCPE 1.1 apk file
|
||||||
[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`)
|
|
||||||
4. After you have downloaded MCPE, place it in the directory where you'll be running this app, and run ./extract.sh _filename_
|
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!
|
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.
|
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
|
## 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
|
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).
|
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
|
#pragma once
|
||||||
|
|
||||||
#include <string>
|
#include "string.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
@ -10,15 +10,15 @@ struct FilePickerSettings {
|
|||||||
NONE, OPEN, SAVE
|
NONE, OPEN, SAVE
|
||||||
};
|
};
|
||||||
struct FileDescription {
|
struct FileDescription {
|
||||||
std::string ext, desc;
|
mcpe::string ext, desc;
|
||||||
};
|
};
|
||||||
|
|
||||||
char filler [0x20]; // 20
|
char filler [0x20];
|
||||||
std::function<void (FilePickerSettings&, std::string)> pickedCallback; // 30
|
std::function<void (FilePickerSettings&, mcpe::string)> pickedCallback;
|
||||||
std::vector<FileDescription> fileDescriptions; // 3c
|
std::vector<FileDescription> fileDescriptions;
|
||||||
int filler3; // 40
|
int filler3;
|
||||||
PickerType type; // 44
|
PickerType type;
|
||||||
std::string defaultFileName; // 48
|
mcpe::string defaultFileName;
|
||||||
std::string pickerTitle; // 52
|
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:
|
public:
|
||||||
virtual ~ImagePickingCallback();
|
virtual ~ImagePickingCallback();
|
||||||
virtual void onImagePickingSuccess(const std::string&);
|
virtual void onImagePickingSuccess(const mcpe::string&);
|
||||||
virtual void onImagePickingCanceled();
|
virtual void onImagePickingCanceled();
|
||||||
|
|
||||||
};
|
};
|
||||||
@ -9,7 +9,7 @@ class Keyboard {
|
|||||||
|
|
||||||
public:
|
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 std::vector<KeyboardAction>* inputs;
|
||||||
static int* states;
|
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"
|
#include "App.h"
|
||||||
|
|
||||||
class Options;
|
class Options;
|
||||||
|
class MinecraftEventing;
|
||||||
|
class ResourcePackRepository;
|
||||||
|
class ResourcePackManager;
|
||||||
|
|
||||||
class MinecraftGame : public App {
|
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
|
#pragma once
|
||||||
|
#include "string.h"
|
||||||
|
|
||||||
struct gl {
|
struct gl {
|
||||||
static std::string (*getOpenGLVendor)();
|
static mcpe::string (*getOpenGLVendor)();
|
||||||
static std::string (*getOpenGLRenderer)();
|
static mcpe::string (*getOpenGLRenderer)();
|
||||||
static std::string (*getOpenGLVersion)();
|
static mcpe::string (*getOpenGLVersion)();
|
||||||
static std::string (*getOpenGLExtensions)();
|
static mcpe::string (*getOpenGLExtensions)();
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace mce {
|
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"
|
#include "gl.h"
|
||||||
|
|
||||||
std::string (*gl::getOpenGLVendor)();
|
mcpe::string (*gl::getOpenGLVendor)();
|
||||||
std::string (*gl::getOpenGLRenderer)();
|
mcpe::string (*gl::getOpenGLRenderer)();
|
||||||
std::string (*gl::getOpenGLVersion)();
|
mcpe::string (*gl::getOpenGLVersion)();
|
||||||
std::string (*gl::getOpenGLExtensions)();
|
mcpe::string (*gl::getOpenGLExtensions)();
|
||||||
void (*mce::Platform::OGL::OGL_initBindings)();
|
void (*mce::Platform::OGL::OGL_initBindings)();
|
||||||
|
|
||||||
#include "Mouse.h"
|
#include "Mouse.h"
|
||||||
@ -40,6 +40,100 @@ void (*Mouse::feed)(char, char, short, short, short, short);
|
|||||||
|
|
||||||
#include "Keyboard.h"
|
#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;
|
std::vector<KeyboardAction>* Keyboard::inputs;
|
||||||
int* Keyboard::states;
|
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 "common.h"
|
||||||
|
|
||||||
|
#include <filesystem>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstdarg>
|
#include <cstdarg>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
@ -14,14 +15,25 @@ extern "C" {
|
|||||||
#include "../hybris/include/hybris/dlfcn.h"
|
#include "../hybris/include/hybris/dlfcn.h"
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string getCWD() {
|
std::string rootPath = "";
|
||||||
char _cwd[MAXPATHLEN];
|
|
||||||
getcwd(_cwd, MAXPATHLEN);
|
std::string getRootPath() {
|
||||||
return std::string(_cwd) + "/";
|
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) {
|
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) {
|
if (handle == nullptr) {
|
||||||
printf("failed to load library %s: %s\n", path.c_str(), hybris_dlerror());
|
printf("failed to load library %s: %s\n", path.c_str(), hybris_dlerror());
|
||||||
return false;
|
return false;
|
||||||
@ -49,7 +61,7 @@ void* loadLibraryOS(std::string path, const char** symbols) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void* loadMod(std::string path) {
|
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) {
|
if (handle == nullptr) {
|
||||||
printf("failed to load mod: %s\n", path.c_str());
|
printf("failed to load mod: %s\n", path.c_str());
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|||||||
@ -2,7 +2,9 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
std::string getCWD();
|
extern std::string rootPath;
|
||||||
|
|
||||||
|
std::string getRootPath();
|
||||||
bool loadLibrary(std::string path);
|
bool loadLibrary(std::string path);
|
||||||
void* loadLibraryOS(std::string path, const char** symbols);
|
void* loadLibraryOS(std::string path, const char** symbols);
|
||||||
void* loadMod(std::string path);
|
void* loadMod(std::string path);
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
#include "LinuxAppPlatform.h"
|
#include "linux_app_platform.h"
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
@ -14,24 +14,25 @@
|
|||||||
#include "../hybris/src/jb/linker.h"
|
#include "../hybris/src/jb/linker.h"
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
#ifndef SERVER
|
||||||
#include <eglut.h>
|
#include <eglut.h>
|
||||||
|
#endif
|
||||||
#include "../hybris/include/hybris/dlfcn.h"
|
#include "../hybris/include/hybris/dlfcn.h"
|
||||||
}
|
}
|
||||||
|
|
||||||
void** LinuxAppPlatform::myVtable = nullptr;
|
void** LinuxAppPlatform::myVtable = nullptr;
|
||||||
bool LinuxAppPlatform::mousePointerHidden = false;
|
bool LinuxAppPlatform::mousePointerHidden = false;
|
||||||
bool enablePocketGuis = false;
|
bool enablePocketGuis = false;
|
||||||
bool serverMode = false;
|
|
||||||
|
|
||||||
LinuxAppPlatform::LinuxAppPlatform() : AppPlatform() {
|
LinuxAppPlatform::LinuxAppPlatform() : AppPlatform() {
|
||||||
this->vtable = myVtable;
|
this->vtable = myVtable;
|
||||||
internalStorage = "data/private/";
|
internalStorage = getRootPath() + "data/private/";
|
||||||
externalStorage = "data/public/";
|
externalStorage = getRootPath() + "data/public/";
|
||||||
currentStorage = "data/current/";
|
currentStorage = getRootPath() + "data/current/";
|
||||||
userdata = "data/user/";
|
userdata = getRootPath() + "data/user/";
|
||||||
userdataPathForLevels = "data/user/";
|
userdataPathForLevels = getRootPath() + "data/user/";
|
||||||
region = "0xdeadbeef";
|
region = "0xdeadbeef";
|
||||||
tmpPath = "tmp/";
|
tmpPath = getRootPath() + "tmp/";
|
||||||
}
|
}
|
||||||
|
|
||||||
#include <execinfo.h>
|
#include <execinfo.h>
|
||||||
@ -99,12 +100,16 @@ void LinuxAppPlatform::initVtable(void* lib) {
|
|||||||
|
|
||||||
void LinuxAppPlatform::hideMousePointer() {
|
void LinuxAppPlatform::hideMousePointer() {
|
||||||
mousePointerHidden = true;
|
mousePointerHidden = true;
|
||||||
|
#ifndef SERVER
|
||||||
moveMouseToCenter = true;
|
moveMouseToCenter = true;
|
||||||
eglutSetMousePointerVisiblity(EGLUT_POINTER_INVISIBLE);
|
eglutSetMousePointerVisiblity(EGLUT_POINTER_INVISIBLE);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
void LinuxAppPlatform::showMousePointer() {
|
void LinuxAppPlatform::showMousePointer() {
|
||||||
mousePointerHidden = false;
|
mousePointerHidden = false;
|
||||||
|
#ifndef SERVER
|
||||||
eglutSetMousePointerVisiblity(EGLUT_POINTER_VISIBLE);
|
eglutSetMousePointerVisiblity(EGLUT_POINTER_VISIBLE);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string LinuxAppPlatform::_pickFile(std::string commandLine) {
|
std::string LinuxAppPlatform::_pickFile(std::string commandLine) {
|
||||||
@ -149,7 +154,7 @@ void LinuxAppPlatform::pickFile(FilePickerSettings &settings) {
|
|||||||
std::cout << " - " << d.ext << " " << d.desc << "\n";
|
std::cout << " - " << d.ext << " " << d.desc << "\n";
|
||||||
}
|
}
|
||||||
std::stringstream ss;
|
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)
|
if (settings.type == FilePickerSettings::PickerType::SAVE)
|
||||||
ss << " --save";
|
ss << " --save";
|
||||||
if (settings.fileDescriptions.size() > 0) {
|
if (settings.fileDescriptions.size() > 0) {
|
||||||
@ -170,9 +175,11 @@ void LinuxAppPlatform::pickFile(FilePickerSettings &settings) {
|
|||||||
|
|
||||||
void LinuxAppPlatform::setFullscreenMode(int mode) {
|
void LinuxAppPlatform::setFullscreenMode(int mode) {
|
||||||
std::cout << "set fullscreen mode: " << mode << "\n";
|
std::cout << "set fullscreen mode: " << mode << "\n";
|
||||||
|
#ifndef SERVER
|
||||||
int newMode = mode == 1 ? EGLUT_FULLSCREEN : EGLUT_WINDOWED;
|
int newMode = mode == 1 ? EGLUT_FULLSCREEN : EGLUT_WINDOWED;
|
||||||
if (eglutGet(EGLUT_FULLSCREEN_MODE) != newMode)
|
if (eglutGet(EGLUT_FULLSCREEN_MODE) != newMode)
|
||||||
eglutToggleFullscreen();
|
eglutToggleFullscreen();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string LinuxAppPlatform::createUUID() {
|
std::string LinuxAppPlatform::createUUID() {
|
||||||
@ -6,6 +6,7 @@
|
|||||||
#include "../mcpe/gl.h"
|
#include "../mcpe/gl.h"
|
||||||
#include "../mcpe/AppPlatform.h"
|
#include "../mcpe/AppPlatform.h"
|
||||||
#include "../mcpe/ImagePickingCallback.h"
|
#include "../mcpe/ImagePickingCallback.h"
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
class ImageData;
|
class ImageData;
|
||||||
class ImagePickingCallback;
|
class ImagePickingCallback;
|
||||||
@ -13,7 +14,6 @@ class FilePickerSettings;
|
|||||||
|
|
||||||
extern bool enablePocketGuis;
|
extern bool enablePocketGuis;
|
||||||
extern bool moveMouseToCenter;
|
extern bool moveMouseToCenter;
|
||||||
extern bool serverMode;
|
|
||||||
|
|
||||||
class LinuxAppPlatform : public AppPlatform {
|
class LinuxAppPlatform : public AppPlatform {
|
||||||
|
|
||||||
@ -35,15 +35,15 @@ public:
|
|||||||
|
|
||||||
std::string getDataUrl() { // this is used only for sounds
|
std::string getDataUrl() { // this is used only for sounds
|
||||||
printf("get data url: assets/\n");
|
printf("get data url: assets/\n");
|
||||||
return "assets/";
|
return getRootPath() + "assets/";
|
||||||
}
|
}
|
||||||
std::string getUserDataUrl() { // this is used only for sounds
|
std::string getUserDataUrl() { // this is used only for sounds
|
||||||
printf("get user data url: data/user/\n");
|
printf("get user data url: data/user/\n");
|
||||||
return "data/user/";
|
return getRootPath() + "data/user/";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string getPackagePath() {
|
std::string getPackagePath() {
|
||||||
return "assets/";
|
return getRootPath() + "assets/";
|
||||||
}
|
}
|
||||||
|
|
||||||
void hideMousePointer();
|
void hideMousePointer();
|
||||||
@ -88,7 +88,7 @@ public:
|
|||||||
}
|
}
|
||||||
std::string getAssetFileFullPath(std::string const& s) {
|
std::string getAssetFileFullPath(std::string const& s) {
|
||||||
printf("get assert full path: %s\n", s.c_str());
|
printf("get assert full path: %s\n", s.c_str());
|
||||||
return "assets/" + s;
|
return getRootPath() + "assets/" + s;
|
||||||
}
|
}
|
||||||
int getScreenType() {
|
int getScreenType() {
|
||||||
if (enablePocketGuis)
|
if (enablePocketGuis)
|
||||||
44
src/main.cpp
44
src/main.cpp
@ -13,16 +13,23 @@
|
|||||||
#include "android_symbols.h"
|
#include "android_symbols.h"
|
||||||
#include "egl_symbols.h"
|
#include "egl_symbols.h"
|
||||||
#include "fmod_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/gl.h"
|
||||||
#include "../mcpe/AppPlatform.h"
|
#include "../mcpe/AppPlatform.h"
|
||||||
#include "../mcpe/MinecraftGame.h"
|
#include "../mcpe/MinecraftGame.h"
|
||||||
#include "LinuxAppPlatform.h"
|
|
||||||
#include "LinuxStore.h"
|
|
||||||
#include "../mcpe/Mouse.h"
|
#include "../mcpe/Mouse.h"
|
||||||
#include "../mcpe/Keyboard.h"
|
#include "../mcpe/Keyboard.h"
|
||||||
#include "../mcpe/Options.h"
|
#include "../mcpe/Options.h"
|
||||||
#include "common.h"
|
#include "../mcpe/Whitelist.h"
|
||||||
#include "hook.h"
|
#include "../mcpe/OpsList.h"
|
||||||
|
#include "../mcpe/LevelSettings.h"
|
||||||
|
#include "../mcpe/UUID.h"
|
||||||
|
#include "../mcpe/ServerInstance.h"
|
||||||
|
#include "../mcpe/FilePathManager.h"
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
@ -33,8 +40,6 @@ extern "C" {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void commonStub() {}
|
|
||||||
|
|
||||||
void androidStub() {
|
void androidStub() {
|
||||||
std::cout << "warn: android call\n";
|
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) {
|
} else if (strcmp(argv[i], "-sw") == 0 || strcmp(argv[i], "--width") == 0) {
|
||||||
i++;
|
i++;
|
||||||
windowWidth = std::stoi(argv[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++;
|
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) {
|
} else if (strcmp(argv[i], "-ns") == 0 || strcmp(argv[i], "--no-stacktrace") == 0) {
|
||||||
enableStackTracePrinting = false;
|
enableStackTracePrinting = false;
|
||||||
} else if (strcmp(argv[i], "--pocket-guis") == 0) {
|
} else if (strcmp(argv[i], "--pocket-guis") == 0) {
|
||||||
enablePocketGuis = true;
|
enablePocketGuis = true;
|
||||||
} else if (strcmp(argv[i], "--server") == 0) {
|
|
||||||
serverMode = true;
|
|
||||||
} else if (strcmp(argv[i], "--amd-fix") == 0) {
|
} else if (strcmp(argv[i], "--amd-fix") == 0) {
|
||||||
std::cout << "--amd-fix: Enabling AMD Workaround.\n";
|
std::cout << "--amd-fix: Enabling AMD Workaround.\n";
|
||||||
workaroundAMD = true;
|
workaroundAMD = true;
|
||||||
} else if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) {
|
} else if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) {
|
||||||
std::cout << "Help\n";
|
std::cout << "Help\n";
|
||||||
std::cout << "--help Shows this help information\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 << "--scale <scale> Sets the pixel scale\n";
|
||||||
std::cout << "--width <width> Sets the window width\n";
|
std::cout << "--width <width> Sets the window width\n";
|
||||||
std::cout << "--height <height> Sets the window height\n";
|
std::cout << "--height <height> Sets the window height\n";
|
||||||
std::cout << "--pocket-guis Switches to Pocket Edition GUIs\n";
|
std::cout << "--pocket-guis Switches to Pocket Edition GUIs\n";
|
||||||
std::cout << "--no-stacktrace Disables stack trace printing\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 << "--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 << "EGL Options\n";
|
||||||
std::cout << "-display <display> Sets the display\n";
|
std::cout << "-display <display> Sets the display\n";
|
||||||
std::cout << "-info Shows info about the display\n\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";
|
std::cout << "loading native libraries\n";
|
||||||
void* glesLib = loadLibraryOS("libGLESv2.so", gles_symbols);
|
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)
|
if (glesLib == nullptr || fmodLib == nullptr)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
@ -277,7 +283,7 @@ int main(int argc, char *argv[]) {
|
|||||||
if (!loadLibrary("libmcpelauncher_mod.so"))
|
if (!loadLibrary("libmcpelauncher_mod.so"))
|
||||||
return -1;
|
return -1;
|
||||||
std::cout << "loading MCPE\n";
|
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);
|
void* handle = hybris_dlopen(mcpePath.c_str(), RTLD_LAZY);
|
||||||
if (handle == nullptr) {
|
if (handle == nullptr) {
|
||||||
std::cout << "failed to load MCPE: " << hybris_dlerror() << "\n";
|
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";
|
std::cout << "loaded " << mods.size() << " mods\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mcpe::string::empty = (mcpe::string*) hybris_dlsym(handle, "_ZN4Util12EMPTY_STRINGE");
|
||||||
|
|
||||||
std::cout << "apply patches\n";
|
std::cout << "apply patches\n";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -373,10 +381,10 @@ int main(int argc, char *argv[]) {
|
|||||||
std::cout << "patches applied!\n";
|
std::cout << "patches applied!\n";
|
||||||
|
|
||||||
// load symbols for gl
|
// load symbols for gl
|
||||||
gl::getOpenGLVendor = (std::string (*)()) hybris_dlsym(handle, "_ZN2gl15getOpenGLVendorEv");
|
gl::getOpenGLVendor = (mcpe::string (*)()) hybris_dlsym(handle, "_ZN2gl15getOpenGLVendorEv");
|
||||||
gl::getOpenGLRenderer = (std::string (*)()) hybris_dlsym(handle, "_ZN2gl17getOpenGLRendererEv");
|
gl::getOpenGLRenderer = (mcpe::string (*)()) hybris_dlsym(handle, "_ZN2gl17getOpenGLRendererEv");
|
||||||
gl::getOpenGLVersion = (std::string (*)()) hybris_dlsym(handle, "_ZN2gl16getOpenGLVersionEv");
|
gl::getOpenGLVersion = (mcpe::string (*)()) hybris_dlsym(handle, "_ZN2gl16getOpenGLVersionEv");
|
||||||
gl::getOpenGLExtensions = (std::string (*)()) hybris_dlsym(handle, "_ZN2gl19getOpenGLExtensionsEv");
|
gl::getOpenGLExtensions = (mcpe::string (*)()) hybris_dlsym(handle, "_ZN2gl19getOpenGLExtensionsEv");
|
||||||
mce::Platform::OGL::OGL_initBindings = (void (*)()) hybris_dlsym(handle, "_ZN3mce8Platform3OGL12InitBindingsEv");
|
mce::Platform::OGL::OGL_initBindings = (void (*)()) hybris_dlsym(handle, "_ZN3mce8Platform3OGL12InitBindingsEv");
|
||||||
|
|
||||||
// init linux app platform
|
// 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::inputs = (std::vector<KeyboardAction>*) hybris_dlsym(handle, "_ZN8Keyboard7_inputsE");
|
||||||
Keyboard::states = (int*) hybris_dlsym(handle, "_ZN8Keyboard7_statesE");
|
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_getFullscreen = (bool (*)(Options*)) hybris_dlsym(handle, "_ZNK7Options13getFullscreenEv");
|
||||||
Options::Options_setFullscreen = (void (*)(Options*, bool)) hybris_dlsym(handle, "_ZN7Options13setFullscreenEb");
|
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