mirror of
https://github.com/celisej567/mcpe.git
synced 2026-09-23 20:09:46 +03:00
Misc patches
This commit is contained in:
12
source/server/CMakeLists.txt
Normal file
12
source/server/CMakeLists.txt
Normal file
@@ -0,0 +1,12 @@
|
||||
add_library(Server STATIC
|
||||
Options.cpp Options.hpp
|
||||
Server.cpp Server.hpp
|
||||
)
|
||||
target_link_libraries(Server PRIVATE
|
||||
Common
|
||||
Network
|
||||
World
|
||||
)
|
||||
if (USE_SDL)
|
||||
target_link_libraries(Server PRIVATE SDL)
|
||||
endif()
|
||||
415
source/server/Options.cpp
Normal file
415
source/server/Options.cpp
Normal file
@@ -0,0 +1,415 @@
|
||||
/********************************************************************
|
||||
Minecraft: Pocket Edition - Decompilation Project
|
||||
Copyright (C) 2023 iProgramInCpp
|
||||
|
||||
The following code is licensed under the BSD 1 clause license.
|
||||
SPDX-License-Identifier: BSD-1-Clause
|
||||
********************************************************************/
|
||||
|
||||
#include <fstream>
|
||||
|
||||
#include "Options.hpp"
|
||||
#include "common/Util.hpp"
|
||||
#include "common/Utils.hpp"
|
||||
#include "compat/KeyCodes.hpp"
|
||||
#ifndef SERVER
|
||||
#include "client/renderer/PatchManager.hpp"
|
||||
#include "client/renderer/GrassColor.hpp"
|
||||
#include "client/renderer/FoliageColor.hpp"
|
||||
#endif
|
||||
|
||||
Options::Option
|
||||
Options::Option::MUSIC (0, "options.music", true, false),
|
||||
Options::Option::SOUND (1, "options.sound", true, false),
|
||||
Options::Option::INVERT_MOUSE (2, "options.invertMouse", false, true),
|
||||
Options::Option::SENSITIVITY (3, "options.sensitivity", true, false),
|
||||
Options::Option::RENDER_DISTANCE (4, "options.renderDistance", false, false),
|
||||
Options::Option::VIEW_BOBBING (5, "options.viewBobbing", false, true),
|
||||
Options::Option::ANAGLYPH (6, "options.anaglyph", false, true),
|
||||
Options::Option::LIMIT_FRAMERATE (7, "options.limitFramerate", false, true),
|
||||
Options::Option::DIFFICULTY (8, "options.difficulty", false, false),
|
||||
Options::Option::GRAPHICS (9, "options.graphics", false, false),
|
||||
Options::Option::AMBIENT_OCCLUSION(10, "options.ao", false, true),
|
||||
Options::Option::GUI_SCALE (11, "options.guiScale", false, false);
|
||||
|
||||
void Options::_initDefaultValues()
|
||||
{
|
||||
field_238 = 2;
|
||||
field_244 = 1.0f;
|
||||
m_bDontRenderGui = false;
|
||||
field_248 = 1.0f;
|
||||
m_bThirdPerson = false;
|
||||
field_0 = 1.0f;
|
||||
field_23E = 0;
|
||||
m_fMasterVolume = 1.0f;
|
||||
m_bFlyCheat = false;
|
||||
field_241 = 0;
|
||||
field_8 = 0.5f;
|
||||
field_24C = 0;
|
||||
m_bInvertMouse = false;
|
||||
m_bAnaglyphs = false;
|
||||
field_16 = 0;
|
||||
m_bAmbientOcclusion = false;
|
||||
field_240 = 1;
|
||||
m_iViewDistance = 2;
|
||||
m_bViewBobbing = 1;
|
||||
m_bAutoJump = true;
|
||||
m_bFancyGraphics = true;
|
||||
field_1C = "Default";
|
||||
m_playerName = "Steve";
|
||||
m_bServerVisibleDefault = true;
|
||||
m_bDebugText = false;
|
||||
m_bBlockOutlines = false;
|
||||
m_bFancyGrass = false;
|
||||
m_bBiomeColors = false;
|
||||
m_bSplitControls = false;
|
||||
m_bDynamicHand = false;
|
||||
m_bOldTitleLogo = false;
|
||||
field_19 = 1;
|
||||
|
||||
// Win32 key codes are being used by default
|
||||
#define KM(idx, name, code) m_keyMappings[idx] = KeyMapping(name, code)
|
||||
KM(KM_FORWARD, "key.forward", 'W');
|
||||
KM(KM_LEFT, "key.left", 'A');
|
||||
KM(KM_BACKWARD, "key.back", 'S');
|
||||
KM(KM_RIGHT, "key.right", 'D');
|
||||
KM(KM_JUMP, "key.jump", ' ');
|
||||
KM(KM_INVENTORY, "key.inventory", 'E');
|
||||
KM(KM_DROP, "key.drop", 'Q');
|
||||
KM(KM_CHAT, "key.chat", 'T');
|
||||
KM(KM_FOG, "key.fog", 'F');
|
||||
KM(KM_SNEAK, "key.sneak", 0x10); // VK_SHIFT. In original, it's 10 (misspelling?)
|
||||
KM(KM_DESTROY, "key.destroy", 'K'); // was 'X'
|
||||
KM(KM_PLACE, "key.place", 'L'); // was 'C'
|
||||
KM(KM_MENU_NEXT, "key.menu.next", 0x28); // VK_DOWN
|
||||
KM(KM_MENU_PREVIOUS,"key.menu.previous", 0x26); // VK_UP
|
||||
KM(KM_MENU_OK, "key.menu.ok", 0x0D); // VK_RETURN
|
||||
KM(KM_MENU_CANCEL, "key.menu.cancel", 0x1B); // VK_ESCAPE, was 0x08 = VK_BACK
|
||||
KM(KM_SLOT_1, "key.slot.1", '1');
|
||||
KM(KM_SLOT_2, "key.slot.2", '2');
|
||||
KM(KM_SLOT_3, "key.slot.3", '3');
|
||||
KM(KM_SLOT_4, "key.slot.4", '4');
|
||||
KM(KM_SLOT_5, "key.slot.5", '5');
|
||||
KM(KM_SLOT_6, "key.slot.6", '6');
|
||||
KM(KM_SLOT_7, "key.slot.7", '7');
|
||||
KM(KM_SLOT_8, "key.slot.8", '8');
|
||||
KM(KM_SLOT_9, "key.slot.9", '9');
|
||||
KM(KM_SLOT_L, "key.slot.left", 'Y');
|
||||
KM(KM_SLOT_R, "key.slot.right", 'U');
|
||||
KM(KM_TOGGLEGUI, "key.fn.gui", 0x70); // VK_F1
|
||||
KM(KM_SCREENSHOT, "key.fn.screenshot", 0x71); // VK_F2
|
||||
KM(KM_TOGGLEDEBUG, "key.fn.debug", 0x72); // VK_F3
|
||||
KM(KM_TOGGLEAO, "key.fn.ao", 0x73); // VK_F4
|
||||
KM(KM_TOGGLE3RD, "key.fn.3rd", 0x74); // VK_F5
|
||||
KM(KM_FLY_UP, "key.fly.up", 'X');
|
||||
KM(KM_FLY_DOWN, "key.fly.down", 'C');
|
||||
KM(KM_CHAT_CMD, "key.chat.cmd", 0xBF); // VK_OEM_2
|
||||
#undef KM
|
||||
|
||||
#ifdef ORIGINAL_CODE
|
||||
m_iViewDistance = 2;
|
||||
m_bThirdPerson = 0;
|
||||
field_19 = 0;
|
||||
#endif
|
||||
|
||||
m_bFancyGraphics = 1;
|
||||
|
||||
#define KM(idx,code) m_keyMappings[idx].value = code
|
||||
#ifdef USE_SDL
|
||||
KM(KM_FORWARD, SDLVK_W);
|
||||
KM(KM_LEFT, SDLVK_A);
|
||||
KM(KM_BACKWARD, SDLVK_S);
|
||||
KM(KM_RIGHT, SDLVK_D);
|
||||
KM(KM_JUMP, SDLVK_SPACE);
|
||||
KM(KM_DESTROY, SDLVK_X);
|
||||
KM(KM_PLACE, SDLVK_C);
|
||||
KM(KM_MENU_NEXT, SDLVK_DOWN);
|
||||
KM(KM_MENU_PREVIOUS, SDLVK_UP);
|
||||
KM(KM_MENU_OK, SDLVK_RETURN);
|
||||
KM(KM_MENU_CANCEL, SDLVK_ESCAPE);
|
||||
KM(KM_DROP, SDLVK_Q);
|
||||
KM(KM_CHAT, SDLVK_T);
|
||||
KM(KM_FOG, SDLVK_F);
|
||||
KM(KM_INVENTORY, SDLVK_E);
|
||||
KM(KM_SNEAK, SDLVK_LSHIFT);
|
||||
KM(KM_SLOT_1, SDLVK_1);
|
||||
KM(KM_SLOT_2, SDLVK_2);
|
||||
KM(KM_SLOT_3, SDLVK_3);
|
||||
KM(KM_SLOT_4, SDLVK_4);
|
||||
KM(KM_SLOT_5, SDLVK_5);
|
||||
KM(KM_SLOT_6, SDLVK_6);
|
||||
KM(KM_SLOT_7, SDLVK_7);
|
||||
KM(KM_SLOT_8, SDLVK_8);
|
||||
KM(KM_SLOT_9, SDLVK_9);
|
||||
KM(KM_TOGGLEGUI, SDLVK_F1);
|
||||
KM(KM_SCREENSHOT, SDLVK_F2);
|
||||
KM(KM_TOGGLEDEBUG, SDLVK_F3);
|
||||
KM(KM_TOGGLEAO, SDLVK_F4);
|
||||
KM(KM_TOGGLE3RD, SDLVK_F5);
|
||||
KM(KM_SLOT_L, SDLVK_Y);
|
||||
KM(KM_SLOT_R, SDLVK_U);
|
||||
KM(KM_FLY_UP, SDLVK_C);
|
||||
KM(KM_FLY_DOWN, SDLVK_X);
|
||||
KM(KM_CHAT_CMD, SDLVK_SLASH);
|
||||
#endif
|
||||
#ifdef USE_NATIVE_ANDROID
|
||||
// -- Original xperia play controls
|
||||
//KM(KM_FORWARD, AKEYCODE_DPAD_UP);
|
||||
//KM(KM_LEFT, AKEYCODE_DPAD_LEFT);
|
||||
//KM(KM_BACKWARD, AKEYCODE_DPAD_DOWN);
|
||||
//KM(KM_RIGHT, AKEYCODE_DPAD_RIGHT);
|
||||
//KM(KM_JUMP, AKEYCODE_DPAD_CENTER);
|
||||
//KM(KM_DESTROY, AKEYCODE_BUTTON_L1);
|
||||
//KM(KM_PLACE, AKEYCODE_BUTTON_R1);
|
||||
//KM(KM_MENU_NEXT, AKEYCODE_DPAD_DOWN);
|
||||
//KM(KM_MENU_PREVIOUS, AKEYCODE_DPAD_UP);
|
||||
//KM(KM_MENU_OK, AKEYCODE_DPAD_CENTER);
|
||||
//KM(KM_MENU_CANCEL, AKEYCODE_BACK);
|
||||
//custom
|
||||
//KM(KM_INVENTORY, AKEYCODE_BUTTON_Y);
|
||||
//KM(KM_SLOT_R, AKEYCODE_BACK);
|
||||
//KM(KM_SLOT_L, AKEYCODE_BUTTON_X);
|
||||
//KM(KM_FLY_UP, AKEYCODE_BUTTON_R1);
|
||||
//KM(KM_FLY_DOWN, AKEYCODE_BUTTON_L1);
|
||||
|
||||
//use controller input on android for now.
|
||||
KM(KM_FORWARD, AKEYCODE_W);
|
||||
KM(KM_LEFT, AKEYCODE_A);
|
||||
KM(KM_BACKWARD, AKEYCODE_S);
|
||||
KM(KM_RIGHT, AKEYCODE_D);
|
||||
KM(KM_JUMP, AKEYCODE_BUTTON_A);
|
||||
KM(KM_DESTROY, AKEYCODE_X);
|
||||
KM(KM_PLACE, AKEYCODE_C);
|
||||
KM(KM_MENU_NEXT, AKEYCODE_DPAD_DOWN);
|
||||
KM(KM_MENU_PREVIOUS, AKEYCODE_DPAD_UP);
|
||||
KM(KM_MENU_OK, AKEYCODE_ENTER);
|
||||
KM(KM_MENU_CANCEL, AKEYCODE_BUTTON_START);
|
||||
// custom
|
||||
KM(KM_SLOT_L, AKEYCODE_BUTTON_L1);
|
||||
KM(KM_SLOT_R, AKEYCODE_BUTTON_R1);
|
||||
KM(KM_DROP, AKEYCODE_Q);
|
||||
KM(KM_CHAT, AKEYCODE_T);
|
||||
KM(KM_FOG, AKEYCODE_F);
|
||||
KM(KM_INVENTORY, AKEYCODE_BUTTON_Y);
|
||||
KM(KM_SNEAK, AKEYCODE_SHIFT_LEFT);
|
||||
KM(KM_SLOT_1, AKEYCODE_1);
|
||||
KM(KM_SLOT_2, AKEYCODE_2);
|
||||
KM(KM_SLOT_3, AKEYCODE_3);
|
||||
KM(KM_SLOT_4, AKEYCODE_4);
|
||||
KM(KM_SLOT_5, AKEYCODE_5);
|
||||
KM(KM_SLOT_6, AKEYCODE_6);
|
||||
KM(KM_SLOT_7, AKEYCODE_7);
|
||||
KM(KM_SLOT_8, AKEYCODE_8);
|
||||
KM(KM_SLOT_9, AKEYCODE_9);
|
||||
KM(KM_TOGGLEGUI, AKEYCODE_F1);
|
||||
KM(KM_SCREENSHOT, AKEYCODE_F2);
|
||||
KM(KM_TOGGLEDEBUG, AKEYCODE_F3);
|
||||
KM(KM_TOGGLEAO, AKEYCODE_F4);
|
||||
KM(KM_TOGGLE3RD, AKEYCODE_F5);
|
||||
KM(KM_FLY_UP, AKEYCODE_C);
|
||||
KM(KM_FLY_DOWN, AKEYCODE_X);
|
||||
KM(KM_CHAT_CMD, AKEYCODE_SLASH);
|
||||
#endif
|
||||
#undef KM
|
||||
}
|
||||
|
||||
Options::Options()
|
||||
{
|
||||
_initDefaultValues();
|
||||
}
|
||||
|
||||
Options::Options(const std::string& folderPath)
|
||||
{
|
||||
m_filePath = folderPath + "/options.txt";
|
||||
_initDefaultValues();
|
||||
_load();
|
||||
}
|
||||
|
||||
std::string getMessage(const Options::Option& option)
|
||||
{
|
||||
return "Options::getMessage - Not implemented";
|
||||
}
|
||||
|
||||
void Options::_load()
|
||||
{
|
||||
std::vector<std::string> strings = readPropertiesFromFile(m_filePath);
|
||||
|
||||
for (int i = 0; i < strings.size(); i += 2)
|
||||
{
|
||||
std::string key = strings[i], value = strings[i + 1];
|
||||
|
||||
if (key == "mp_username")
|
||||
m_playerName = value;
|
||||
else if (key == "ctrl_invertmouse")
|
||||
m_bInvertMouse = readBool(value);
|
||||
else if (key == "ctrl_autojump")
|
||||
m_bAutoJump = readBool(value);
|
||||
else if (key == "ctrl_split")
|
||||
m_bSplitControls = readBool(value);
|
||||
else if (key == "gfx_fancygraphics")
|
||||
m_bFancyGraphics = readBool(value);
|
||||
else if (key == "mp_server_visible_default")
|
||||
m_bServerVisibleDefault = readBool(value);
|
||||
else if (key == "gfx_smoothlighting")
|
||||
m_bAmbientOcclusion = readBool(value);
|
||||
else if (key == "gfx_viewdistance")
|
||||
m_iViewDistance = readInt(value);
|
||||
else if (key == "gfx_blockoutlines")
|
||||
m_bBlockOutlines = readBool(value);
|
||||
else if (key == "gfx_fancygrass")
|
||||
{
|
||||
m_bFancyGrass = readBool(value);
|
||||
#ifndef SERVER // TODO(Er2): Move this to client?
|
||||
if (!(GetPatchManager()->IsGrassSidesTinted()))
|
||||
m_bFancyGrass = false;
|
||||
#endif
|
||||
}
|
||||
else if (key == "gfx_biomecolors")
|
||||
{
|
||||
m_bBiomeColors = readBool(value);
|
||||
#ifndef SERVER // TODO(Er2): this too
|
||||
if (!GrassColor::isAvailable() && !FoliageColor::isAvailable())
|
||||
{
|
||||
m_bBiomeColors = false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else if (key == "gfx_hidegui")
|
||||
m_bDontRenderGui = readBool(value);
|
||||
else if (key == "gfx_thirdperson")
|
||||
m_bThirdPerson = readBool(value);
|
||||
else if (key == "gfx_3danaglyphs")
|
||||
m_bAnaglyphs = readBool(value);
|
||||
else if (key == "gfx_dynamichand")
|
||||
m_bDynamicHand = readBool(value);
|
||||
else if (key == "misc_oldtitle")
|
||||
m_bOldTitleLogo = readBool(value);
|
||||
else if (key == "info_debugtext")
|
||||
m_bDebugText = readBool(value);
|
||||
}
|
||||
}
|
||||
|
||||
void Options::save()
|
||||
{
|
||||
savePropertiesToFile(m_filePath, getOptionStrings());
|
||||
}
|
||||
|
||||
std::string Options::getMessage(const Options::Option& option)
|
||||
{
|
||||
return "Options::getMessage - Not implemented";
|
||||
}
|
||||
|
||||
bool Options::readBool(const std::string& str)
|
||||
{
|
||||
std::string trimmed = Util::stringTrim(str);
|
||||
if (trimmed == "true" || trimmed == "1")
|
||||
return true;
|
||||
if (trimmed == "false" || trimmed == "0")
|
||||
return false;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int Options::readInt(const std::string& str)
|
||||
{
|
||||
int f;
|
||||
|
||||
if (!sscanf(str.c_str(), "%d", &f))
|
||||
f = 0;
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
std::string Options::saveBool(bool b)
|
||||
{
|
||||
return b ? "true" : "false";
|
||||
}
|
||||
|
||||
std::string Options::saveInt(int i)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << i;
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
std::vector<std::string> Options::readPropertiesFromFile(const std::string& filePath)
|
||||
{
|
||||
std::vector<std::string> o;
|
||||
|
||||
const char* const path = filePath.c_str();
|
||||
LOG_I("Loading options from %s", path);
|
||||
|
||||
std::ifstream ifs(path);
|
||||
if (!ifs.is_open())
|
||||
{
|
||||
LOG_W("%s doesn't exist, resetting to defaults", path);
|
||||
return o;
|
||||
}
|
||||
|
||||
std::string str;
|
||||
while (true)
|
||||
{
|
||||
if (!std::getline(ifs, str, '\n'))
|
||||
break;
|
||||
|
||||
if (str.empty() || str[0] == '#')
|
||||
continue;
|
||||
|
||||
std::stringstream ss;
|
||||
ss << str;
|
||||
|
||||
std::string key, value;
|
||||
if (std::getline(ss, key, ':') && std::getline(ss, value))
|
||||
{
|
||||
o.push_back(key);
|
||||
o.push_back(value);
|
||||
}
|
||||
}
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
void Options::savePropertiesToFile(const std::string& filePath, std::vector<std::string> properties)
|
||||
{
|
||||
assert(properties.size() % 2 == 0);
|
||||
|
||||
std::ofstream os;
|
||||
os.open(filePath.c_str());
|
||||
if (!os.is_open())
|
||||
{
|
||||
LOG_E("Failed to read %s", filePath.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
os << "#Config file for Minecraft PE. The # at the start denotes a comment, removing it makes it a command.\n\n";
|
||||
|
||||
for (int i = 0; i < properties.size(); i += 2)
|
||||
os << properties[i] << ':' << properties[i + 1] << '\n';
|
||||
}
|
||||
|
||||
std::vector<std::string> Options::getOptionStrings()
|
||||
{
|
||||
std::vector<std::string> vec;
|
||||
|
||||
#define SO(optname, value) do { vec.push_back(optname); vec.push_back(value); } while (0)
|
||||
|
||||
SO("mp_username", m_playerName);
|
||||
SO("ctrl_invertmouse", saveBool(m_bInvertMouse));
|
||||
SO("ctrl_autojump", saveBool(m_bAutoJump));
|
||||
SO("ctrl_split", saveBool(m_bSplitControls));
|
||||
SO("mp_server_visible_default", saveBool(m_bServerVisibleDefault));
|
||||
SO("gfx_fancygraphics", saveBool(m_bFancyGraphics));
|
||||
SO("gfx_smoothlighting", saveBool(m_bAmbientOcclusion));
|
||||
SO("gfx_hidegui", saveBool(m_bDontRenderGui));
|
||||
SO("gfx_thirdperson", saveBool(m_bThirdPerson));
|
||||
SO("gfx_3danaglyphs", saveBool(m_bAnaglyphs));
|
||||
SO("gfx_viewdistance", saveInt (m_iViewDistance));
|
||||
SO("gfx_blockoutlines", saveBool(m_bBlockOutlines));
|
||||
SO("gfx_fancygrass", saveBool(m_bFancyGrass));
|
||||
SO("gfx_biomecolors", saveBool(m_bBiomeColors));
|
||||
SO("gfx_dynamichand", saveBool(m_bDynamicHand));
|
||||
SO("misc_oldtitle", saveBool(m_bOldTitleLogo));
|
||||
SO("info_debugtext", saveBool(m_bDebugText));
|
||||
|
||||
return vec;
|
||||
}
|
||||
159
source/server/Options.hpp
Normal file
159
source/server/Options.hpp
Normal file
@@ -0,0 +1,159 @@
|
||||
/********************************************************************
|
||||
Minecraft: Pocket Edition - Decompilation Project
|
||||
Copyright (C) 2023 iProgramInCpp
|
||||
|
||||
The following code is licensed under the BSD 1 clause license.
|
||||
SPDX-License-Identifier: BSD-1-Clause
|
||||
********************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
enum eKeyMappingIndex
|
||||
{
|
||||
KM_FORWARD,
|
||||
KM_LEFT,
|
||||
KM_BACKWARD,
|
||||
KM_RIGHT,
|
||||
KM_JUMP,
|
||||
KM_INVENTORY,
|
||||
KM_DROP,
|
||||
KM_CHAT,
|
||||
KM_FOG,
|
||||
KM_SNEAK,
|
||||
KM_DESTROY,
|
||||
KM_PLACE,
|
||||
KM_MENU_NEXT,
|
||||
KM_MENU_PREVIOUS,
|
||||
KM_MENU_OK,
|
||||
KM_MENU_CANCEL, KM_BACK = KM_MENU_CANCEL,
|
||||
KM_SLOT_1,
|
||||
KM_SLOT_2,
|
||||
KM_SLOT_3,
|
||||
KM_SLOT_4,
|
||||
KM_SLOT_5,
|
||||
KM_SLOT_6,
|
||||
KM_SLOT_7,
|
||||
KM_SLOT_8,
|
||||
KM_SLOT_9,
|
||||
KM_SLOT_L,
|
||||
KM_SLOT_R,
|
||||
KM_TOGGLEGUI,
|
||||
KM_SCREENSHOT,
|
||||
KM_TOGGLEDEBUG,
|
||||
KM_TOGGLEAO,
|
||||
KM_TOGGLE3RD,
|
||||
KM_FLY_UP,
|
||||
KM_FLY_DOWN,
|
||||
KM_CHAT_CMD, // called "Open Chat" in Release 1.8
|
||||
KM_COUNT,
|
||||
};
|
||||
|
||||
struct KeyMapping
|
||||
{
|
||||
std::string key;
|
||||
int value;
|
||||
|
||||
KeyMapping() {}
|
||||
KeyMapping(const char* keyName, int keyCode) : key(keyName), value(keyCode) {}
|
||||
};
|
||||
|
||||
class Options
|
||||
{
|
||||
public:
|
||||
struct Option;
|
||||
struct KeyBind;
|
||||
private:
|
||||
static bool readBool(const std::string& str);
|
||||
static int readInt(const std::string& str);
|
||||
static std::string saveBool(bool b);
|
||||
static std::string saveInt(int i);
|
||||
static std::vector<std::string> readPropertiesFromFile(const std::string& filePath);
|
||||
static void savePropertiesToFile(const std::string& filePath, std::vector<std::string> properties);
|
||||
|
||||
private:
|
||||
void _initDefaultValues();
|
||||
void _load();
|
||||
public:
|
||||
Options();
|
||||
Options(const std::string& folderPath);
|
||||
void save();
|
||||
std::string getMessage(const Options::Option&);
|
||||
std::vector<std::string> getOptionStrings();
|
||||
|
||||
int getKey(eKeyMappingIndex idx)
|
||||
{
|
||||
return m_keyMappings[idx].value;
|
||||
}
|
||||
bool isKey(eKeyMappingIndex idx, int keyCode)
|
||||
{
|
||||
return getKey(idx) == keyCode;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string m_filePath;
|
||||
|
||||
public:
|
||||
float field_0;
|
||||
float m_fMasterVolume;
|
||||
float field_8;
|
||||
bool m_bInvertMouse;
|
||||
int m_iViewDistance;
|
||||
bool m_bViewBobbing;
|
||||
bool m_bAnaglyphs;
|
||||
uint8_t field_16;
|
||||
bool m_bFancyGraphics;
|
||||
bool m_bAmbientOcclusion;
|
||||
uint8_t field_19; // use Mouse as input for breaking
|
||||
std::string field_1C;
|
||||
KeyMapping m_keyMappings[KM_COUNT];
|
||||
int field_238;
|
||||
bool m_bDontRenderGui;
|
||||
bool m_bThirdPerson;
|
||||
uint8_t field_23E;
|
||||
bool m_bFlyCheat;
|
||||
uint8_t field_240;
|
||||
uint8_t field_241;
|
||||
float field_244;
|
||||
float field_248;
|
||||
int field_24C;
|
||||
std::string m_playerName;
|
||||
bool m_bServerVisibleDefault;
|
||||
bool m_bAutoJump;
|
||||
bool m_bDebugText;
|
||||
bool m_bBlockOutlines;
|
||||
bool m_bFancyGrass;
|
||||
bool m_bBiomeColors;
|
||||
bool m_bSplitControls;
|
||||
bool m_bDynamicHand;
|
||||
bool m_bOldTitleLogo;
|
||||
|
||||
public:
|
||||
struct Option
|
||||
{
|
||||
bool field_0;
|
||||
bool field_1;
|
||||
std::string str;
|
||||
int field_1C;
|
||||
|
||||
Option(int i, const std::string& str, bool b1, bool b2) : field_0(b1), field_1(b2), str(str), field_1C(i) {}
|
||||
|
||||
static Option MUSIC;
|
||||
static Option SOUND;
|
||||
static Option INVERT_MOUSE;
|
||||
static Option SENSITIVITY;
|
||||
static Option RENDER_DISTANCE;
|
||||
static Option VIEW_BOBBING;
|
||||
static Option ANAGLYPH;
|
||||
static Option LIMIT_FRAMERATE;
|
||||
static Option DIFFICULTY;
|
||||
static Option GRAPHICS;
|
||||
static Option AMBIENT_OCCLUSION;
|
||||
static Option GUI_SCALE;
|
||||
};
|
||||
};
|
||||
|
||||
203
source/server/Server.cpp
Normal file
203
source/server/Server.cpp
Normal file
@@ -0,0 +1,203 @@
|
||||
#include "Server.hpp"
|
||||
#include "network/ServerSideNetworkHandler.hpp"
|
||||
#include "world/level/storage/ExternalFileLevelStorageSource.hpp"
|
||||
|
||||
Server::Server(bool standalone)
|
||||
{
|
||||
m_pOptions = new Options();
|
||||
m_pGameMode = nullptr;
|
||||
m_pLevel = nullptr;
|
||||
m_pLevelStorageSource = nullptr;
|
||||
m_pRakNetInstance = new RakNetInstance;
|
||||
|
||||
if (standalone)
|
||||
{
|
||||
m_pLevelStorageSource = new ExternalFileLevelStorageSource("level");
|
||||
setLevel("level", "Level", 123456);
|
||||
}
|
||||
|
||||
m_pNetEventCallback = new ServerSideNetworkHandler(this, m_pRakNetInstance);
|
||||
m_bRunning = true;
|
||||
}
|
||||
|
||||
void Server::setLevel(const std::string path, const std::string name, int seed)
|
||||
{
|
||||
LevelStorage* pStor = m_pLevelStorageSource->selectLevel(path, false);
|
||||
Dimension* pDim = Dimension::getNew(0);
|
||||
// don't delete pDim manually, it's deleted automatically by level
|
||||
|
||||
m_pLevel = new Level(pStor, name, seed, 1, pDim);
|
||||
}
|
||||
|
||||
Server::~Server()
|
||||
{
|
||||
delete m_pGameMode;
|
||||
delete m_pLevel;
|
||||
delete m_pLevelStorageSource;
|
||||
delete m_pRakNetInstance;
|
||||
delete m_pNetEventCallback;
|
||||
delete m_pOptions;
|
||||
}
|
||||
|
||||
Level* Server::getLevel()
|
||||
{
|
||||
return m_pLevel;
|
||||
}
|
||||
|
||||
RakNetInstance* Server::getRakNetInstance()
|
||||
{
|
||||
return m_pRakNetInstance;
|
||||
}
|
||||
|
||||
Options* Server::getOptions()
|
||||
{
|
||||
return m_pOptions;
|
||||
}
|
||||
|
||||
GameMode* Server::getGameMode()
|
||||
{
|
||||
return m_pGameMode;
|
||||
}
|
||||
|
||||
void Server::addMessage(const std::string& message)
|
||||
{
|
||||
LOG_I("MSG: %s", message.c_str());
|
||||
}
|
||||
|
||||
void Server::start(const std::string name)
|
||||
{
|
||||
m_pRakNetInstance->host(name, C_DEFAULT_PORT, C_MAX_CONNECTIONS);
|
||||
}
|
||||
|
||||
void Server::stop()
|
||||
{
|
||||
m_bRunning = false;
|
||||
}
|
||||
|
||||
void Server::generateLevel()
|
||||
{
|
||||
if (!m_pLevel)
|
||||
{
|
||||
LOG_W("Level wasn't initialized!");
|
||||
setLevel("level", "Level", 123456);
|
||||
}
|
||||
|
||||
LOG_I("Building terrain");
|
||||
|
||||
float startTime = getTimeS();
|
||||
Level* pLevel = m_pLevel;
|
||||
|
||||
if (!pLevel->field_B0C)
|
||||
{
|
||||
pLevel->setUpdateLights(0);
|
||||
}
|
||||
|
||||
printf("Processing");
|
||||
for (int i = 8, i2 = 0; i != 8 + C_MAX_CHUNKS_X * 16; i += 16)
|
||||
{
|
||||
for (int j = 8; j != 8 + C_MAX_CHUNKS_Z * 16; j += 16, i2 += 100)
|
||||
{
|
||||
// this looks like some kind of progress tracking
|
||||
printf("\r\033[KProcessing %i%%", i2 / (C_MAX_CHUNKS_X * C_MAX_CHUNKS_Z));
|
||||
fflush(stdout);
|
||||
|
||||
float time1 = getTimeS();
|
||||
|
||||
// generating all the chunks at once
|
||||
TileID unused = m_pLevel->getTile(i, (C_MAX_Y + C_MIN_Y) / 2, j);
|
||||
|
||||
if (time1 != -1.0f)
|
||||
getTimeS();
|
||||
|
||||
float time2 = getTimeS();
|
||||
if (m_pLevel->field_B0C)
|
||||
{
|
||||
while (m_pLevel->updateLights());
|
||||
}
|
||||
|
||||
if (time2 != -1.0f)
|
||||
getTimeS();
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
if (startTime != -1.0f)
|
||||
getTimeS();
|
||||
|
||||
m_pLevel->setUpdateLights(1);
|
||||
|
||||
startTime = getTimeS();
|
||||
|
||||
for (int x = 0; x < C_MAX_CHUNKS_X; x++)
|
||||
{
|
||||
for (int z = 0; z < C_MAX_CHUNKS_Z; z++)
|
||||
{
|
||||
LevelChunk* pChunk = m_pLevel->getChunk(x, z);
|
||||
if (!pChunk)
|
||||
continue;
|
||||
|
||||
if (pChunk->field_237)
|
||||
continue;
|
||||
|
||||
pChunk->m_bUnsaved = false;
|
||||
pChunk->clearUpdateMap();
|
||||
}
|
||||
}
|
||||
|
||||
if (startTime != -1.0f)
|
||||
getTimeS();
|
||||
|
||||
LOG_I("Saving chunks");
|
||||
|
||||
if (m_pLevel->field_B0C)
|
||||
{
|
||||
m_pLevel->setInitialSpawn();
|
||||
m_pLevel->saveLevelData();
|
||||
m_pLevel->getChunkSource()->saveAll();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pLevel->saveLevelData();
|
||||
}
|
||||
|
||||
LOG_I("Preparing");
|
||||
|
||||
startTime = getTimeS();
|
||||
|
||||
m_pLevel->prepare();
|
||||
|
||||
m_pNetEventCallback->levelGenerated(m_pLevel, nullptr);
|
||||
}
|
||||
|
||||
void Server::tick()
|
||||
{
|
||||
m_pLevel->tickEntities();
|
||||
m_pLevel->tick();
|
||||
}
|
||||
|
||||
void Server::host()
|
||||
{
|
||||
ServerSideNetworkHandler* pSSNH = (ServerSideNetworkHandler*)m_pNetEventCallback;
|
||||
pSSNH->allowIncomingConnections(true);
|
||||
LOG_I("Server is ready!");
|
||||
|
||||
while (m_bRunning)
|
||||
{
|
||||
m_pRakNetInstance->runEvents(m_pNetEventCallback);
|
||||
|
||||
// tick
|
||||
m_timer.advanceTime();
|
||||
|
||||
for (int i = 0; i < m_timer.m_ticks; i++)
|
||||
{
|
||||
tick();
|
||||
}
|
||||
|
||||
//sleepMs(1);
|
||||
}
|
||||
|
||||
LOG_I("Stopping server");
|
||||
LOG_I("Saving chunks");
|
||||
|
||||
m_pLevel->saveLevelData();
|
||||
}
|
||||
41
source/server/Server.hpp
Normal file
41
source/server/Server.hpp
Normal file
@@ -0,0 +1,41 @@
|
||||
#pragma once
|
||||
|
||||
#include "Options.hpp"
|
||||
#include "common/Timer.hpp"
|
||||
#include "network/RakNetInstance.hpp"
|
||||
#include "world/level/Level.hpp"
|
||||
#include "world/gamemode/GameMode.hpp"
|
||||
|
||||
class ServerSideNetworkHandler;
|
||||
|
||||
class Server
|
||||
{
|
||||
public:
|
||||
Server(bool standalone);
|
||||
~Server();
|
||||
|
||||
void setLevel(const std::string path, const std::string name, int seed);
|
||||
Level* getLevel();
|
||||
RakNetInstance* getRakNetInstance();
|
||||
Options* getOptions();
|
||||
GameMode* getGameMode();
|
||||
|
||||
void start(const std::string name);
|
||||
void stop();
|
||||
void generateLevel();
|
||||
void tick();
|
||||
void host();
|
||||
|
||||
virtual void addMessage(const std::string& message);
|
||||
public:
|
||||
Level* m_pLevel;
|
||||
RakNetInstance* m_pRakNetInstance;
|
||||
GameMode* m_pGameMode;
|
||||
LevelStorageSource* m_pLevelStorageSource;
|
||||
NetEventCallback* m_pNetEventCallback;
|
||||
protected:
|
||||
Options* m_pOptions;
|
||||
Timer m_timer;
|
||||
private:
|
||||
bool m_bRunning;
|
||||
};
|
||||
Reference in New Issue
Block a user