7 Commits

Author SHA1 Message Date
676fd54982 Landscape mode on Android PWA 2026-05-13 13:52:00 +02:00
084607cc86 Merge remote-tracking branch 'origin/main' into web-changes-android
Merged main repo changes
2026-05-13 13:22:21 +02:00
bbd81665a6 Fix multitouch on web 2026-05-12 17:40:10 +02:00
06398e98e2 Made progressive web app installable 2026-05-12 17:09:27 +02:00
7d9328b865 Adaptation to be able to play on android 2026-05-12 14:59:04 +02:00
f1111d06c2 Scroll on settings 2026-05-12 14:32:05 +02:00
ba9f1da758 Simple http server web 2026-05-12 14:23:26 +02:00
128 changed files with 1397 additions and 3168 deletions

View File

@@ -60,16 +60,13 @@ jobs:
- name: Build - name: Build
working-directory: ${{github.workspace}}/build working-directory: ${{github.workspace}}/build
run: | run: cmake --build . --config $BUILD_TYPE --target MinecraftPE --parallel
cmake --build . --config $BUILD_TYPE --target MinecraftPE --parallel
cmake --build . --config $BUILD_TYPE --target MinecraftPE-server --parallel
- name: Upload Artifact - name: Upload Artifact
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: mcpe-windows name: mcpe-windows
path: | path: |
${{github.workspace}}/build/MinecraftPE-server.exe
${{github.workspace}}/build/MinecraftPE.exe ${{github.workspace}}/build/MinecraftPE.exe
${{github.workspace}}/build/libpng16.dll ${{github.workspace}}/build/libpng16.dll
${{github.workspace}}/build/OpenAL32.dll ${{github.workspace}}/build/OpenAL32.dll
@@ -303,12 +300,6 @@ jobs:
files: mcpe-windows/MinecraftPE.exe mcpe-windows/libpng16.dll mcpe-windows/OpenAL32.dll mcpe-windows/libz.dll files: mcpe-windows/MinecraftPE.exe mcpe-windows/libpng16.dll mcpe-windows/OpenAL32.dll mcpe-windows/libz.dll
dest: minecraftpe-${{ steps.ref.outputs.hash }}-windows.zip dest: minecraftpe-${{ steps.ref.outputs.hash }}-windows.zip
- name: Zip Windows Server Artifacts
uses: vimtor/action-zip@v1.2
with:
files: mcpe-windows/MinecraftPE-server.exe
dest: minecraftpe-server-${{ steps.ref.outputs.hash }}-windows.zip
- name: Zip Linux Artifacts - name: Zip Linux Artifacts
uses: vimtor/action-zip@v1.2 uses: vimtor/action-zip@v1.2
with: with:
@@ -319,7 +310,7 @@ jobs:
uses: vimtor/action-zip@v1.2 uses: vimtor/action-zip@v1.2
with: with:
files: mcpe-linux/MinecraftPE-server files: mcpe-linux/MinecraftPE-server
dest: minecraftpe-server-${{ steps.ref.outputs.hash }}-linux.zip dest: minecraftpe-server-${{ steps.ref.outputs.hash }}.zip
- name: Rename Android Artifacts - name: Rename Android Artifacts
run: | run: |
@@ -352,11 +343,7 @@ jobs:
./data.zip ./data.zip
./minecraftpe-server-${{ steps.ref.outputs.hash }}.zip ./minecraftpe-server-${{ steps.ref.outputs.hash }}.zip
./minecraftpe-${{ steps.ref.outputs.hash }}-windows.zip ./minecraftpe-${{ steps.ref.outputs.hash }}-windows.zip
./minecraftpe-server-${{ steps.ref.outputs.hash }}-windows.zip
./minecraftpe-${{ steps.ref.outputs.hash }}-linux.zip ./minecraftpe-${{ steps.ref.outputs.hash }}-linux.zip
./minecraftpe-${{ steps.ref.outputs.hash }}-android-arm64-v8a.apk ./minecraftpe-${{ steps.ref.outputs.hash }}-android-arm64-v8a.apk
./minecraftpe-${{ steps.ref.outputs.hash }}-android-armeabi-v7a.apk ./minecraftpe-${{ steps.ref.outputs.hash }}-android-armeabi-v7a.apk
./minecraftpe-server-${{ steps.ref.outputs.hash }}-linux.zip
./minecraftpe-${{ steps.ref.outputs.hash }}-android-arm64-v8a.zip
./minecraftpe-${{ steps.ref.outputs.hash }}-android-armeabi-v7a.zip
./minecraftpe-${{ steps.ref.outputs.hash }}-web.zip ./minecraftpe-${{ steps.ref.outputs.hash }}-web.zip

View File

@@ -3,9 +3,10 @@ project(MinecraftPE)
include(cmake/CPM.cmake) include(cmake/CPM.cmake)
set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED TRUE) set(CMAKE_CXX_STANDARD_REQUIRED TRUE)
set(CMAKE_POLICY_VERSION_MINIMUM 3.10) set(CMAKE_POLICY_VERSION_MINIMUM 3.10)
include(cmake/EnumOption.cmake) include(cmake/EnumOption.cmake)
if(EMSCRIPTEN) if(EMSCRIPTEN)
@@ -33,11 +34,9 @@ if (${PLATFORM} STREQUAL "Desktop")
add_definitions(-D_CRT_SECURE_NO_WARNINGS) add_definitions(-D_CRT_SECURE_NO_WARNINGS)
include_directories(misc/windows) include_directories(misc/windows)
set(EXTRA_LIBS ws2_32 winhttp) set(EXTRA_LIBS ws2_32 winhttp)
add_definitions(-DLUA_DL_DLL=1)
elseif(UNIX) elseif(UNIX)
find_library(pthread NAMES pthread) find_library(pthread NAMES pthread)
set(EXTRA_LIBS pthread m) set(EXTRA_LIBS pthread m)
add_definitions(-DLUA_USE_DLOPEN=1)
endif() endif()
elseif (${PLATFORM} STREQUAL "Web") elseif (${PLATFORM} STREQUAL "Web")
@@ -96,46 +95,6 @@ else()
"GLFW_BUILD_TESTS OFF" "GLFW_BUILD_TESTS OFF"
"GLFW_BUILD_DOCS OFF" "GLFW_BUILD_DOCS OFF"
) )
CPMAddPackage("gh:halx99/sol2#support-lua-5.5")
CPMAddPackage("gh:lua/lua#master")
add_library(
lua STATIC
${lua_SOURCE_DIR}/lapi.c
${lua_SOURCE_DIR}/lauxlib.c
${lua_SOURCE_DIR}/lbaselib.c
${lua_SOURCE_DIR}/lcode.c
${lua_SOURCE_DIR}/lcorolib.c
${lua_SOURCE_DIR}/lctype.c
${lua_SOURCE_DIR}/ldblib.c
${lua_SOURCE_DIR}/ldebug.c
${lua_SOURCE_DIR}/ldo.c
${lua_SOURCE_DIR}/ldump.c
${lua_SOURCE_DIR}/lfunc.c
${lua_SOURCE_DIR}/lgc.c
${lua_SOURCE_DIR}/linit.c
${lua_SOURCE_DIR}/liolib.c
${lua_SOURCE_DIR}/llex.c
${lua_SOURCE_DIR}/lmathlib.c
${lua_SOURCE_DIR}/lmem.c
${lua_SOURCE_DIR}/loadlib.c
${lua_SOURCE_DIR}/lobject.c
${lua_SOURCE_DIR}/lopcodes.c
${lua_SOURCE_DIR}/loslib.c
${lua_SOURCE_DIR}/lparser.c
${lua_SOURCE_DIR}/lstate.c
${lua_SOURCE_DIR}/lstring.c
${lua_SOURCE_DIR}/lstrlib.c
${lua_SOURCE_DIR}/ltable.c
${lua_SOURCE_DIR}/ltablib.c
${lua_SOURCE_DIR}/ltm.c
${lua_SOURCE_DIR}/lua.c
${lua_SOURCE_DIR}/lundump.c
${lua_SOURCE_DIR}/lutf8lib.c
${lua_SOURCE_DIR}/lvm.c
${lua_SOURCE_DIR}/lzio.c
)
endif() endif()
CPMAddPackage( CPMAddPackage(
@@ -152,6 +111,7 @@ CPMAddPackage(
"ALSOFT_STATIC_LIBGCC ON" "ALSOFT_STATIC_LIBGCC ON"
) )
# TODO: Clear this paths with *
file(GLOB SERVER_SOURCES file(GLOB SERVER_SOURCES
"project/lib_projects/raknet/jni/RaknetSources/*.cpp" "project/lib_projects/raknet/jni/RaknetSources/*.cpp"
"src/NinecraftApp.cpp" "src/NinecraftApp.cpp"
@@ -190,6 +150,7 @@ file(GLOB SERVER_SOURCES
"src/platform/CThread.cpp" "src/platform/CThread.cpp"
"src/platform/HttpClient.cpp" "src/platform/HttpClient.cpp"
"src/platform/PngLoader.cpp"
"src/platform/time.cpp" "src/platform/time.cpp"
"src/platform/input/Controller.cpp" "src/platform/input/Controller.cpp"
@@ -255,9 +216,6 @@ file(GLOB SERVER_SOURCES
"src/world/level/tile/entity/*.cpp" "src/world/level/tile/entity/*.cpp"
"src/world/phys/HitResult.cpp" "src/world/phys/HitResult.cpp"
"src/commands/*.cpp"
"src/plugins/*.cpp"
) )
file(GLOB CLIENT_SOURCES file(GLOB CLIENT_SOURCES
@@ -341,10 +299,6 @@ file(GLOB CLIENT_SOURCES
"src/AppPlatform_glfw.cpp" "src/AppPlatform_glfw.cpp"
"src/main.cpp" "src/main.cpp"
"src/commands/*.cpp"
"src/plugins/*.cpp"
) )
if (${PLATFORM} STREQUAL "Desktop") if (${PLATFORM} STREQUAL "Desktop")
@@ -352,21 +306,21 @@ if (${PLATFORM} STREQUAL "Desktop")
endif() endif()
# Server # Server
add_executable("${PROJECT_NAME}-server" ${SERVER_SOURCES}) if(UNIX)
set_target_properties("${PROJECT_NAME}-server" PROPERTIES ENABLE_EXPORTS TRUE) add_executable("${PROJECT_NAME}-server" ${SERVER_SOURCES})
target_compile_definitions("${PROJECT_NAME}-server" PUBLIC "STANDALONE_SERVER" "SERVER_PROFILER")
target_include_directories("${PROJECT_NAME}-server" PUBLIC target_compile_definitions("${PROJECT_NAME}-server" PUBLIC "STANDALONE_SERVER" "SERVER_PROFILER")
target_include_directories("${PROJECT_NAME}-server" PUBLIC
"${CMAKE_SOURCE_DIR}/glad/include/"
"${CMAKE_SOURCE_DIR}/src/" "${CMAKE_SOURCE_DIR}/src/"
"${lua_SOURCE_DIR}/"
"project/lib_projects/raknet/jni/RaknetSources" "project/lib_projects/raknet/jni/RaknetSources"
) )
target_link_libraries("${PROJECT_NAME}-server" ${CMAKE_THREAD_LIBS_INIT} ${EXTRA_LIBS} lua sol2::sol2) target_link_libraries("${PROJECT_NAME}-server" ${CMAKE_THREAD_LIBS_INIT})
endif()
add_executable(${PROJECT_NAME} ${CLIENT_SOURCES}) add_executable(${PROJECT_NAME} ${CLIENT_SOURCES})
set_target_properties(${PROJECT_NAME} PROPERTIES ENABLE_EXPORTS TRUE)
target_compile_definitions(${PROJECT_NAME} PUBLIC ${PLATFORM_CPP}) target_compile_definitions(${PROJECT_NAME} PUBLIC ${PLATFORM_CPP})
@@ -376,8 +330,6 @@ target_include_directories(${PROJECT_NAME} PUBLIC
"${openal_SOURCE_DIR}/include" "${openal_SOURCE_DIR}/include"
"${glfw_SOURCE_DIR}/include" "${glfw_SOURCE_DIR}/include"
"lib/include" "lib/include"
"${lua_SOURCE_DIR}/"
) )
if(${PLATFORM} MATCHES "Web") if(${PLATFORM} MATCHES "Web")
@@ -387,7 +339,11 @@ if(${PLATFORM} MATCHES "Web")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EM_FLAGS}") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EM_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EM_FLAGS}") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EM_FLAGS}")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${EM_FLAGS} --preload-file ${CMAKE_SOURCE_DIR}/data@/data") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${EM_FLAGS} --preload-file \"${CMAKE_SOURCE_DIR}/data@/data\"")
set_target_properties(${PROJECT_NAME} PROPERTIES RULE_LAUNCH_LINK "set EMCC_WASM_OPT=0 &&")
# Remove -g (DWARF) to prevent wasm-opt post-link optimizations from running
string(REPLACE "-g" "" CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO}")
string(REPLACE "-g" "" CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
target_compile_options(${PROJECT_NAME} PUBLIC target_compile_options(${PROJECT_NAME} PUBLIC
"-Os" "-Os"
@@ -403,7 +359,7 @@ if(${PLATFORM} MATCHES "Web")
"-sFORCE_FILESYSTEM=1" "-sFORCE_FILESYSTEM=1"
"-sLEGACY_GL_EMULATION=1" "-sLEGACY_GL_EMULATION=1"
"-sGL_UNSAFE_OPTS=0" "-sGL_UNSAFE_OPTS=0"
"-sEMULATE_FUNCTION_POINTER_CASTS=1" "-sEMULATE_FUNCTION_POINTER_CASTS=0"
"-sALLOW_TABLE_GROWTH=1" "-sALLOW_TABLE_GROWTH=1"
"-sEXPORTED_RUNTIME_METHODS=['FS','stringToUTF8','UTF8ToString','cwrap','ccall','HEAP8','HEAPU8','HEAP32','HEAPU32']" "-sEXPORTED_RUNTIME_METHODS=['FS','stringToUTF8','UTF8ToString','cwrap','ccall','HEAP8','HEAPU8','HEAP32','HEAPU32']"
"-sEXPORTED_FUNCTIONS=['_main']" "-sEXPORTED_FUNCTIONS=['_main']"
@@ -425,7 +381,7 @@ endif()
# Client # Client
target_compile_definitions(${PROJECT_NAME} PUBLIC "OPENGL_ES" "NO_EGL" ${PLATFORM}) target_compile_definitions(${PROJECT_NAME} PUBLIC "OPENGL_ES" "NO_EGL" ${PLATFORM})
target_link_libraries(${PROJECT_NAME} zlib ${PNG_LIB} OpenAL::OpenAL glfw ${EXTRA_LIBS} lua sol2::sol2) target_link_libraries(${PROJECT_NAME} zlib ${PNG_LIB} OpenAL::OpenAL glfw ${EXTRA_LIBS})
if (OpenSSL_FOUND) if (OpenSSL_FOUND)
target_link_libraries(${PROJECT_NAME} OpenSSL::SSL OpenSSL::Crypto) target_link_libraries(${PROJECT_NAME} OpenSSL::SSL OpenSSL::Crypto)
@@ -452,6 +408,10 @@ else()
TARGET ${PROJECT_NAME} TARGET ${PROJECT_NAME}
POST_BUILD POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_SOURCE_DIR}/misc/web/index.html" $<TARGET_FILE_DIR:${PROJECT_NAME}> COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_SOURCE_DIR}/misc/web/index.html" $<TARGET_FILE_DIR:${PROJECT_NAME}>
COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_SOURCE_DIR}/misc/web/coi-serviceworker.js" $<TARGET_FILE_DIR:${PROJECT_NAME}>
COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_SOURCE_DIR}/misc/web/manifest.json" $<TARGET_FILE_DIR:${PROJECT_NAME}>
COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_SOURCE_DIR}/misc/web/icon-192.png" $<TARGET_FILE_DIR:${PROJECT_NAME}>
COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_SOURCE_DIR}/misc/web/icon-512.png" $<TARGET_FILE_DIR:${PROJECT_NAME}>
) )
endif() endif()

View File

@@ -176,7 +176,7 @@ cmake --build .
2. Configure and build project: 2. Configure and build project:
``` ```
mkdir build && cd build mkdir build && cd build
cmake .. -B . -G Ninja "-DCMAKE_TOOLCHAIN_FILE=$EMSDK/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake" cmake .. -G Ninja -DCMAKE_TOOLCHAIN_FILE="$env:EMSDK/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake"
cmake --build . --target MinecraftPE cmake --build . --target MinecraftPE
``` ```
> [!Note] > [!Note]

View File

@@ -207,6 +207,7 @@ options.graphics.fancy=Fancy
options.graphics.fast=Fast options.graphics.fast=Fast
options.guiScale=GUI Scale options.guiScale=GUI Scale
options.guiScale.auto=Auto options.guiScale.auto=Auto
options.guiScale.tiny=Tiny
options.guiScale.small=Small options.guiScale.small=Small
options.guiScale.medium=Medium options.guiScale.medium=Medium
options.guiScale.large=Large options.guiScale.large=Large
@@ -225,6 +226,7 @@ options.smoothCamera=Smooth camera
options.destroyVibration=Destroy vibration options.destroyVibration=Destroy vibration
options.isLeftHanded=Left handed options.isLeftHanded=Left handed
options.useTouchscreen=Use touchscreen options.useTouchscreen=Use touchscreen
options.touchOverride=Touch Mode Override
options.fancyGraphics=Fancy graphics options.fancyGraphics=Fancy graphics
options.renderDebug=Debug render options.renderDebug=Debug render
options.anaglyph3d=3D anaglyph options.anaglyph3d=3D anaglyph

View File

@@ -0,0 +1,26 @@
/* coi-serviceworker.js - Cross-Origin Isolation + PWA support */
// Service Worker context
self.addEventListener("install", () => self.skipWaiting());
self.addEventListener("activate", (event) =>
event.waitUntil(self.clients.claim())
);
self.addEventListener("fetch", (event) => {
if (event.request.method !== "GET") return;
event.respondWith(
fetch(event.request).then((response) => {
if (response.status === 0 || response.type === "opaque") return response;
const headers = new Headers(response.headers);
headers.set("Cross-Origin-Embedder-Policy", "require-corp");
headers.set("Cross-Origin-Opener-Policy", "same-origin");
headers.set("Cross-Origin-Resource-Policy", "cross-origin");
return new Response(response.body, {
status: response.status,
statusText: response.statusText,
headers,
});
}).catch(() => fetch(event.request))
);
});

BIN
misc/web/icon-192.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

BIN
misc/web/icon-512.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

View File

@@ -2,6 +2,12 @@
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="manifest" href="manifest.json">
<meta name="theme-color" content="#000000">
<meta name="mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-capable" content="yes">
<link rel="apple-touch-icon" href="icon-192.png">
<title>MCPE 0.6.1</title> <title>MCPE 0.6.1</title>
<style> <style>
html, body { html, body {
@@ -16,6 +22,10 @@
width: 100vw; width: 100vw;
height: 100vh; height: 100vh;
display: block; display: block;
touch-action: none;
user-select: none;
-webkit-user-select: none;
-webkit-tap-highlight-color: transparent;
} }
</style> </style>
</head> </head>
@@ -23,6 +33,40 @@
<canvas id="canvas"></canvas> <canvas id="canvas"></canvas>
<script>
if ('serviceWorker' in navigator) {
var reloadedForSw = false;
navigator.serviceWorker.register('./coi-serviceworker.js', { scope: './' }).then(function () {
navigator.serviceWorker.addEventListener('controllerchange', function () {
if (reloadedForSw) return;
reloadedForSw = true;
window.location.reload();
});
}).catch(function (error) {
console.warn('Service worker registration failed:', error);
});
}
</script>
<script>
function isAndroid() {
return /Android/i.test(navigator.userAgent || '');
}
function lockLandscapeOnAndroid() {
if (!isAndroid()) return;
var orientation = screen.orientation;
if (!orientation || typeof orientation.lock !== 'function') return;
orientation.lock('landscape').catch(function () {});
}
lockLandscapeOnAndroid();
window.addEventListener('pointerdown', lockLandscapeOnAndroid, { once: true });
window.addEventListener('touchstart', lockLandscapeOnAndroid, { once: true, passive: true });
</script>
<script> <script>
var Module = { var Module = {
canvas: document.getElementById('canvas'), canvas: document.getElementById('canvas'),

25
misc/web/manifest.json Normal file
View File

@@ -0,0 +1,25 @@
{
"name": "MCPE 0.6.1",
"short_name": "MCPE 0.6.1",
"description": "Minecraft Pocket Edition 0.6.1 Alpha - Web Build",
"id": "./",
"start_url": "./",
"scope": "./",
"display_override": ["standalone"],
"display": "standalone",
"orientation": "landscape",
"background_color": "#000000",
"theme_color": "#000000",
"icons": [
{
"src": "icon-192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "icon-512.png",
"sizes": "512x512",
"type": "image/png"
}
]
}

View File

@@ -167,6 +167,7 @@ options.graphics.fancy=Fancy
options.graphics.fast=Fast options.graphics.fast=Fast
options.guiScale=GUI Scale options.guiScale=GUI Scale
options.guiScale.auto=Auto options.guiScale.auto=Auto
options.guiScale.tiny=Tiny
options.guiScale.small=Small options.guiScale.small=Small
options.guiScale.medium=Medium options.guiScale.medium=Medium
options.guiScale.large=Large options.guiScale.large=Large

View File

@@ -110,7 +110,6 @@ LOCAL_SRC_FILES := ../../../src/main.cpp \
../../../src/client/renderer/Textures.cpp \ ../../../src/client/renderer/Textures.cpp \
../../../src/client/renderer/TileRenderer.cpp \ ../../../src/client/renderer/TileRenderer.cpp \
../../../src/client/renderer/gles.cpp \ ../../../src/client/renderer/gles.cpp \
../../../src/world/level/LevelConstants.cpp \
../../../src/client/renderer/culling/Frustum.cpp \ ../../../src/client/renderer/culling/Frustum.cpp \
../../../src/client/renderer/entity/ArrowRenderer.cpp \ ../../../src/client/renderer/entity/ArrowRenderer.cpp \
../../../src/client/renderer/entity/ChickenRenderer.cpp \ ../../../src/client/renderer/entity/ChickenRenderer.cpp \
@@ -141,12 +140,6 @@ LOCAL_SRC_FILES := ../../../src/main.cpp \
../../../src/network/Packet.cpp \ ../../../src/network/Packet.cpp \
../../../src/network/RakNetInstance.cpp \ ../../../src/network/RakNetInstance.cpp \
../../../src/network/ServerSideNetworkHandler.cpp \ ../../../src/network/ServerSideNetworkHandler.cpp \
../../../src/commands/Command.cpp \
../../../src/commands/CommandHelp.cpp \
../../../src/commands/CommandKick.cpp \
../../../src/commands/CommandBan.cpp \
../../../src/commands/CommandManager.cpp \
../../../src/commands/CommandOp.cpp \
../../../src/server/ServerLevel.cpp \ ../../../src/server/ServerLevel.cpp \
../../../src/server/ServerPlayer.cpp \ ../../../src/server/ServerPlayer.cpp \
../../../src/util/DataIO.cpp \ ../../../src/util/DataIO.cpp \

View File

@@ -167,6 +167,7 @@ options.graphics.fancy=Fancy
options.graphics.fast=Fast options.graphics.fast=Fast
options.guiScale=GUI Scale options.guiScale=GUI Scale
options.guiScale.auto=Auto options.guiScale.auto=Auto
options.guiScale.tiny=Tiny
options.guiScale.small=Small options.guiScale.small=Small
options.guiScale.medium=Medium options.guiScale.medium=Medium
options.guiScale.large=Large options.guiScale.large=Large

View File

@@ -232,7 +232,6 @@ LOCAL_SRC_FILES := ../../../src/main.cpp \
../../../src/world/level/tile/entity/TileEntity.cpp \ ../../../src/world/level/tile/entity/TileEntity.cpp \
../../../src/world/level/tile/entity/FurnaceTileEntity.cpp \ ../../../src/world/level/tile/entity/FurnaceTileEntity.cpp \
../../../src/world/phys/HitResult.cpp ../../../src/world/phys/HitResult.cpp
../../../src/world/level/LevelConstants.cpp
LOCAL_CFLAGS := -Wno-psabi $(LOCAL_CFLAGS) LOCAL_CFLAGS := -Wno-psabi $(LOCAL_CFLAGS)

View File

@@ -140,7 +140,7 @@ RakNet::TimeUS GetTimeUS_Windows( void )
#if _MSC_VER >= 1400 && defined (_M_X64) #if _MSC_VER >= 1400 && defined (_M_X64)
GetProcessAffinityMask(mProc, (PDWORD_PTR)&mProcMask, (PDWORD_PTR)&mSysMask); GetProcessAffinityMask(mProc, (PDWORD_PTR)&mProcMask, (PDWORD_PTR)&mSysMask);
#else #else
GetProcessAffinityMask(mProc, (PDWORD_PTR)&mProcMask, (PDWORD_PTR)&mSysMask); GetProcessAffinityMask(mProc, &mProcMask, &mSysMask);
#endif #endif
mThread = GetCurrentThread(); mThread = GetCurrentThread();

View File

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

View File

@@ -115,10 +115,11 @@ void NinecraftApp::init()
LOGI("This: %p\n", this); LOGI("This: %p\n", this);
screenChooser.setScreen(SCREEN_STARTMENU); screenChooser.setScreen(SCREEN_STARTMENU);
if (options.getBooleanValue(OPTIONS_FIRST_LAUNCH)) { // Disabled: Show username screen on first launch
options.toggle(OPTIONS_FIRST_LAUNCH); // if (options.getBooleanValue(OPTIONS_FIRST_LAUNCH)) {
setScreen(new UsernameScreen()); // options.toggle(OPTIONS_FIRST_LAUNCH);
} // setScreen(new UsernameScreen());
// }
#else #else
hostMultiplayer(); hostMultiplayer();
#endif #endif
@@ -136,7 +137,7 @@ void NinecraftApp::teardown()
Recipes ::teardownRecipes(); Recipes ::teardownRecipes();
TileEntity::teardownTileEntities(); TileEntity::teardownTileEntities();
#endif #endif
#if defined(WIN32) && !defined(STANDALONE_SERVER) #ifdef WIN32
ItemRenderer::teardown_static(); ItemRenderer::teardown_static();
if (EntityTileRenderer::instance != NULL) { if (EntityTileRenderer::instance != NULL) {
delete EntityTileRenderer::instance; delete EntityTileRenderer::instance;

View File

@@ -2,7 +2,6 @@
#include "Options.h" #include "Options.h"
#include "client/Options.h" #include "client/Options.h"
#include "client/player/input/IBuildInput.h" #include "client/player/input/IBuildInput.h"
#include "commands/CommandManager.hpp"
#include "platform/input/Keyboard.h" #include "platform/input/Keyboard.h"
#include "world/item/Item.h" #include "world/item/Item.h"
#include "world/item/ItemInstance.h" #include "world/item/ItemInstance.h"
@@ -92,14 +91,10 @@
#include "../network/command/CommandServer.h" #include "../network/command/CommandServer.h"
#include "gamemode/CreatorMode.h" #include "gamemode/CreatorMode.h"
#ifndef STANDALONE_SERVER
#include "../world/level/GrassColor.h" #include "../world/level/GrassColor.h"
#include "renderer/LevelRenderer.h" #include "renderer/LevelRenderer.h"
#include "particle/ParticleEngine.h" #include "particle/ParticleEngine.h"
#endif
#include "../world/level/Level.h" #include "../world/level/Level.h"
static void checkGlError(const char* tag) { static void checkGlError(const char* tag) {
#ifdef GLDEBUG #ifdef GLDEBUG
while (1) { while (1) {
@@ -185,8 +180,7 @@ Minecraft::Minecraft() :
_powerVr(false), _powerVr(false),
commandPort(4711), commandPort(4711),
reserved_d1(0),reserved_d2(0), reserved_d1(0),reserved_d2(0),
reserved_f1(0),reserved_f2(0), options(this), reserved_f1(0),reserved_f2(0), options(this)
m_commandManager()
{ {
//#ifdef ANDROID //#ifdef ANDROID
@@ -267,10 +261,9 @@ void Minecraft::selectLevel( const std::string& levelId, const std::string& leve
void Minecraft::setLevel(Level* level, const std::string& message /* ="" */, LocalPlayer* forceInsertPlayer /* = NULL */) { void Minecraft::setLevel(Level* level, const std::string& message /* ="" */, LocalPlayer* forceInsertPlayer /* = NULL */) {
cameraTargetPlayer = NULL; cameraTargetPlayer = NULL;
if (level != NULL) {
LOGI("Seed is %ld\n", level->getSeed()); LOGI("Seed is %ld\n", level->getSeed());
if (level != NULL) {
level->raknetInstance = raknetInstance; level->raknetInstance = raknetInstance;
gameMode->initLevel(level); gameMode->initLevel(level);
@@ -287,7 +280,6 @@ void Minecraft::setLevel(Level* level, const std::string& message /* ="" */, Loc
} }
} }
this->level = level; this->level = level;
_hasSignaledGeneratingLevelFinished = false; _hasSignaledGeneratingLevelFinished = false;
#ifdef STANDALONE_SERVER #ifdef STANDALONE_SERVER
const bool threadedLevelCreation = false; const bool threadedLevelCreation = false;
@@ -371,10 +363,10 @@ void Minecraft::prepareLevel(const std::string& title) {
if (!level->isNew()) if (!level->isNew())
level->setUpdateLights(false); level->setUpdateLights(false);
int Max = LevelConstants::CHUNK_CACHE_WIDTH * LevelConstants::CHUNK_CACHE_WIDTH; int Max = CHUNK_CACHE_WIDTH * CHUNK_CACHE_WIDTH;
int pp = 0; int pp = 0;
for (int x = 8; x < (LevelConstants::CHUNK_CACHE_WIDTH * LevelConstants::CHUNK_WIDTH); x += LevelConstants::CHUNK_WIDTH) { for (int x = 8; x < (CHUNK_CACHE_WIDTH * CHUNK_WIDTH); x += CHUNK_WIDTH) {
for (int z = 8; z < (LevelConstants::CHUNK_CACHE_WIDTH * LevelConstants::CHUNK_WIDTH); z += LevelConstants::CHUNK_WIDTH) { for (int z = 8; z < (CHUNK_CACHE_WIDTH * CHUNK_WIDTH); z += CHUNK_WIDTH) {
progressStagePercentage = 100 * pp++ / Max; progressStagePercentage = 100 * pp++ / Max;
//printf("level generation progress %d\n", progressStagePercentage); //printf("level generation progress %d\n", progressStagePercentage);
B.start(); B.start();
@@ -391,9 +383,9 @@ void Minecraft::prepareLevel(const std::string& title) {
level->setUpdateLights(true); level->setUpdateLights(true);
C.start(); C.start();
for (int x = 0; x < LevelConstants::CHUNK_CACHE_WIDTH; x++) for (int x = 0; x < CHUNK_CACHE_WIDTH; x++)
{ {
for (int z = 0; z < LevelConstants::CHUNK_CACHE_WIDTH; z++) for (int z = 0; z < CHUNK_CACHE_WIDTH; z++)
{ {
LevelChunk* chunk = level->getChunk(x, z); LevelChunk* chunk = level->getChunk(x, z);
if (chunk && !chunk->createdFromSave) if (chunk && !chunk->createdFromSave)
@@ -741,21 +733,6 @@ void Minecraft::tickInput() {
options.toggle(OPTIONS_RENDER_DEBUG); options.toggle(OPTIONS_RENDER_DEBUG);
} }
// TODO: replace it with client /give command :face_vomiting:
// if (key == Keyboard::KEY_F4) {
// player->inventory->add(new ItemInstance(Tile::redBrick));
// player->inventory->add(new ItemInstance(Item::ironIngot, 64));
// player->inventory->add(new ItemInstance(Item::ironIngot, 34));
// player->inventory->add(new ItemInstance(Tile::stonecutterBench));
// player->inventory->add(new ItemInstance(Tile::workBench));
// player->inventory->add(new ItemInstance(Tile::furnace));
// player->inventory->add(new ItemInstance(Tile::wood, 54));
// player->inventory->add(new ItemInstance(Item::stick, 14));
// player->inventory->add(new ItemInstance(Item::coal, 31));
// player->inventory->add(new ItemInstance(Tile::sand, 6));
// }
if (key == Keyboard::KEY_F5) { if (key == Keyboard::KEY_F5) {
options.toggle(OPTIONS_THIRD_PERSON_VIEW); options.toggle(OPTIONS_THIRD_PERSON_VIEW);
/* /*
@@ -880,7 +857,6 @@ void Minecraft::tickInput() {
for (int i = 0; i < 5 * SharedConstants::TicksPerSecond; ++i) for (int i = 0; i < 5 * SharedConstants::TicksPerSecond; ++i)
level->tick(); level->tick();
} }
#endif #endif
} }
@@ -906,9 +882,6 @@ void Minecraft::tickInput() {
handleBuildAction(&bai); handleBuildAction(&bai);
} else { } else {
gameMode->stopDestroyBlock(); gameMode->stopDestroyBlock();
if (player && player->isUsingItem()) {
gameMode->releaseUsingItem(player);
}
} }
} else { } else {
// Desktop: left mouse = destroy/attack // Desktop: left mouse = destroy/attack
@@ -1152,6 +1125,9 @@ bool Minecraft::useTouchscreen() {
#elif defined(RPI) #elif defined(RPI)
return false; return false;
#endif #endif
if (options.getBooleanValue(OPTIONS_TOUCH_OVERRIDE)) {
return options.getBooleanValue(OPTIONS_USE_TOUCHSCREEN);
}
return options.getBooleanValue(OPTIONS_USE_TOUCHSCREEN) && !_supportsNonTouchscreen; return options.getBooleanValue(OPTIONS_USE_TOUCHSCREEN) && !_supportsNonTouchscreen;
} }
bool Minecraft::supportNonTouchScreen() { bool Minecraft::supportNonTouchScreen() {
@@ -1159,7 +1135,6 @@ bool Minecraft::supportNonTouchScreen() {
} }
void Minecraft::init() void Minecraft::init()
{ {
LevelChunk::ChunkBlockCount = LevelConstants::CHUNK_BLOCK_COUNT;
#ifndef STANDALONE_SERVER #ifndef STANDALONE_SERVER
checkGlError("Init enter"); checkGlError("Init enter");
@@ -1210,8 +1185,6 @@ void Minecraft::init()
checkGlError("Init complete"); checkGlError("Init complete");
#endif #endif
PluginsManager::get().init(*this);
options.load(); options.load();
setIsCreativeMode(false); // false means it's Survival Mode setIsCreativeMode(false); // false means it's Survival Mode
@@ -1247,13 +1220,14 @@ void Minecraft::setSize(int w, int h) {
// determine gui scale, optionally overriding auto // determine gui scale, optionally overriding auto
if (guiScale != 0) { if (guiScale != 0) {
// manual selection: 1->small, 2->medium, 3->large, 4->larger, 5->largest // manual selection: 1->tiny, 2->small, 3->medium, 4->large, 5->larger, 6->largest
switch (guiScale) { switch (guiScale) {
case 1: Gui::GuiScale = 2.0f; break; case 1: Gui::GuiScale = 1.0f; break;
case 2: Gui::GuiScale = 3.0f; break; case 2: Gui::GuiScale = 2.0f; break;
case 3: Gui::GuiScale = 4.0f; break; case 3: Gui::GuiScale = 3.0f; break;
case 4: Gui::GuiScale = 5.0f; break; case 4: Gui::GuiScale = 4.0f; break;
case 5: Gui::GuiScale = 6.0f; break; case 5: Gui::GuiScale = 5.0f; break;
case 6: Gui::GuiScale = 6.0f; break;
default: Gui::GuiScale = 1.0f; break; // auto default: Gui::GuiScale = 1.0f; break; // auto
} }
} else { } else {
@@ -1313,16 +1287,15 @@ void Minecraft::setSize(int w, int h) {
void Minecraft::reloadOptions() { void Minecraft::reloadOptions() {
options.save(); options.save();
bool wasTouchscreen = options.getBooleanValue(OPTIONS_USE_TOUCHSCREEN);
options.set(OPTIONS_USE_TOUCHSCREEN, useTouchscreen());
options.save();
if ((wasTouchscreen != useTouchscreen()) || (inputHolder == 0)) bool useTouch = useTouchscreen();
_reloadInput(); _reloadInput();
gui.refreshTouchState();
// user->name = options.username; // user->name = options.username;
LOGI("Reloading-options\n"); LOGI("Reloading-options (touch=%d)\n", useTouch);
// @todo @fix Android and iOS behaves a bit differently when leaving // @todo @fix Android and iOS behaves a bit differently when leaving
// an options screen (Android recreates OpenGL surface) // an options screen (Android recreates OpenGL surface)
@@ -1400,8 +1373,11 @@ bool Minecraft::joinMultiplayerFromString( const std::string& server )
ip = server; ip = server;
} }
printf("%s \n", port.c_str());
if (isLookingForMultiplayer && netCallback) { if (isLookingForMultiplayer && netCallback) {
isLookingForMultiplayer = false; isLookingForMultiplayer = false;
printf("test");
int portNum = atoi(port.c_str()); int portNum = atoi(port.c_str());
return raknetInstance->connect(ip.c_str(), portNum); return raknetInstance->connect(ip.c_str(), portNum);
} }
@@ -1709,11 +1685,3 @@ void Minecraft::optionUpdated(OptionId option, int value ) {
setSize(width, height); setSize(width, height);
} }
} }
void Minecraft::addMessage(const std::string& msg) {
#ifndef STANDALONE_SERVER
gui.addMessage(msg);
#else
LOGI("%s \n", msg.c_str());
#endif
}

View File

@@ -2,9 +2,6 @@
#define NET_MINECRAFT_CLIENT__Minecraft_H__ #define NET_MINECRAFT_CLIENT__Minecraft_H__
#include "Options.h" #include "Options.h"
#include "commands/CommandManager.hpp"
#include <plugins/PluginsManager.hpp>
#ifndef STANDALONE_SERVER #ifndef STANDALONE_SERVER
#include "MouseHandler.h" #include "MouseHandler.h"
#include "gui/Gui.h" #include "gui/Gui.h"
@@ -131,17 +128,11 @@ public:
void optionUpdated(OptionId option, bool value); void optionUpdated(OptionId option, bool value);
void optionUpdated(OptionId option, float value); void optionUpdated(OptionId option, float value);
void optionUpdated(OptionId option, int value); void optionUpdated(OptionId option, int value);
int getTicks() { return ticks; }
void addMessage(const std::string& msg);
#ifdef __APPLE__ #ifdef __APPLE__
bool _isSuperFast; bool _isSuperFast;
bool isSuperFast() { return _isSuperFast; } bool isSuperFast() { return _isSuperFast; }
#endif #endif
CommandManager& commandManager() { return m_commandManager; }
protected: protected:
void _levelGenerated(); void _levelGenerated();
@@ -214,7 +205,6 @@ public:
std::string externalCacheStoragePath; std::string externalCacheStoragePath;
protected: protected:
Timer timer; Timer timer;
// @note @attn @warn: this is dangerous as fuck! // @note @attn @warn: this is dangerous as fuck!
volatile bool isGeneratingLevel; volatile bool isGeneratingLevel;
bool _hasSignaledGeneratingLevelFinished; bool _hasSignaledGeneratingLevelFinished;
@@ -243,8 +233,6 @@ private:
PerfRenderer* _perfRenderer; PerfRenderer* _perfRenderer;
CommandServer* _commandServer; CommandServer* _commandServer;
CommandManager m_commandManager;
}; };
#endif /*NET_MINECRAFT_CLIENT__Minecraft_H__*/ #endif /*NET_MINECRAFT_CLIENT__Minecraft_H__*/

View File

@@ -22,3 +22,5 @@ const char* OptionStrings::Controls_AutoJump = "ctrl_autojump";
const char* OptionStrings::Game_DifficultyLevel = "game_difficulty"; const char* OptionStrings::Game_DifficultyLevel = "game_difficulty";
const char* OptionStrings::Tweaks_TouchOverride = "options.touchOverride";

View File

@@ -30,6 +30,7 @@ public:
static const char* Tweaks_Sprint; static const char* Tweaks_Sprint;
static const char* Tweaks_BarOnTop; static const char* Tweaks_BarOnTop;
static const char* Tweaks_TouchOverride;
}; };

View File

@@ -27,14 +27,14 @@ OptionBool autoJump("autoJump", true);
OptionFloat flySpeed("flySpeed", 1.f); OptionFloat flySpeed("flySpeed", 1.f);
OptionFloat cameraSpeed("cameraSpeed", 1.f); OptionFloat cameraSpeed("cameraSpeed", 1.f);
OptionInt guiScale("guiScale", 0, 0, 5); OptionInt guiScale("guiScale", 0, 0, 6);
OptionString skin("skin", "Default"); OptionString skin("skin", "Default");
#ifdef RPI #ifdef RPI
OptionString username("username", "StevePi"); OptionString username("username", "test");
#else #else
OptionString username("username", "Steve"); OptionString username("username", "test");
#endif #endif
OptionBool destroyVibration("destroyVibration", true); OptionBool destroyVibration("destroyVibration", true);
@@ -64,6 +64,8 @@ OptionBool useVignette("useVignette", true);
OptionBool useTouchscreen("useTouchscreen", true); OptionBool useTouchscreen("useTouchscreen", true);
OptionBool touchOverride("touchOverride", false);
OptionBool serverVisible("servervisible", true); OptionBool serverVisible("servervisible", true);
OptionBool foliageTint("foliagetint", true); OptionBool foliageTint("foliagetint", true);
@@ -173,6 +175,8 @@ void Options::initTable() {
m_options[OPTIONS_RESTORED_ANIMS] = &restoredAnims; m_options[OPTIONS_RESTORED_ANIMS] = &restoredAnims;
m_options[OPTIONS_TOUCH_OVERRIDE] = &touchOverride;
m_options[OPTIONS_SERVER_VISIBLE] = &serverVisible; m_options[OPTIONS_SERVER_VISIBLE] = &serverVisible;
m_options[OPTIONS_MENU_STYLE] = &menuStyle; m_options[OPTIONS_MENU_STYLE] = &menuStyle;

View File

@@ -92,6 +92,7 @@ enum OptionId {
OPTIONS_FOG_TYPE, OPTIONS_FOG_TYPE,
OPTIONS_JAVA_HUD, OPTIONS_JAVA_HUD,
OPTIONS_RESTORED_ANIMS, OPTIONS_RESTORED_ANIMS,
OPTIONS_TOUCH_OVERRIDE,
OPTIONS_TINTED_SIDE, OPTIONS_TINTED_SIDE,
OPTIONS_BETA_SKY, OPTIONS_BETA_SKY,
OPTIONS_BEAUTIFUL_SKY, OPTIONS_BEAUTIFUL_SKY,

View File

@@ -90,12 +90,8 @@ bool GameMode::useItemOn(Player* player, Level* level, ItemInstance* item, int x
float clickY = hit.y - y; float clickY = hit.y - y;
float clickZ = hit.z - z; float clickZ = hit.z - z;
if (level->isClientSide) { if (level->isClientSide) {
LOGI("%f %f %f \n", player->x, player->y, player->z);
item = player->inventory->getSelected(); item = player->inventory->getSelected();
UseItemPacket packet(x, y, z, face, item, player->entityId, clickX, clickY, clickZ, player->x, player->y, player->z, UseItemPacket packet(x, y, z, face, item, player->entityId, clickX, clickY, clickZ);
player->bb.x0, player->bb.y0, player->bb.z0, player->bb.x1, player->bb.y1, player->bb.z1);
minecraft->raknetInstance->send(packet); minecraft->raknetInstance->send(packet);
} }
int t = level->getTile(x, y, z); int t = level->getTile(x, y, z);
@@ -104,7 +100,7 @@ bool GameMode::useItemOn(Player* player, Level* level, ItemInstance* item, int x
return true; return true;
if (item == NULL) return false; if (item == NULL) return false;
if (isCreativeType()) { if(isCreativeType()) {
int aux = item->getAuxValue(); int aux = item->getAuxValue();
int count = item->count; int count = item->count;
bool success = item->useOn(player, level, x, y, z, face, clickX, clickY, clickZ); bool success = item->useOn(player, level, x, y, z, face, clickX, clickY, clickZ);
@@ -121,8 +117,7 @@ bool GameMode::useItem( Player* player, Level* level, ItemInstance* item ) {
ItemInstance* itemInstance = item->use(level, player); ItemInstance* itemInstance = item->use(level, player);
if(level->isClientSide) { if(level->isClientSide) {
UseItemPacket packet(item, player->entityId, player->aimDirection, player->x, player->y, player->z, UseItemPacket packet(item, player->entityId, player->aimDirection);
player->bb.x0, player->bb.y0, player->bb.z0, player->bb.x1, player->bb.y1, player->bb.z1);
minecraft->raknetInstance->send(packet); minecraft->raknetInstance->send(packet);
} }
if (itemInstance != item || (itemInstance != NULL && itemInstance->count != oldCount)) { if (itemInstance != item || (itemInstance != NULL && itemInstance->count != oldCount)) {

View File

@@ -68,7 +68,6 @@ bool SurvivalMode::destroyBlock( int x, int y, int z, int face ) {
minecraft->player->inventory->clearSlot(minecraft->player->inventory->selected); minecraft->player->inventory->clearSlot(minecraft->player->inventory->selected);
} }
} }
if (changed && couldDestroy) { if (changed && couldDestroy) {
ItemInstance instance(t, 1, data); ItemInstance instance(t, 1, data);
Tile::tiles[t]->playerDestroy(minecraft->level, minecraft->player, x, y, z, data); Tile::tiles[t]->playerDestroy(minecraft->level, minecraft->player, x, y, z, data);

View File

@@ -224,8 +224,8 @@ void Gui::handleClick(int button, int x, int y) {
} }
} }
void Gui::handleKeyPressed(int key) void Gui::handleKeyPressed(int key)
{ {
bool isChatting = (minecraft->screen && (dynamic_cast<ChatScreen*>(minecraft->screen) || dynamic_cast<ConsoleScreen*>(minecraft->screen))); bool isChatting = (minecraft->screen && (dynamic_cast<ChatScreen*>(minecraft->screen) || dynamic_cast<ConsoleScreen*>(minecraft->screen)));
if (isChatting) { if (isChatting) {
// Allow scrolling the chat history with the mouse/keyboard when chat is open // Allow scrolling the chat history with the mouse/keyboard when chat is open
@@ -275,7 +275,7 @@ void Gui::handleClick(int button, int x, int y) {
{ {
minecraft->player->inventory->dropSlot(minecraft->player->inventory->selected, false); minecraft->player->inventory->dropSlot(minecraft->player->inventory->selected, false);
} }
} }
void Gui::scrollChat(int delta) { void Gui::scrollChat(int delta) {
if (delta == 0) if (delta == 0)
@@ -423,6 +423,10 @@ void Gui::inventoryUpdated() {
_inventoryNeedsUpdate = true; _inventoryNeedsUpdate = true;
} }
void Gui::refreshTouchState() {
_openInventorySlot = minecraft->useTouchscreen();
}
void Gui::onGraphicsReset() { void Gui::onGraphicsReset() {
inventoryUpdated(); inventoryUpdated();
} }
@@ -755,6 +759,7 @@ void Gui::renderDebugInfo() {
// Position // Position
float px = p->x, py = p->y - p->heightOffset, pz = p->z; float px = p->x, py = p->y - p->heightOffset, pz = p->z;
posTranslator.to(px, py, pz);
int bx = (int)floorf(px), by = (int)floorf(py), bz = (int)floorf(pz); int bx = (int)floorf(px), by = (int)floorf(py), bz = (int)floorf(pz);
int cx = bx >> 4, cz = bz >> 4; int cx = bx >> 4, cz = bz >> 4;
@@ -781,25 +786,6 @@ void Gui::renderDebugInfo() {
long day = worldTime / Level::TICKS_PER_DAY; long day = worldTime / Level::TICKS_PER_DAY;
long seed = lvl ? lvl->getSeed() : 0; long seed = lvl ? lvl->getSeed() : 0;
// Block looking at
std::string CurrentTile = "Air";
if (minecraft->hitResult.type == TILE) {
int LookingX = minecraft->hitResult.x;
int LookingY = minecraft->hitResult.y;
int LookingZ = minecraft->hitResult.z;
int tileID = minecraft->level->getTile(LookingX, LookingY, LookingZ);
if (tileID > 0 && tileID < 256){
Tile* LookingTile = Tile::tiles[tileID];
if (LookingTile != NULL) {
CurrentTile = LookingTile->getDescriptionId();
} else {
CurrentTile = "Unknown Tile";
}
} else {
CurrentTile = "Air";
}
}
// Build lines (NULL entry = blank gap) // Build lines (NULL entry = blank gap)
Font* font = minecraft->font; Font* font = minecraft->font;
@@ -838,9 +824,6 @@ void Gui::renderDebugInfo() {
sprintf(buf, "Biome: %s", biomeName); sprintf(buf, "Biome: %s", biomeName);
drawString(font, buf, 2, 124, 0xE0E0E0); drawString(font, buf, 2, 124, 0xE0E0E0);
sprintf(buf, "Looking at: %s", CurrentTile.c_str());
drawString(font, buf, 2, 134, 0xE0E0E0);
} }
else if (minecraft->options.getIntValue(OPTIONS_DEBUG_STYLE) == 1){ else if (minecraft->options.getIntValue(OPTIONS_DEBUG_STYLE) == 1){

View File

@@ -71,6 +71,7 @@ public:
void onGraphicsReset(); void onGraphicsReset();
void inventoryUpdated(); void inventoryUpdated();
void refreshTouchState();
void setNowPlaying(const std::string& string); void setNowPlaying(const std::string& string);
void displayClientMessage(const std::string& messageId); void displayClientMessage(const std::string& messageId);

View File

@@ -35,6 +35,17 @@ void GuiElementContainer::removeChild( GuiElement* element ) {
children.erase(it); children.erase(it);
} }
bool GuiElementContainer::containsPointInChildren(int x, int y) const {
for (std::vector<GuiElement*>::const_iterator it = children.begin(); it != children.end(); ++it) {
GuiElement* child = *it;
if (child == NULL || !child->visible) continue;
if (child->pointInside(x, y)) return true;
const GuiElementContainer* container = dynamic_cast<const GuiElementContainer*>(child);
if (container != NULL && container->containsPointInChildren(x, y)) return true;
}
return false;
}
void GuiElementContainer::tick( Minecraft* minecraft ) { void GuiElementContainer::tick( Minecraft* minecraft ) {
for(std::vector<GuiElement*>::iterator it = children.begin(); it != children.end(); ++it) { for(std::vector<GuiElement*>::iterator it = children.begin(); it != children.end(); ++it) {
(*it)->tick(minecraft); (*it)->tick(minecraft);

View File

@@ -13,6 +13,7 @@ public:
virtual void setupPositions(); virtual void setupPositions();
virtual void addChild(GuiElement* element); virtual void addChild(GuiElement* element);
virtual void removeChild(GuiElement* element); virtual void removeChild(GuiElement* element);
bool containsPointInChildren(int x, int y) const;
virtual void tick( Minecraft* minecraft ); virtual void tick( Minecraft* minecraft );

View File

@@ -6,14 +6,36 @@
#include "../../../locale/I18n.h" #include "../../../locale/I18n.h"
#include "TextOption.h" #include "TextOption.h"
#include "KeyOption.h" #include "KeyOption.h"
#include <algorithm>
#include "../Gui.h"
#include "../Screen.h"
#include "../../../platform/input/Mouse.h"
#include "../../../util/Mth.h"
OptionsGroup::OptionsGroup( std::string labelID ) { OptionsGroup::OptionsGroup( std::string labelID )
: contentHeight(0),
scrollOffsetY(0.0f),
maxScrollOffsetY(0.0f),
trackingScrollGesture(false),
scrollingGesture(false),
touchDispatched(false),
dragStartX(0),
dragStartY(0),
lastDragY(0),
touchStartX(0),
touchStartY(0) {
label = I18n::get(labelID); label = I18n::get(labelID);
} }
void OptionsGroup::setupPositions() { void OptionsGroup::setupPositions() {
const int labelHeight = 18;
const int bottomPadding = 36;
const float requestedScroll = scrollOffsetY;
const int scrollOffset = (int)requestedScroll;
int curY = y + labelHeight - scrollOffset;
const int contentStartY = y + labelHeight;
// First we write the header and then we add the items // First we write the header and then we add the items
int curY = y + 18;
for(std::vector<GuiElement*>::iterator it = children.begin(); it != children.end(); ++it) { for(std::vector<GuiElement*>::iterator it = children.begin(); it != children.end(); ++it) {
(*it)->width = width - 5; (*it)->width = width - 5;
@@ -22,16 +44,109 @@ void OptionsGroup::setupPositions() {
(*it)->setupPositions(); (*it)->setupPositions();
curY += (*it)->height + 3; curY += (*it)->height + 3;
} }
height = curY; curY += bottomPadding;
contentHeight = std::max(0, curY - contentStartY + scrollOffset);
maxScrollOffsetY = std::max(0, contentHeight - (height - labelHeight));
const float clampedScroll = Mth::clamp(requestedScroll, 0.0f, maxScrollOffsetY);
if (clampedScroll != requestedScroll) {
scrollOffsetY = clampedScroll;
setupPositions();
}
} }
void OptionsGroup::render( Minecraft* minecraft, int xm, int ym ) { void OptionsGroup::render( Minecraft* minecraft, int xm, int ym ) {
float padX = 10.0f; float padX = 10.0f;
float padY = 5.0f; float padY = 5.0f;
const int labelHeight = 18;
minecraft->font->draw(label, (float)x + padX, (float)y + padY, 0xffffffff, false); minecraft->font->draw(label, (float)x + padX, (float)y + padY, 0xffffffff, false);
glEnable2(GL_SCISSOR_TEST);
glScissor(
Gui::GuiScale * x,
minecraft->height - Gui::GuiScale * (y + height),
Gui::GuiScale * width,
Gui::GuiScale * (height - labelHeight)
);
super::render(minecraft, xm, ym); super::render(minecraft, xm, ym);
glDisable2(GL_SCISSOR_TEST);
}
void OptionsGroup::tick(Minecraft* minecraft) {
int xm = Mouse::getX();
int ym = Mouse::getY();
if (minecraft->screen != NULL) {
minecraft->screen->toGUICoordinate(xm, ym);
}
bool leftDown = Mouse::isButtonDown(MouseAction::ACTION_LEFT);
if (trackingScrollGesture && leftDown) {
int dy = ym - lastDragY;
int dx = xm - dragStartX;
if (!scrollingGesture) {
int totalDx = xm - dragStartX;
int totalDy = ym - dragStartY;
if (std::abs(totalDx) >= ScrollStartThreshold || std::abs(totalDy) >= ScrollStartThreshold) {
if (std::abs(totalDy) >= std::abs(totalDx)) {
scrollingGesture = true;
} else if (!touchDispatched) {
super::mouseClicked(minecraft, touchStartX, touchStartY, MouseAction::ACTION_LEFT);
touchDispatched = true;
}
}
}
if (scrollingGesture && dy != 0) {
scrollByPixels((float)dy);
}
lastDragY = ym;
}
super::tick(minecraft);
}
void OptionsGroup::mouseClicked(Minecraft* minecraft, int x, int y, int buttonNum) {
trackingScrollGesture = false;
scrollingGesture = false;
touchDispatched = false;
if (buttonNum == MouseAction::ACTION_LEFT && pointInside(x, y)) {
trackingScrollGesture = true;
dragStartX = x;
dragStartY = y;
lastDragY = y;
touchStartX = x;
touchStartY = y;
return;
}
super::mouseClicked(minecraft, x, y, buttonNum);
}
void OptionsGroup::mouseReleased(Minecraft* minecraft, int x, int y, int buttonNum) {
bool wasScrolling = scrollingGesture;
bool wasTracking = trackingScrollGesture;
trackingScrollGesture = false;
scrollingGesture = false;
if (buttonNum == MouseAction::ACTION_LEFT && wasTracking && !touchDispatched && pointInside(touchStartX, touchStartY)) {
super::mouseClicked(minecraft, touchStartX, touchStartY, buttonNum);
touchDispatched = true;
}
if (!wasScrolling) {
super::mouseReleased(minecraft, x, y, buttonNum);
}
}
void OptionsGroup::scrollByPixels(float deltaY) {
if (deltaY == 0.0f || maxScrollOffsetY <= 0.0f) return;
scrollOffsetY = Mth::clamp(scrollOffsetY - deltaY, 0.0f, maxScrollOffsetY);
setupPositions();
}
bool OptionsGroup::isScrollingGestureActive() const {
return trackingScrollGesture || scrollingGesture;
} }
OptionsGroup& OptionsGroup::addOptionItem(OptionId optId, Minecraft* minecraft ) { OptionsGroup& OptionsGroup::addOptionItem(OptionId optId, Minecraft* minecraft ) {

View File

@@ -17,7 +17,12 @@ public:
OptionsGroup(std::string labelID); OptionsGroup(std::string labelID);
virtual void setupPositions(); virtual void setupPositions();
virtual void render(Minecraft* minecraft, int xm, int ym); virtual void render(Minecraft* minecraft, int xm, int ym);
virtual void tick(Minecraft* minecraft);
virtual void mouseClicked(Minecraft* minecraft, int x, int y, int buttonNum);
virtual void mouseReleased(Minecraft* minecraft, int x, int y, int buttonNum);
OptionsGroup& addOptionItem(OptionId optId, Minecraft* minecraft); OptionsGroup& addOptionItem(OptionId optId, Minecraft* minecraft);
void scrollByPixels(float deltaY);
bool isScrollingGestureActive() const;
protected: protected:
void createToggle(OptionId optId, Minecraft* minecraft); void createToggle(OptionId optId, Minecraft* minecraft);
@@ -27,6 +32,18 @@ protected:
void createKey(OptionId optId, Minecraft* minecraft); void createKey(OptionId optId, Minecraft* minecraft);
std::string label; std::string label;
int contentHeight;
float scrollOffsetY;
float maxScrollOffsetY;
bool trackingScrollGesture;
bool scrollingGesture;
bool touchDispatched;
int dragStartX;
int dragStartY;
int lastDragY;
int touchStartX;
int touchStartY;
static const int ScrollStartThreshold = 5;
}; };
#endif /*NET_MINECRAFT_CLIENT_GUI_COMPONENTS__OptionsGroup_H__*/ #endif /*NET_MINECRAFT_CLIENT_GUI_COMPONENTS__OptionsGroup_H__*/

View File

@@ -27,11 +27,12 @@ void OptionsItem::render( Minecraft* minecraft, int xm, int ym ) {
std::string scaleText; std::string scaleText;
switch (value) { switch (value) {
case 0: scaleText = I18n::get("options.guiScale.auto"); break; case 0: scaleText = I18n::get("options.guiScale.auto"); break;
case 1: scaleText = I18n::get("options.guiScale.small"); break; case 1: scaleText = I18n::get("options.guiScale.tiny"); break;
case 2: scaleText = I18n::get("options.guiScale.medium"); break; case 2: scaleText = I18n::get("options.guiScale.small"); break;
case 3: scaleText = I18n::get("options.guiScale.large"); break; case 3: scaleText = I18n::get("options.guiScale.medium"); break;
case 4: scaleText = I18n::get("options.guiScale.larger"); break; case 4: scaleText = I18n::get("options.guiScale.large"); break;
case 5: scaleText = I18n::get("options.guiScale.largest"); break; case 5: scaleText = I18n::get("options.guiScale.larger"); break;
case 6: scaleText = I18n::get("options.guiScale.largest"); break;
default: scaleText = I18n::get("options.guiScale.auto"); break; default: scaleText = I18n::get("options.guiScale.auto"); break;
} }
text += ": " + scaleText; text += ": " + scaleText;

View File

@@ -8,7 +8,6 @@
#include "../../../network/ServerSideNetworkHandler.h" #include "../../../network/ServerSideNetworkHandler.h"
#include "../../../network/packet/ChatPacket.h" #include "../../../network/packet/ChatPacket.h"
#include "../../../platform/log.h" #include "../../../platform/log.h"
#include "util/StringUtils.h"
#include <sstream> #include <sstream>
#include <cstdlib> #include <cstdlib>
@@ -55,37 +54,141 @@ void ConsoleScreen::charPressed(char inputChar)
_input += inputChar; _input += inputChar;
} }
// ---------------------------------------------------------------------------
// execute: run _input as a command, print result, close screen
// ---------------------------------------------------------------------------
void ConsoleScreen::execute() void ConsoleScreen::execute()
{ {
if (!minecraft->level) return;
if (_input.empty()) { if (_input.empty()) {
return minecraft->setScreen(NULL); minecraft->setScreen(NULL);
return;
} }
// if (_input[0] == '/') { if (_input[0] == '/') {
// // Command // Command
// _input = Util::stringTrim(_input.substr(1)); std::string result = processCommand(_input);
if (!result.empty())
// std::istringstream iss(minecraft->commandManager().execute(*minecraft, *minecraft->player, _input)); minecraft->gui.addMessage(result);
// for (std::string line; std::getline(iss, line); ) { } else {
// minecraft->gui.addMessage(line); // Chat message: <name> message
// } std::string msg = std::string("<") + minecraft->player->name + "> " + _input;
// } else {
// @ai @rewrite
if (minecraft->netCallback && minecraft->raknetInstance->isServer()) { if (minecraft->netCallback && minecraft->raknetInstance->isServer()) {
static_cast<ServerSideNetworkHandler*>(minecraft->netCallback)->displayGameMessage(_input); // Hosting a LAN game: displayGameMessage shows locally + broadcasts MessagePacket to clients
static_cast<ServerSideNetworkHandler*>(minecraft->netCallback)->displayGameMessage(msg);
} else if (minecraft->netCallback) { } else if (minecraft->netCallback) {
ChatPacket chatPkt(_input); // Connected client: send ChatPacket to server; server echoes it back as MessagePacket
ChatPacket chatPkt(msg);
minecraft->raknetInstance->send(chatPkt); minecraft->raknetInstance->send(chatPkt);
} else { } else {
minecraft->gui.addMessage("<" + minecraft->player->name + "> " + _input); // Singleplayer: show locally only
minecraft->gui.addMessage(msg);
}
} }
// }
minecraft->setScreen(NULL); minecraft->setScreen(NULL);
} }
// ---------------------------------------------------------------------------
// processCommand
// ---------------------------------------------------------------------------
static std::string trim(const std::string& s) {
size_t a = s.find_first_not_of(" \t");
if (a == std::string::npos) return "";
size_t b = s.find_last_not_of(" \t");
return s.substr(a, b - a + 1);
}
std::string ConsoleScreen::processCommand(const std::string& raw)
{
// strip leading '/'
std::string line = raw;
if (!line.empty() && line[0] == '/') line = line.substr(1);
line = trim(line);
// tokenise
std::vector<std::string> args;
{
std::istringstream ss(line);
std::string tok;
while (ss >> tok) args.push_back(tok);
}
if (args.empty()) return "";
Level* level = minecraft->level;
if (!level) return "No level loaded.";
// -----------------------------------------------------------------------
// /time ...
// -----------------------------------------------------------------------
if (args[0] == "time") {
if (args.size() < 2)
return "Usage: /time <add|set|query> ...";
const std::string& sub = args[1];
// -- time add <value> -----------------------------------------------
if (sub == "add") {
if (args.size() < 3) return "Usage: /time add <value>";
long delta = std::atol(args[2].c_str());
long newTime = level->getTime() + delta;
level->setTime(newTime);
std::ostringstream out;
out << "Set the time to " << (newTime % Level::TICKS_PER_DAY);
return out.str();
}
// -- time set <value|day|night|noon|midnight> -----------------------
if (sub == "set") {
if (args.size() < 3) return "Usage: /time set <value|day|night|noon|midnight>";
const std::string& val = args[2];
long t = -1;
if (val == "day") t = 1000;
else if (val == "noon") t = 6000;
else if (val == "night") t = 13000;
else if (val == "midnight") t = 18000;
else {
// numeric — accept positive integers only
bool numeric = true;
for (char c : val)
if (!std::isdigit((unsigned char)c)) { numeric = false; break; }
if (!numeric) return std::string("Unknown value: ") + val;
t = std::atol(val.c_str());
}
// Preserve the total day count so only the time-of-day changes
long dayCount = level->getTime() / Level::TICKS_PER_DAY;
long newTime = dayCount * Level::TICKS_PER_DAY + (t % Level::TICKS_PER_DAY);
level->setTime(newTime);
std::ostringstream out;
out << "Set the time to " << t;
return out.str();
}
// -- time query <daytime|gametime|day> ------------------------------
if (sub == "query") {
if (args.size() < 3) return "Usage: /time query <daytime|gametime|day>";
const std::string& what = args[2];
long total = level->getTime();
long daytime = total % Level::TICKS_PER_DAY;
long day = total / Level::TICKS_PER_DAY;
std::ostringstream out;
if (what == "daytime") { out << "The time of day is " << daytime; }
else if (what == "gametime") { out << "The game time is " << total; }
else if (what == "day") { out << "The day is " << day; }
else return std::string("Unknown query: ") + what;
return out.str();
}
return "Unknown sub-command. Usage: /time <add|set|query> ...";
}
return std::string("Unknown command: /") + args[0];
}
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// render // render
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------

View File

@@ -25,6 +25,7 @@ public:
private: private:
void execute(); void execute();
std::string processCommand(const std::string& cmd);
std::string _input; std::string _input;
int _cursorBlink; // tick counter for cursor blink int _cursorBlink; // tick counter for cursor blink

View File

@@ -121,6 +121,7 @@ void OptionsScreen::setupPositions() {
(*it)->x = categoryButtons[0]->width; (*it)->x = categoryButtons[0]->width;
(*it)->y = bHeader->height; (*it)->y = bHeader->height;
(*it)->width = width - categoryButtons[0]->width; (*it)->width = width - categoryButtons[0]->width;
(*it)->height = height - bHeader->height;
(*it)->setupPositions(); (*it)->setupPositions();
} }
@@ -147,7 +148,7 @@ void OptionsScreen::removed() {
void OptionsScreen::buttonClicked(Button* button) { void OptionsScreen::buttonClicked(Button* button) {
if (button == btnClose) { if (button == btnClose) {
minecraft->options.save(); minecraft->reloadOptions();
if (minecraft->screen != NULL) { if (minecraft->screen != NULL) {
minecraft->setScreen(NULL); minecraft->setScreen(NULL);
} else { } else {
@@ -194,11 +195,11 @@ void OptionsScreen::generateOptionScreens() {
.addOptionItem(OPTIONS_SENSITIVITY, minecraft); .addOptionItem(OPTIONS_SENSITIVITY, minecraft);
// Game Pane // Game Pane
optionPanes[1]->addOptionItem(OPTIONS_DIFFICULTY, minecraft) optionPanes[1]->addOptionItem(OPTIONS_GUI_SCALE, minecraft)
.addOptionItem(OPTIONS_DIFFICULTY, minecraft)
.addOptionItem(OPTIONS_SERVER_VISIBLE, minecraft) .addOptionItem(OPTIONS_SERVER_VISIBLE, minecraft)
.addOptionItem(OPTIONS_THIRD_PERSON_VIEW, minecraft) .addOptionItem(OPTIONS_THIRD_PERSON_VIEW, minecraft)
.addOptionItem(OPTIONS_WINDOW_SCALE, minecraft) .addOptionItem(OPTIONS_WINDOW_SCALE, minecraft)
.addOptionItem(OPTIONS_GUI_SCALE, minecraft)
.addOptionItem(OPTIONS_SENSITIVITY, minecraft) .addOptionItem(OPTIONS_SENSITIVITY, minecraft)
.addOptionItem(OPTIONS_MUSIC_VOLUME, minecraft) .addOptionItem(OPTIONS_MUSIC_VOLUME, minecraft)
.addOptionItem(OPTIONS_SOUND_VOLUME, minecraft) .addOptionItem(OPTIONS_SOUND_VOLUME, minecraft)
@@ -233,7 +234,8 @@ void OptionsScreen::generateOptionScreens() {
.addOptionItem(OPTIONS_BEAUTIFUL_SKY, minecraft) .addOptionItem(OPTIONS_BEAUTIFUL_SKY, minecraft)
.addOptionItem(OPTIONS_VIGNETTE, minecraft); .addOptionItem(OPTIONS_VIGNETTE, minecraft);
optionPanes[4]->addOptionItem(OPTIONS_ALLOW_SPRINT, minecraft) optionPanes[4]->addOptionItem(OPTIONS_TOUCH_OVERRIDE, minecraft)
.addOptionItem(OPTIONS_ALLOW_SPRINT, minecraft)
.addOptionItem(OPTIONS_BAR_ON_TOP, minecraft) .addOptionItem(OPTIONS_BAR_ON_TOP, minecraft)
.addOptionItem(OPTIONS_MENU_STYLE, minecraft) .addOptionItem(OPTIONS_MENU_STYLE, minecraft)
.addOptionItem(OPTIONS_RPI_CURSOR, minecraft) .addOptionItem(OPTIONS_RPI_CURSOR, minecraft)
@@ -261,11 +263,17 @@ void OptionsScreen::mouseReleased(int x, int y, int buttonNum) {
super::mouseReleased(x, y, buttonNum); super::mouseReleased(x, y, buttonNum);
} }
void OptionsScreen::mouseWheel(int dx, int dy, int xm, int ym) {
if (currentOptionsGroup != NULL && currentOptionsGroup->pointInside(xm, ym) && dy != 0) {
currentOptionsGroup->scrollByPixels((float)dy * 18.0f);
}
}
void OptionsScreen::keyPressed(int eventKey) { void OptionsScreen::keyPressed(int eventKey) {
if (currentOptionsGroup != NULL) if (currentOptionsGroup != NULL)
currentOptionsGroup->keyPressed(minecraft, eventKey); currentOptionsGroup->keyPressed(minecraft, eventKey);
if (eventKey == Keyboard::KEY_ESCAPE) if (eventKey == Keyboard::KEY_ESCAPE)
minecraft->options.save(); minecraft->reloadOptions();
super::keyPressed(eventKey); super::keyPressed(eventKey);
} }

View File

@@ -27,6 +27,7 @@ public:
virtual void mouseClicked(int x, int y, int buttonNum); virtual void mouseClicked(int x, int y, int buttonNum);
virtual void mouseReleased(int x, int y, int buttonNum); virtual void mouseReleased(int x, int y, int buttonNum);
virtual void mouseWheel(int dx, int dy, int xm, int ym);
virtual void keyPressed(int eventKey); virtual void keyPressed(int eventKey);
virtual void charPressed(char inputChar); virtual void charPressed(char inputChar);

View File

@@ -118,22 +118,15 @@ void SimpleChooseLevelScreen::setupPositions()
bGamemode->x = centerX - totalButtonWidth / 2; bGamemode->x = centerX - totalButtonWidth / 2;
bCheats->x = bGamemode->x + buttonWidth + buttonSpacing; bCheats->x = bGamemode->x + buttonWidth + buttonSpacing;
// compute vertical centre for buttons in remaining space // position Survival/Cheats buttons below the seed field
{ int buttonY = tSeed.y + tSeed.height + 20;
int bottomPad = 20; bGamemode->y = buttonY;
int availTop = buttonHeight + 20 + 30 + 10; // just below seed bCheats->y = buttonY;
int availBottom = height - bottomPad - bCreate->height - 10; // leave some gap before create
int availHeight = availBottom - availTop;
if (availHeight < 0) availHeight = 0;
int y = availTop + (availHeight - bGamemode->height) / 2;
bGamemode->y = y;
bCheats->y = y;
}
// position Create button just below with a small gap
bCreate->width = 100; bCreate->width = 100;
bCreate->x = centerX - bCreate->width / 2; bCreate->x = centerX - bCreate->width / 2;
int bottomPadding = 20; bCreate->y = buttonY + bGamemode->height + 40;
bCreate->y = height - bottomPadding - bCreate->height;
} }
void SimpleChooseLevelScreen::tick() void SimpleChooseLevelScreen::tick()

View File

@@ -16,12 +16,7 @@
#include "../../../../world/level/Level.h" #include "../../../../world/level/Level.h"
#include "../../../../world/item/DyePowderItem.h" #include "../../../../world/item/DyePowderItem.h"
#include "../../../../world/item/crafting/Recipe.h" #include "../../../../world/item/crafting/Recipe.h"
#include "network/RakNetInstance.h"
#include "network/packet/WantCreatePacket.h"
#include "platform/input/Keyboard.h" #include "platform/input/Keyboard.h"
#include <cstdint>
#include <iostream>
#include <string>
static NinePatchLayer* guiPaneFrame = NULL; static NinePatchLayer* guiPaneFrame = NULL;
@@ -198,26 +193,6 @@ void PaneCraftingScreen::setupPositions() {
} }
void PaneCraftingScreen::tick() { void PaneCraftingScreen::tick() {
if (minecraft->isOnline()) {
// TODO: Make better algorithm
static std::map<uint8_t, uint16_t> oldMap = {};
std::map<uint8_t, uint16_t> newMap = {};
for (int i = Inventory::MAX_SELECTION_SIZE; i < minecraft->player->inventory->getContainerSize(); ++i) {
auto itm = minecraft->player->inventory->getItem(i);
if (itm != NULL) {
newMap[itm->id] += itm->count;
}
}
if (oldMap != newMap) {
oldMap = newMap;
newMap = {};
recheckRecipes();
}
}
if (pane) pane->tick(); if (pane) pane->tick();
} }
@@ -464,10 +439,6 @@ void PaneCraftingScreen::craftSelectedItem()
ItemInstance resultItem = currentItem->item; ItemInstance resultItem = currentItem->item;
if (minecraft->player) { if (minecraft->player) {
if (minecraft->isOnline()) {
WantCreatePacket packet(minecraft->player->entityId, resultItem.count, resultItem.getAuxValue(), resultItem.id);
minecraft->raknetInstance->send(packet);
}
// Remove all items required for the recipe and ... // Remove all items required for the recipe and ...
for (unsigned int i = 0; i < currentItem->neededItems.size(); ++i) { for (unsigned int i = 0; i < currentItem->neededItems.size(); ++i) {
CItem::ReqItem& req = currentItem->neededItems[i]; CItem::ReqItem& req = currentItem->neededItems[i];

View File

@@ -40,9 +40,10 @@ HumanoidModel::HumanoidModel( float g /*= 0*/, float yOffset /*= 0*/, int texW /
head.addBox(-4, -8, -4, 8, 8, 8, g); // Head head.addBox(-4, -8, -4, 8, 8, 8, g); // Head
head.setPos(0, 0 + yOffset, 0); head.setPos(0, 0 + yOffset, 0);
if (modernSkin) {
hair.addBox(-4, -8, -4, 8, 8, 8, g + 0.5f); // Outer head layer (hat) hair.addBox(-4, -8, -4, 8, 8, 8, g + 0.5f); // Outer head layer (hat)
hair.setPos(0, 0 + yOffset, 0); hair.setPos(0, 0 + yOffset, 0);
}
body.addBox(-4, 0, -2, 8, 12, 4, g); // Body body.addBox(-4, 0, -2, 8, 12, 4, g); // Body
body.setPos(0, 0 + yOffset, 0); body.setPos(0, 0 + yOffset, 0);
@@ -98,17 +99,17 @@ void HumanoidModel::render(Entity* e, float time, float r, float bob, float yRot
setupAnim(time, r, bob, yRot, xRot, scale); setupAnim(time, r, bob, yRot, xRot, scale);
// Sync overlay with head rotation/position // Sync overlay with head rotation/position
if (texWidth == 64 && texHeight == 64) {
hair.xRot = head.xRot; hair.xRot = head.xRot;
hair.yRot = head.yRot; hair.yRot = head.yRot;
hair.zRot = head.zRot; hair.zRot = head.zRot;
hair.y = head.y; hair.y = head.y;
}
head.render(scale); head.render(scale);
if (texWidth == 64 && texHeight == 64) {
hair.render(scale); hair.render(scale);
}
body.render(scale); body.render(scale);
arm0.render(scale); arm0.render(scale);
arm1.render(scale); arm1.render(scale);
@@ -122,12 +123,12 @@ void HumanoidModel::render( HumanoidModel* model, float scale )
head.yRot = model->head.yRot; head.yRot = model->head.yRot;
head.y = model->head.y; head.y = model->head.y;
head.xRot = model->head.xRot; head.xRot = model->head.xRot;
if (texWidth == 64 && texHeight == 64) {
hair.yRot = head.yRot; hair.yRot = head.yRot;
hair.xRot = head.xRot; hair.xRot = head.xRot;
hair.zRot = head.zRot; hair.zRot = head.zRot;
hair.y = head.y; hair.y = head.y;
}
arm0.xRot = model->arm0.xRot; arm0.xRot = model->arm0.xRot;
arm0.zRot = model->arm0.zRot; arm0.zRot = model->arm0.zRot;
@@ -272,7 +273,7 @@ void HumanoidModel::onGraphicsReset()
arm1.onGraphicsReset(); arm1.onGraphicsReset();
leg0.onGraphicsReset(); leg0.onGraphicsReset();
leg1.onGraphicsReset(); leg1.onGraphicsReset();
hair.onGraphicsReset(); //hair.onGraphicsReset();
} }
//void renderHair(float scale) { //void renderHair(float scale) {

View File

@@ -355,11 +355,7 @@ LocalPlayer::LocalPlayer(Minecraft* minecraft, Level* level, const std::string&
armorTypeHash(0), armorTypeHash(0),
sprinting(false), sprinting(false),
sprintDoubleTapTimer(0), sprintDoubleTapTimer(0),
prevForwardHeld(false), prevForwardHeld(false)
xBob(0.0f),
yBob(0.0f),
xBobO(0.0f),
yBobO(0.0f)
{ {
this->dimension = dimension; this->dimension = dimension;
_init(); _init();
@@ -460,7 +456,7 @@ void LocalPlayer::tick() {
{ {
sentInventoryItemId = newItemId; sentInventoryItemId = newItemId;
sentInventoryItemData = newItemData; sentInventoryItemData = newItemData;
PlayerEquipmentPacket packet(entityId, newItemId, newItemData, inventory->selected, inventory->getSlot(newItemId, newItemData)); PlayerEquipmentPacket packet(entityId, newItemId, newItemData);
minecraft->raknetInstance->send(packet); minecraft->raknetInstance->send(packet);
} }
} }
@@ -554,10 +550,6 @@ void LocalPlayer::aiStep() {
//if (onGround && abilities.flying) //if (onGround && abilities.flying)
// abilities.flying = false; // abilities.flying = false;
yBobO = yBob;
xBobO = xBob;
xBob += (xRot - xBob) * 0.5;
yBob += (yRot - yBob) * 0.5;
if (interpolateOnly()) if (interpolateOnly())
updateAi(); updateAi();

View File

@@ -22,10 +22,6 @@ public:
virtual void reset(); virtual void reset();
void tick(); void tick();
float yBob, xBob; // shredder added from b1.8/4j for the hand swaying animation
float yBobO, xBobO; // shredder added from b1.8/4j for the hand swaying animation
void move(float xa, float ya, float za); void move(float xa, float ya, float za);
void aiStep(); void aiStep();

View File

@@ -4,6 +4,7 @@
#include "../../../gui/Gui.h" #include "../../../gui/Gui.h"
#include "../../../renderer/Tesselator.h" #include "../../../renderer/Tesselator.h"
#include "../../../../world/entity/player/Player.h" #include "../../../../world/entity/player/Player.h"
#include "../../../../util/Mth.h"
#include "../../../Minecraft.h" #include "../../../Minecraft.h"
#include "../../../../platform/log.h" #include "../../../../platform/log.h"
@@ -125,48 +126,80 @@ void TouchscreenInput_TestFps::onConfigChanged(const Config& c) {
*/ */
// Code for "D-pad with jump in center" // Code for "D-pad with jump in center"
float Bw = w * 0.11f;//0.08f; // Calculate button size so the full 3x3 grid fits on screen with margins
float Bh = Bw;//0.15f; const float margin = 12.0f;
float availW = w - margin * 2; // horizontal space available
float availH = h - margin * 2; // vertical space available
// Each button: 3 wide, 3 tall
float Bw = availW / 3.0f;
float Bh = availH / 3.0f;
// Use the smaller of the two to maintain square buttons
float btnSize = Mth::Min(Bw, Bh);
// If too large (like playing on Tablet) // Scale down to 65% of max available for a more comfortable, non-obtrusive size
btnSize *= 0.65f;
// Clamp to physical millimeters for consistency across DPIs
PixelCalc& pc = _minecraft->pixelCalc; PixelCalc& pc = _minecraft->pixelCalc;
if (pc.pixelsToMillimeters(Bw) > 200) { //14 float minBtnPx = pc.millimetersToPixels(35); // minimum touch target
Bw = Bh = pc.millimetersToPixels(200); //14 float maxBtnPx = pc.millimetersToPixels(90); // maximum
} if (btnSize < minBtnPx) btnSize = minBtnPx;
if (btnSize > maxBtnPx) btnSize = maxBtnPx;
float Bw2 = btnSize;
float Bh2 = btnSize;
// temp data // temp data
float xx; float xx;
float yy; float yy;
const float BaseY = -8 + h - 3.0f * Bh; // Position from top-left (or top-right for left-handed)
const float BaseX = _options->getBooleanValue(OPTIONS_IS_LEFT_HANDED)? -8 + w - 3 * Bw float dpadTotalW = 3.0f * Bw2;
: 8 + 0; float dpadTotalH = 3.0f * Bh2;
// Place at top of screen instead of bottom
float BaseY = margin;
if (BaseY + dpadTotalH > h - margin) BaseY = h - dpadTotalH - margin;
float BaseX = _options->getBooleanValue(OPTIONS_IS_LEFT_HANDED) ? w - dpadTotalW - margin : margin;
if (BaseX < margin) BaseX = margin;
if (BaseX + dpadTotalW > w - margin) BaseX = w - dpadTotalW - margin;
// Setup the bounding rectangle // Setup the bounding rectangle
_boundingRectangle = RectangleArea(BaseX, BaseY, BaseX + 3 * Bw, BaseY + 3 * Bh); _boundingRectangle = RectangleArea(BaseX, BaseY, BaseX + dpadTotalW, BaseY + dpadTotalH);
xx = BaseX + Bw; yy = BaseY; xx = BaseX + Bw2; yy = BaseY;
_model.addArea(AREA_DPAD_N, aUp = new RectangleArea(xx, yy, xx+Bw, yy+Bh)); _model.addArea(AREA_DPAD_N, aUp = new RectangleArea(xx, yy, xx+Bw2, yy+Bh2));
xx = BaseX; xx = BaseX;
aUpLeft = new RectangleArea(xx, yy, xx+Bw, yy+Bh); aUpLeft = new RectangleArea(xx, yy, xx+Bw2, yy+Bh2);
xx = BaseX + 2 * Bw; xx = BaseX + 2 * Bw2;
aUpRight = new RectangleArea(xx, yy, xx+Bw, yy+Bh); aUpRight = new RectangleArea(xx, yy, xx+Bw2, yy+Bh2);
xx = BaseX + Bw; yy = BaseY + Bh; xx = BaseX + Bw2; yy = BaseY + Bh2;
_model.addArea(AREA_DPAD_C, aJump = new RectangleArea(xx, yy, xx+Bw, yy+Bh)); _model.addArea(AREA_DPAD_C, aJump = new RectangleArea(xx, yy, xx+Bw2, yy+Bh2));
xx = BaseX + Bw; yy = BaseY + 2 * Bh; xx = BaseX + Bw2; yy = BaseY + 2 * Bh2;
_model.addArea(AREA_DPAD_S, aDown = new RectangleArea(xx, yy, xx+Bw, yy+Bh)); _model.addArea(AREA_DPAD_S, aDown = new RectangleArea(xx, yy, xx+Bw2, yy+Bh2));
xx = BaseX; yy = BaseY + Bh; xx = BaseX; yy = BaseY + Bh2;
_model.addArea(AREA_DPAD_W, aLeft = new RectangleArea(xx, yy, xx+Bw, yy+Bh)); _model.addArea(AREA_DPAD_W, aLeft = new RectangleArea(xx, yy, xx+Bw2, yy+Bh2));
xx = BaseX + 2 * Bw; yy = BaseY + Bh; xx = BaseX + 2 * Bw2; yy = BaseY + Bh2;
_model.addArea(AREA_DPAD_E, aRight = new RectangleArea(xx, yy, xx+Bw, yy+Bh)); _model.addArea(AREA_DPAD_E, aRight = new RectangleArea(xx, yy, xx+Bw2, yy+Bh2));
float maxPixels = _minecraft->pixelCalc.millimetersToPixels(10); // Pause and chat buttons - sized relative to D-pad buttons, with bounds checking
// float btnSize = Mth::Min(18 * Gui::GuiScale, maxPixels); float actionBtnSize = Bw2 * 0.7f;
float btnSize = pc.millimetersToPixels(18 * Gui::GuiScale); float actionBtnMargin = 8.0f;
_model.addArea(AREA_PAUSE, aPause = new RectangleArea(w - 4 - btnSize, 4, w - 4, 4 + btnSize)); // Clamp action button size
_model.addArea(AREA_CHAT, aChat = new RectangleArea(w - 8 - btnSize * 2, 4, w - 8 - btnSize, 4 + btnSize)); if (actionBtnSize < pc.millimetersToPixels(30)) actionBtnSize = pc.millimetersToPixels(30);
if (actionBtnSize > pc.millimetersToPixels(120)) actionBtnSize = pc.millimetersToPixels(120);
_model.addArea(AREA_PAUSE, aPause = new RectangleArea(
w - actionBtnMargin - actionBtnSize, actionBtnMargin,
w - actionBtnMargin, actionBtnMargin + actionBtnSize));
_model.addArea(AREA_CHAT, aChat = new RectangleArea(
w - actionBtnMargin * 2 - actionBtnSize * 2, actionBtnMargin,
w - actionBtnMargin * 2 - actionBtnSize, actionBtnMargin + actionBtnSize));
//rebuild(); //rebuild();
} }

View File

@@ -347,7 +347,6 @@ void GameRenderer::renderLevel(float a) {
Lighting::turnOff(); Lighting::turnOff();
glDisable2(GL_BLEND); glDisable2(GL_BLEND);
glBlendFunc2(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBlendFunc2(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
Lighting::turnOff();
setupFog(0); setupFog(0);
glEnable2(GL_BLEND); glEnable2(GL_BLEND);
glDisable2(GL_CULL_FACE); glDisable2(GL_CULL_FACE);

View File

@@ -280,9 +280,6 @@ void ItemInHandRenderer::render( float a )
float h = oHeight + (height - oHeight) * a; float h = oHeight + (height - oHeight) * a;
Player* player = mc->player; Player* player = mc->player;
// if (selectedTile==NULL) return; // if (selectedTile==NULL) return;
LocalPlayer* localPlayer = (LocalPlayer*)(player);
float xr = player->xRotO + (player->xRot - player->xRotO) * a; // shredder added for hand swaying
glPushMatrix2(); glPushMatrix2();
glRotatef2(player->xRotO + (player->xRot - player->xRotO) * a, 1, 0, 0); glRotatef2(player->xRotO + (player->xRot - player->xRotO) * a, 1, 0, 0);
@@ -291,16 +288,6 @@ void ItemInHandRenderer::render( float a )
Lighting::turnOn(mc); Lighting::turnOn(mc);
glPopMatrix2(); glPopMatrix2();
if (localPlayer) // shredder added, basically does the hand swaying animation from b1.8
{
float xrr = localPlayer->xBobO + (localPlayer->xBob - localPlayer->xBobO) * a;
float yrr = localPlayer->yBobO + (localPlayer->yBob - localPlayer->yBobO) * a;
// 4J - was using player->xRot and yRot directly here rather than interpolating between old & current with a
float yr = player->yRotO + (player->yRot - player->yRotO) * a;
glRotatef((xr - xrr) * 0.1f, 1, 0, 0);
glRotatef((yr - yrr) * 0.1f, 0, 1, 0);
}
float br = mc->level->getBrightness(Mth::floor(player->x), Mth::floor(player->y), Mth::floor(player->z)); float br = mc->level->getBrightness(Mth::floor(player->x), Mth::floor(player->y), Mth::floor(player->z));
ItemInstance* item;// = selectedItem; ItemInstance* item;// = selectedItem;

View File

@@ -69,7 +69,7 @@ LevelRenderer::LevelRenderer( Minecraft* mc)
destroyProgress(0) destroyProgress(0)
{ {
#ifdef OPENGL_ES #ifdef OPENGL_ES
int maxChunksWidth = 2 * LevelConstants::LEVEL_WIDTH / CHUNK_SIZE + 1; int maxChunksWidth = 2 * LEVEL_WIDTH / CHUNK_SIZE + 1;
numListsOrBuffers = maxChunksWidth * maxChunksWidth * (128/CHUNK_SIZE) * 3; numListsOrBuffers = maxChunksWidth * maxChunksWidth * (128/CHUNK_SIZE) * 3;
chunkBuffers = new GLuint[numListsOrBuffers]; chunkBuffers = new GLuint[numListsOrBuffers];
glGenBuffers2(numListsOrBuffers, chunkBuffers); glGenBuffers2(numListsOrBuffers, chunkBuffers);
@@ -1452,13 +1452,13 @@ void LevelRenderer::playSound(const std::string& name, float x, float y, float z
float dd = 16; float dd = 16;
if (volume > 1) dd *= volume; if (volume > 1) dd *= volume;
if (mc->cameraTargetPlayer != NULL && mc->cameraTargetPlayer->distanceToSqr(x, y, z) < dd * dd) { if (mc->cameraTargetPlayer->distanceToSqr(x, y, z) < dd * dd) {
mc->soundEngine->play(name, x, y, z, volume, pitch); mc->soundEngine->play(name, x, y, z, volume, pitch);
} }
} }
void LevelRenderer::addParticle(const std::string& name, float x, float y, float z, float xa, float ya, float za, int data) { void LevelRenderer::addParticle(const std::string& name, float x, float y, float z, float xa, float ya, float za, int data) {
if (mc->cameraTargetPlayer != NULL) {
float xd = mc->cameraTargetPlayer->x - x; float xd = mc->cameraTargetPlayer->x - x;
float yd = mc->cameraTargetPlayer->y - y; float yd = mc->cameraTargetPlayer->y - y;
float zd = mc->cameraTargetPlayer->z - z; float zd = mc->cameraTargetPlayer->z - z;
@@ -1499,7 +1499,6 @@ void LevelRenderer::addParticle(const std::string& name, float x, float y, float
//sw.stop(); //sw.stop();
//sw.printEvery(50, "add-particle-string"); //sw.printEvery(50, "add-particle-string");
}
} }
/* /*

View File

@@ -133,8 +133,6 @@ void EntityRenderer::postRender(Entity* entity, float x, float y, float z, float
} }
if (entity->isOnFire()) renderFlame(entity, x, y, z, a); if (entity->isOnFire()) renderFlame(entity, x, y, z, a);
} }
// duplicate renderflame below is the pre b1.6.6 way flame rendered on player and mobs, probs gonna make it an option. - shredder
/*
void EntityRenderer::renderFlame(Entity* e, float x, float y, float z, float a) { void EntityRenderer::renderFlame(Entity* e, float x, float y, float z, float a) {
glDisable(GL_LIGHTING); glDisable(GL_LIGHTING);
int tex = ((Tile*)Tile::fire)->tex; int tex = ((Tile*)Tile::fire)->tex;
@@ -180,75 +178,6 @@ void EntityRenderer::renderFlame(Entity* e, float x, float y, float z, float a)
glPopMatrix2(); glPopMatrix2();
glEnable2(GL_LIGHTING); glEnable2(GL_LIGHTING);
} }
*/
// new renderflame ported from b1.6.6, fixes player height offset and also uses the newer style - shredder
void EntityRenderer::renderFlame(Entity* e, float x, float y, float z, float a) {
glDisable(GL_LIGHTING);
int tex = ((Tile*)Tile::fire)->tex;
int xt = (tex & 0xf) << 4;
int yt = tex & 0xf0;
float u0 = (xt) / 256.0f;
float u1 = (xt + 15.99f) / 256.0f;
float v0 = (yt) / 256.0f;
float v1 = (yt + 15.99f) / 256.0f;
glPushMatrix2();
glTranslatef2((float) x, (float) y, (float) z);
float s = e->bbWidth * 1.4f;
glScalef2(s, s, s);
bindTexture("terrain.png");
Tesselator& t = Tesselator::instance;
float r = 0.5f;
float xo = 0.0f;
float h = e->bbHeight / s;
float yo = (float)(e->y - e->bb.y0) / s;
glRotatef2(-entityRenderDispatcher->playerRotY, 0, 1, 0);
glTranslatef2(0, 0, -0.3f + ((int) h) * 0.02f);
glColor4f2(1, 1, 1, 1);
float zo = 0.0f;
int cycle_counter = 0;
t.begin();
while (h > 0.0f) {
float current_u0 = u0;
float current_u1 = u1;
float current_v0 = v0;
float current_v1 = v1;
if (cycle_counter % 2 != 0) {
current_v0 = (yt + 16) / 256.0f;
current_v1 = (yt + 16 + 15.99f) / 256.0f;
}
if ((cycle_counter / 2) % 2 == 0) {
float tmp = current_u1;
current_u1 = current_u0;
current_u0 = tmp;
}
t.vertexUV(r - xo, 0.0f - yo, zo, current_u1, current_v1);
t.vertexUV(-r - xo, 0.0f - yo, zo, current_u0, current_v1);
t.vertexUV(-r - xo, 1.4f - yo, zo, current_u0, current_v0);
t.vertexUV(r - xo, 1.4f - yo, zo, current_u1, current_v0);
h -= 0.45f;
yo -= 0.45f;
r *= 0.9f;
zo += 0.03f;
cycle_counter++;
}
t.draw();
glPopMatrix2();
glEnable2(GL_LIGHTING);
}
void EntityRenderer::renderShadow(Entity* e, float x, float y, float z, float pow, float a) { // void EntityRenderer::renderShadow(Entity* e, float x, float y, float z, float pow, float a) { //
glEnable2(GL_BLEND); glEnable2(GL_BLEND);
@@ -300,8 +229,6 @@ void EntityRenderer::renderShadow(Entity* e, float x, float y, float z, float po
glColor4f2(1, 1, 1, 1); glColor4f2(1, 1, 1, 1);
glDisable2(GL_BLEND); glDisable2(GL_BLEND);
glDepthMask(true); glDepthMask(true);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
} }
Level* EntityRenderer::getLevel() { Level* EntityRenderer::getLevel() {

View File

@@ -218,8 +218,6 @@ void MobRenderer::renderNameTag(Mob* mob, const std::string& name, float x, floa
glScalef2(-s, -s, s); glScalef2(-s, -s, s);
glDisable(GL_LIGHTING);
glDepthMask(false); glDepthMask(false);
glDisable2(GL_DEPTH_TEST); glDisable2(GL_DEPTH_TEST);
glEnable2(GL_BLEND); glEnable2(GL_BLEND);
@@ -243,7 +241,6 @@ void MobRenderer::renderNameTag(Mob* mob, const std::string& name, float x, floa
glDepthMask(true); glDepthMask(true);
font->draw(name, (float) fnameWidth, 0, 0xffffffff); font->draw(name, (float) fnameWidth, 0, 0xffffffff);
glEnable(GL_LIGHTING);
glDisable2(GL_BLEND); glDisable2(GL_BLEND);
glColor4f2(1, 1, 1, 1); glColor4f2(1, 1, 1, 1);
glPopMatrix2(); glPopMatrix2();

View File

@@ -77,10 +77,10 @@ void PlayerRenderer::render(Entity* mob_, float x, float y, float z, float rot,
model = desired; model = desired;
humanoidModel = desired; humanoidModel = desired;
} }
/* LOGI("[PlayerRenderer] %s: skin=%s, modelTex=%dx%d, desired=%s\n", // LOGI("[PlayerRenderer] %s: skin=%s, modelTex=%dx%d, desired=%s\n", // don't log it always, only for debug - shredder
((Player*)mob)->name.c_str(), mob->getTexture().c_str(), // ((Player*)mob)->name.c_str(), mob->getTexture().c_str(),
humanoidModel->texWidth, humanoidModel->texHeight, // humanoidModel->texWidth, humanoidModel->texHeight,
(desired == playerModel64 ? "64" : "32")); */ // (desired == playerModel64 ? "64" : "32"));
HumanoidMobRenderer::render(mob_, x, y, z, rot, a); HumanoidMobRenderer::render(mob_, x, y, z, rot, a);
} }

View File

@@ -1,10 +0,0 @@
#include "Command.hpp"
#include "world/level/Level.h"
#include <client/Minecraft.h>
bool Command::isPlayerOp(Minecraft& mc, Player& player) {
std::string nicknameLower = player.name;
std::transform(nicknameLower.begin(), nicknameLower.end(), nicknameLower.begin(), ::tolower);
return mc.level->ops.find(nicknameLower) != mc.level->ops.end();
}

View File

@@ -1,28 +0,0 @@
#pragma once
#include <string>
#include <vector>
enum CommandFlags {
COMMAND_FLAG_SINGLEPLAYER_ONLY = (1 << 1),
COMMAND_FLAG_NO_ARGS = (1 << 2),
};
class Minecraft;
class Player;
class Command {
public:
const std::string& getName() { return m_name; }
const CommandFlags getFlags() { return m_flags; }
bool isPlayerOp(Minecraft& mc, Player& player);
virtual std::string execute(Minecraft& mc, Player& player, const std::vector<std::string>& args) = 0;
virtual std::string help(Minecraft& mc) = 0;
protected:
Command(const std::string& name, CommandFlags flags = (CommandFlags)0) : m_name(name), m_flags(flags) {}
const std::string m_name;
const CommandFlags m_flags;
};

View File

@@ -1,49 +0,0 @@
#include "CommandBan.hpp"
#include "commands/Command.hpp"
#include "network/RakNetInstance.h"
#include "raknet/RakPeerInterface.h"
#include "world/level/Level.h"
#include <algorithm>
#include <client/Minecraft.h>
#include <network/packet/LoginStatusPacket.h>
CommandBan::CommandBan() : Command("ban") {}
std::string CommandBan::execute(Minecraft& mc, Player& player, const std::vector<std::string>& args) {
if (!isPlayerOp(mc, player)) {
return "You aren't enough priveleged to run this command";
}
if (args.empty()) {
return help(mc);
}
std::string nicknameLower = args[0];
std::transform(nicknameLower.begin(), nicknameLower.end(), nicknameLower.begin(), ::tolower);
auto it = std::find_if(mc.level->players.begin(), mc.level->players.end(), [nicknameLower] (auto& it) -> bool {
std::string lower = it->name;
std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower);
return lower == nicknameLower;
});
if (it != mc.level->players.end()) {
if (*it == (Player*)mc.player) {
return "banip: you can't ban urself lol";
}
} else {
for (auto& banned : mc.level->bannedPpl) {
if (nicknameLower == banned) {
return args[0] + " already banned!";
}
}
}
mc.level->bannedPpl.insert(nicknameLower);
return "ban: successfully banned player " + args[0];
}
std::string CommandBan::help(Minecraft& mc) {
return "Usage: /ban <player>";
}

View File

@@ -1,9 +0,0 @@
#include "Command.hpp"
class CommandBan : public Command {
public:
CommandBan();
std::string execute(Minecraft& mc, Player& player, const std::vector<std::string>& args);
std::string help(Minecraft& mc);
};

View File

@@ -1,65 +0,0 @@
#include "CommandBanIp.hpp"
#include "commands/Command.hpp"
#include "network/RakNetInstance.h"
#include "raknet/RakPeerInterface.h"
#include "world/level/Level.h"
#include <algorithm>
#include <client/Minecraft.h>
CommandBanIp::CommandBanIp() : Command("banip") {}
std::string CommandBanIp::execute(Minecraft& mc, Player& player, const std::vector<std::string>& args) {
if (!isPlayerOp(mc, player)) {
return "You aren't enough priveleged to run this command";
}
if (args.empty()) {
return help(mc);
}
std::string nicknameLower = args[0];
std::transform(nicknameLower.begin(), nicknameLower.end(), nicknameLower.begin(), ::tolower);
auto it = std::find_if(mc.level->players.begin(), mc.level->players.end(), [nicknameLower] (auto& it) -> bool {
std::string lower = it->name;
std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower);
return lower == nicknameLower;
});
std::string clientIp;
if (it != mc.level->players.end()) {
if (*it == (Player*)mc.player) {
return "banip: you can't ban urself lol";
}
RakNet::SystemAddress sysAddress = mc.raknetInstance->getPeer()->GetSystemAddressFromGuid((*it)->owner);
char ip[32];
sysAddress.ToString(false, ip);
clientIp = ip;
auto sourceId = (*it)->owner;
(*it)->reallyRemoveIfPlayer = true;
mc.level->removeEntity((*it));
mc.raknetInstance->getPeer()->CloseConnection(sourceId, true);
} else {
for (auto& banned : mc.level->bannedIps) {
if (clientIp == banned) {
return args[0] + " already banned!";
}
}
clientIp = args[0];
}
mc.level->bannedIps.insert(clientIp);
return "banip: successfully banned player by ip " + args[0];
}
std::string CommandBanIp::help(Minecraft& mc) {
return "Usage: /banip <player>";
}

View File

@@ -1,9 +0,0 @@
#include "Command.hpp"
class CommandBanIp : public Command {
public:
CommandBanIp();
std::string execute(Minecraft& mc, Player& player, const std::vector<std::string>& args);
std::string help(Minecraft& mc);
};

View File

@@ -1,35 +0,0 @@
#include "CommandHelp.hpp"
#include "commands/Command.hpp"
#include "CommandManager.hpp"
#include <client/Minecraft.h>
#include <sstream>
CommandHelp::CommandHelp() : Command("help") {}
std::string CommandHelp::execute(Minecraft& mc, Player& player, const std::vector<std::string>& args) {
if (args.empty()) {
auto cmds = mc.commandManager().getListAllCommands();
std::ostringstream output;
output << "List of all commands:" << std::endl;
for (auto& cmd : cmds) {
output << " - " + cmd << std::endl;;
}
return output.str();
}
Command* cmd = mc.commandManager().getCommand(args[0]);
if (cmd != nullptr) {
return cmd->help(mc);
}
return "help: command " + args[0] + " not found";
}
std::string CommandHelp::help(Minecraft& mc) {
return "Usage: /help <command>";
}

View File

@@ -1,9 +0,0 @@
#include "Command.hpp"
class CommandHelp : public Command {
public:
CommandHelp();
std::string execute(Minecraft& mc, Player& player, const std::vector<std::string>& args);
std::string help(Minecraft& mc);
};

View File

@@ -1,48 +0,0 @@
#include "CommandKick.hpp"
#include "commands/Command.hpp"
#include "network/RakNetInstance.h"
#include "raknet/RakPeerInterface.h"
#include "world/level/Level.h"
#include <algorithm>
#include <client/Minecraft.h>
CommandKick::CommandKick() : Command("kick") {}
std::string CommandKick::execute(Minecraft& mc, Player& player, const std::vector<std::string>& args) {
if (!isPlayerOp(mc, player)) {
return "You aren't enough priveleged to run this command";
}
if (args.empty()) {
return help(mc);
}
std::string nicknameLower = args[0];
std::transform(nicknameLower.begin(), nicknameLower.end(), nicknameLower.begin(), ::tolower);
auto it = std::find_if(mc.level->players.begin(), mc.level->players.end(), [args, nicknameLower] (auto& it) -> bool {
std::string lower = it->name;
std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower);
return lower == nicknameLower;
});
if (it == mc.level->players.end()) {
return "kick: can't find player with name " + args[0];
}
if (*it == (Player*)mc.player) {
return "kick: you can't kick urself lol";
}
auto sourceId = (*it)->owner;
(*it)->reallyRemoveIfPlayer = true;
mc.level->removeEntity((*it));
mc.raknetInstance->getPeer()->CloseConnection(sourceId, true);
return "kick: successfully kicked player " + args[0];
}
std::string CommandKick::help(Minecraft& mc) {
return "Usage: /kick <player>";
}

View File

@@ -1,9 +0,0 @@
#include "Command.hpp"
class CommandKick : public Command {
public:
CommandKick();
std::string execute(Minecraft& mc, Player& player, const std::vector<std::string>& args);
std::string help(Minecraft& mc);
};

View File

@@ -1,79 +0,0 @@
#include "CommandManager.hpp"
#include <algorithm>
#include <string>
#include <vector>
#include "client/Minecraft.h"
#include "commands/Command.hpp"
#include "commands/CommandHelp.hpp"
#include "commands/CommandKick.hpp"
#include "commands/CommandOp.hpp"
#include "commands/CommandBan.hpp"
#include "commands/CommandBanIp.hpp"
#include "commands/CommandPardon.hpp"
#include "network/packet/ChatPacket.h"
#include "network/RakNetInstance.h"
#include "world/level/Level.h"
CommandManager::CommandManager() {
registerAllCommands();
}
void CommandManager::registerAllCommands() {
m_commands.push_back(new CommandHelp());
m_commands.push_back(new CommandKick());
m_commands.push_back(new CommandOp());
m_commands.push_back(new CommandBan());
m_commands.push_back(new CommandBanIp());
m_commands.push_back(new CommandPardon());
}
std::vector<std::string> CommandManager::getListAllCommands() {
std::vector<std::string> ret;
for (auto& cmd : m_commands) {
ret.push_back(cmd->getName());
}
return ret;
}
std::string CommandManager::execute(Minecraft& mc, Player& player, const std::string& input) {
std::istringstream ss(input);
std::string cmd;
ss >> cmd;
auto it = std::find_if(m_commands.begin(), m_commands.end(), [cmd](auto& it) -> bool {
return it->getName() == cmd;
});
if (it == m_commands.end()) {
return "Command /" + cmd + " not found";
}
std::vector<std::string> args;
std::string tok;
while (ss >> tok) args.push_back(tok);
if (!mc.level->isClientSide || (*it)->getFlags() & CommandFlags::COMMAND_FLAG_SINGLEPLAYER_ONLY) {
return (*it)->execute(mc, player, args);
} else {
ChatPacket packet("/" + input);
mc.raknetInstance->send(packet);
}
return "";
}
Command* CommandManager::getCommand(const std::string& name) {
auto it = std::find_if(m_commands.begin(), m_commands.end(), [name](auto& it) -> bool {
return it->getName() == name;
});
if (it == m_commands.end()) {
return *it;
}
return nullptr;
}

View File

@@ -1,21 +0,0 @@
#pragma once
#include <string>
#include <vector>
#include "Command.hpp"
class CommandManager {
public:
CommandManager();
std::vector<std::string> getListAllCommands();
std::string execute(Minecraft& mc, Player& player, const std::string& input);
Command* getCommand(const std::string& name);
private:
void registerAllCommands();
std::vector<Command*> m_commands;
};

View File

@@ -1,31 +0,0 @@
#include "CommandOp.hpp"
#include "commands/Command.hpp"
#include "world/level/Level.h"
#include <algorithm>
#include <client/Minecraft.h>
CommandOp::CommandOp() : Command("op") {}
std::string CommandOp::execute(Minecraft& mc, Player& player, const std::vector<std::string>& args) {
if (!isPlayerOp(mc, player)) {
return "You aren't enough priveleged to run this command";
}
if (args.empty()) {
return help(mc);
}
std::string nicknameLower = args[0];
std::transform(nicknameLower.begin(), nicknameLower.end(), nicknameLower.begin(), ::tolower);
if (mc.level->ops.find(nicknameLower) != mc.level->ops.end()) {
return "op: player " + args[0] + " already opped";
}
mc.level->ops.emplace(nicknameLower);
return "op: successfully opped player " + args[0];
}
std::string CommandOp::help(Minecraft& mc) {
return "Usage: /op <player>";
}

View File

@@ -1,9 +0,0 @@
#include "Command.hpp"
class CommandOp : public Command {
public:
CommandOp();
std::string execute(Minecraft& mc, Player& player, const std::vector<std::string>& args);
std::string help(Minecraft& mc);
};

View File

@@ -1,40 +0,0 @@
#include "CommandPardon.hpp"
#include "commands/Command.hpp"
#include "network/RakNetInstance.h"
#include "raknet/RakPeerInterface.h"
#include "world/level/Level.h"
#include <algorithm>
#include <client/Minecraft.h>
CommandPardon::CommandPardon() : Command("pardon") {}
std::string CommandPardon::execute(Minecraft& mc, Player& player, const std::vector<std::string>& args) {
if (!isPlayerOp(mc, player)) {
return "You aren't enough priveleged to run this command";
}
if (args.empty()) {
return help(mc);
}
std::string nicknameLower = args[0];
std::transform(nicknameLower.begin(), nicknameLower.end(), nicknameLower.begin(), ::tolower);
if (mc.level->bannedPpl.find(nicknameLower) != mc.level->bannedPpl.end()) {
mc.level->bannedPpl.erase(nicknameLower);
return "pardon: successfully unbanned player " + args[0];
}
if (mc.level->bannedIps.find(nicknameLower) != mc.level->bannedIps.end()) {
mc.level->bannedIps.erase(nicknameLower);
return "pardon: successfully unbanned ip " + args[0];
}
return "Player/Ip doesnt banned";
}
std::string CommandPardon::help(Minecraft& mc) {
return "Usage: /pardon <player>";
}

View File

@@ -1,9 +0,0 @@
#include "Command.hpp"
class CommandPardon : public Command {
public:
CommandPardon();
std::string execute(Minecraft& mc, Player& player, const std::vector<std::string>& args);
std::string help(Minecraft& mc);
};

View File

@@ -1,30 +1,25 @@
#include <fstream>
#include <iostream> #include <iostream>
#include "NinecraftApp.h" #include "NinecraftApp.h"
#include "AppPlatform.h" #include "AppPlatform.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <signal.h> #include <signal.h>
#ifdef __linux__
#include <unistd.h> #include <unistd.h>
#endif
#include "world/level/LevelSettings.h" #include "world/level/LevelSettings.h"
#include "world/level/Level.h" #include "world/level/Level.h"
#include "server/ArgumentsSettings.h" #include "server/ArgumentsSettings.h"
#include "platform/time.h" #include "platform/time.h"
#include "SharedConstants.h" #include "SharedConstants.h"
#include "world/level/LevelConstants.h"
#include <plugins/PluginsManager.hpp>
#define MAIN_CLASS NinecraftApp #define MAIN_CLASS NinecraftApp
static App* g_app = 0; static App* g_app = 0;
static int g_exitCode = 0; static int g_exitCode = 0;
void signal_callback_handler(int signum) { void signal_callback_handler(int signum) {
std::cout << "Signum caught: " << signum << std::endl; std::cout << "Signum caught: " << signum << std::endl;
if(signum == 2 || signum == 3){ // SIGINT || SIGQUIT
if (signum == 2 || signum == 3) { // SIGINT || SIGQUIT if(g_app != 0) {
if (g_app != 0) {
g_app->quit(); g_app->quit();
} else { } else {
exit(g_exitCode); exit(g_exitCode);
@@ -32,242 +27,47 @@ void signal_callback_handler(int signum) {
} }
} }
std::string findStringInConfig(std::string line, std::string config) {
auto valuePos = config.find(line);
if (line.empty()) {
throw std::runtime_error("Key cannot be empty");
}
if (valuePos == std::string::npos) {
throw std::runtime_error("Cannot find value");
}
std::string valueStr = "";
valuePos += 1 + line.size();
while (true) {
auto sym = config.at(valuePos);
if (sym == '\n') {
break;
}
if (valuePos == config.size()) {
throw std::runtime_error("Cannot find end of the line");
}
valueStr += sym;
valuePos++;
}
return valueStr;
}
int main(int numArguments, char* pszArgs[]) { int main(int numArguments, char* pszArgs[]) {
std::ifstream serverProperties("server.properties"); ArgumentsSettings aSettings(numArguments, pszArgs);
if(aSettings.getShowHelp()) {
int port = 0;
int gamemode = 0;
int worldSize = 0;
std::string levelDir = "";
std::string cachePath = "";
std::string externalPath = "";
std::string levelName = "";
if (serverProperties.is_open()) {
std::string propString;
std::string line;
while (std::getline(serverProperties, line)) {
propString += line;
propString += "\n";
}
if (propString.empty()) {
throw std::runtime_error("Config cannot be empty");
}
port = std::stoi(findStringInConfig("port", propString));
worldSize = std::stoi(findStringInConfig("world-size", propString));
if (worldSize < 16 || worldSize > 32) {
throw std::runtime_error("Incorrect world size.");
}
LevelConstants::CHUNK_CACHE_WIDTH = worldSize;
LevelConstants::LEVEL_WIDTH = LevelConstants::CHUNK_CACHE_WIDTH * LevelConstants::CHUNK_WIDTH;
LevelConstants::LEVEL_DEPTH = LevelConstants::CHUNK_CACHE_WIDTH * LevelConstants::CHUNK_DEPTH;
cachePath = findStringInConfig("level-cachepath", propString);
externalPath = findStringInConfig("level-externalpath", propString);
levelName = findStringInConfig("level-name", propString);
levelDir = findStringInConfig("level-dir", propString);
std::string gamemodeStr = findStringInConfig("gamemode", propString);
if (gamemodeStr == "survival") {
gamemode = GameType::Survival;
} else if (gamemodeStr == "creative") {
gamemode = GameType::Creative;
} else {
gamemode = GameType::Survival;
}
printf("%d %s %s %d %d\n", port, cachePath.c_str(), externalPath.c_str(), gamemode, LevelConstants::CHUNK_CACHE_WIDTH);
} else {
std::ofstream defaultProperties("server.properties");
if (defaultProperties.is_open()) {
ArgumentsSettings defaultSettings(0, NULL); ArgumentsSettings defaultSettings(0, NULL);
printf("Minecraft Pockect Edition Server %s\n", Common::getGameVersionString("").c_str());
std::stringstream buffer; printf("-------------------------------------------------------\n");
printf("--cachepath - Path to where the server can store temp stuff (not sure if this is used) [default: \"%s\"]\n", defaultSettings.getCachePath().c_str());
buffer << "// MCPE Server properties" << std::endl; printf("--externalpath - The path to the place where the server should store the levels. [default: \"%s\"]\n", defaultSettings.getExternalPath().c_str());
buffer << "port=" << defaultSettings.getPort() << std::endl; printf("--levelname - The name of the server [default: \"%s\"]\n", defaultSettings.getLevelName().c_str());
buffer << "level-dir=" << defaultSettings.getLevelDir() << std::endl; printf("--leveldir - The name of the server [default: \"%s\"]\n", defaultSettings.getLevelDir().c_str());
buffer << "level-cachepath=" << defaultSettings.getCachePath() << std::endl; printf("--help - Shows this message.\n");
buffer << "level-externalpath=" << defaultSettings.getExternalPath() << std::endl; printf("--port - The port to run the server on. [default: %d]\n", defaultSettings.getPort());
buffer << "gamemode=survival" << std::endl; printf("--serverkey - The key that the server should use for API calls. [default: \"%s\"]\n", defaultSettings.getServerKey().c_str());
buffer << "level-name=" << defaultSettings.getLevelName() << std::endl; printf("-------------------------------------------------------\n");
buffer << "world-size=16" << std::endl; return 0;
defaultProperties << buffer.str();
printf("%s \n", buffer.str().c_str());
printf("Edit a config file first!\n");
defaultProperties.close();
exit(0);
} else {
throw std::runtime_error("Cannot create default config.");
} }
} printf("Level Name: %s\n", aSettings.getLevelName().c_str());
printf("Level Name: %s\n", levelName.c_str());
AppContext appContext; AppContext appContext;
appContext.platform = new AppPlatform(); appContext.platform = new AppPlatform();
App* app = new MAIN_CLASS(); App* app = new MAIN_CLASS();
signal(SIGINT, signal_callback_handler); signal(SIGINT, signal_callback_handler);
g_app = app; g_app = app;
((MAIN_CLASS*)g_app)->externalStoragePath = externalPath; ((MAIN_CLASS*)g_app)->externalStoragePath = aSettings.getExternalPath();
((MAIN_CLASS*)g_app)->externalCacheStoragePath = cachePath; ((MAIN_CLASS*)g_app)->externalCacheStoragePath = aSettings.getCachePath();
g_app->init(appContext); g_app->init(appContext);
LevelSettings settings(getEpochTimeS(), gamemode); LevelSettings settings(getEpochTimeS(), GameType::Creative);
float startTime = getTimeS(); float startTime = getTimeS();
((MAIN_CLASS*)g_app)->selectLevel(levelDir, levelName, settings); ((MAIN_CLASS*)g_app)->selectLevel(aSettings.getLevelDir(), aSettings.getLevelName(), settings);
((MAIN_CLASS*)g_app)->hostMultiplayer(port); ((MAIN_CLASS*)g_app)->hostMultiplayer(aSettings.getPort());
PluginsManager::get().loadPlugins();
// Reading ops
std::ifstream ops("ops.txt");
if (ops.is_open()) {
std::string line;
while (std::getline(ops, line)) {
if (!line.empty()) {
((MAIN_CLASS*)g_app)->level->ops.insert(line);
}
}
} else {
std::ofstream opsDefault("ops.txt");
if (!opsDefault.is_open()) {
throw std::runtime_error("Cannot create ops list.");
}
}
// Reading banned ppl
std::ifstream banned("banned-players.txt");
if (banned.is_open()) {
std::string line;
while (std::getline(banned, line)) {
if (!line.empty()) {
((MAIN_CLASS*)g_app)->level->bannedPpl.insert(line);
}
}
} else {
std::ofstream bannedPpl("banned-players.txt");
if (!bannedPpl.is_open()) {
throw std::runtime_error("Cannot create banned players list.");
}
}
std::ifstream bannedIps("banned-ips.txt");
if (bannedIps.is_open()) {
std::string line;
while (std::getline(bannedIps, line)) {
if (!line.empty()) {
((MAIN_CLASS*)g_app)->level->bannedIps.insert(line);
}
}
} else {
std::ofstream bannedIp("banned-ips.txt");
if (!bannedIp.is_open()) {
throw std::runtime_error("Cannot create banned players list.");
}
}
std::cout << "Level has been generated in " << getTimeS() - startTime << std::endl; std::cout << "Level has been generated in " << getTimeS() - startTime << std::endl;
((MAIN_CLASS*)g_app)->level->saveLevelData(); ((MAIN_CLASS*)g_app)->level->saveLevelData();
std::cout << "Level has been saved!" << std::endl; std::cout << "Level has been saved!" << std::endl;
PluginsManager::get().emit("ServerLoaded");
while(!app->wantToQuit()) { while(!app->wantToQuit()) {
app->update(); app->update();
//pthread_yield(); //pthread_yield();
sleepMs(20); sleepMs(20);
} }
std::ofstream opsWrite("ops.txt");
if (opsWrite.is_open()) {
for (auto& op : ((MAIN_CLASS*)g_app)->level->ops) {
opsWrite << op << std::endl;
}
opsWrite.close();
} else {
throw std::runtime_error("Cannot open ops list.");
}
std::ofstream bannedWrite("banned-players.txt");
if (bannedWrite.is_open()) {
for (auto& banned : ((MAIN_CLASS*)g_app)->level->bannedPpl) {
bannedWrite << banned << std::endl;
}
bannedWrite.close();
} else {
throw std::runtime_error("Cannot open banned players list.");
}
std::ofstream bannedIpsWrite("banned-ips.txt");
if (bannedIpsWrite.is_open()) {
for (auto& banned : ((MAIN_CLASS*)g_app)->level->bannedIps) {
bannedIpsWrite << banned << std::endl;
}
bannedIpsWrite.close();
} else {
throw std::runtime_error("Cannot open banned players list.");
}
PluginsManager::get().emit("ServerShutdown");
((MAIN_CLASS*)g_app)->level->saveLevelData(); ((MAIN_CLASS*)g_app)->level->saveLevelData();
delete app; delete app;
appContext.platform->finish(); appContext.platform->finish();
delete appContext.platform; delete appContext.platform;

View File

@@ -18,6 +18,87 @@
#endif #endif
static App* g_app = 0; static App* g_app = 0;
#ifdef __EMSCRIPTEN__
static int g_touchPointerIds[Multitouch::MAX_POINTERS];
static void resetTouchPointerIds() {
for (int i = 0; i < Multitouch::MAX_POINTERS; ++i) {
g_touchPointerIds[i] = -1;
}
}
static int getTouchPointerSlot(int touchId) {
for (int i = 0; i < Multitouch::MAX_POINTERS; ++i) {
if (g_touchPointerIds[i] == touchId) return i;
}
return -1;
}
static int allocateTouchPointerSlot(int touchId) {
int slot = getTouchPointerSlot(touchId);
if (slot >= 0) return slot;
for (int i = 0; i < Multitouch::MAX_POINTERS; ++i) {
if (g_touchPointerIds[i] < 0) {
g_touchPointerIds[i] = touchId;
return i;
}
}
return -1;
}
static void releaseTouchPointerSlot(int touchId) {
for (int i = 0; i < Multitouch::MAX_POINTERS; ++i) {
if (g_touchPointerIds[i] == touchId) {
g_touchPointerIds[i] = -1;
return;
}
}
}
static EM_BOOL touch_callback(int eventType, const EmscriptenTouchEvent* touchEvent, void* userData) {
if (!touchEvent) return 0;
const bool isStart = eventType == EMSCRIPTEN_EVENT_TOUCHSTART;
const bool isMove = eventType == EMSCRIPTEN_EVENT_TOUCHMOVE;
const bool isEnd = eventType == EMSCRIPTEN_EVENT_TOUCHEND;
const bool isCancel = eventType == EMSCRIPTEN_EVENT_TOUCHCANCEL;
if (isCancel) {
for (int i = 0; i < Multitouch::MAX_POINTERS; ++i) {
if (g_touchPointerIds[i] >= 0) {
Multitouch::feed(1, 0, Multitouch::getX(i), Multitouch::getY(i), i);
g_touchPointerIds[i] = -1;
}
}
return 1;
}
for (int i = 0; i < touchEvent->numTouches; ++i) {
const EmscriptenTouchPoint& touch = touchEvent->touches[i];
if (!touch.isChanged) continue;
const int slot = isEnd ? getTouchPointerSlot(touch.identifier) : allocateTouchPointerSlot(touch.identifier);
if (slot < 0) continue;
const short x = (short)touch.targetX;
const short y = (short)touch.targetY;
if (isStart) {
Multitouch::feed(1, 1, x, y, slot);
} else if (isMove) {
Multitouch::feed(0, 0, x, y, slot);
} else if (isEnd) {
Multitouch::feed(1, 0, x, y, slot);
releaseTouchPointerSlot(touch.identifier);
}
}
return 1;
}
#endif
int transformKey(int glfwkey) { int transformKey(int glfwkey) {
if (glfwkey >= GLFW_KEY_F1 && glfwkey <= GLFW_KEY_F12) { if (glfwkey >= GLFW_KEY_F1 && glfwkey <= GLFW_KEY_F12) {
return glfwkey - 178; return glfwkey - 178;
@@ -180,6 +261,13 @@ int main(void) {
glfwSetMouseButtonCallback(platform->window, mouse_button_callback); glfwSetMouseButtonCallback(platform->window, mouse_button_callback);
glfwSetScrollCallback(platform->window, scroll_callback); glfwSetScrollCallback(platform->window, scroll_callback);
glfwSetWindowSizeCallback(platform->window, window_size_callback); glfwSetWindowSizeCallback(platform->window, window_size_callback);
#ifdef __EMSCRIPTEN__
resetTouchPointerIds();
emscripten_set_touchstart_callback("#canvas", 0, 1, touch_callback);
emscripten_set_touchmove_callback("#canvas", 0, 1, touch_callback);
emscripten_set_touchend_callback("#canvas", 0, 1, touch_callback);
emscripten_set_touchcancel_callback("#canvas", 0, 1, touch_callback);
#endif
glfwMakeContextCurrent(platform->window); glfwMakeContextCurrent(platform->window);
#ifndef __EMSCRIPTEN__ #ifndef __EMSCRIPTEN__

View File

@@ -1,7 +1,6 @@
#include "ClientSideNetworkHandler.h" #include "ClientSideNetworkHandler.h"
#include "client/Options.h" #include "client/Options.h"
#include "network/packet/LoginStatusPacket.h"
#include "packet/PacketInclude.h" #include "packet/PacketInclude.h"
#include "RakNetInstance.h" #include "RakNetInstance.h"
#include "../world/level/chunk/ChunkSource.h" #include "../world/level/chunk/ChunkSource.h"
@@ -11,9 +10,6 @@
#include "../world/entity/player/Inventory.h" #include "../world/entity/player/Inventory.h"
#include "../client/Minecraft.h" #include "../client/Minecraft.h"
#include "../client/gamemode/GameMode.h" #include "../client/gamemode/GameMode.h"
#include "world/item/ItemInstance.h"
#include "world/level/LevelConstants.h"
#include <cstddef>
#ifndef STANDALONE_SERVER #ifndef STANDALONE_SERVER
#include "../client/gui/screens/DisconnectionScreen.h" #include "../client/gui/screens/DisconnectionScreen.h"
#endif #endif
@@ -46,9 +42,6 @@ ClientSideNetworkHandler::ClientSideNetworkHandler(Minecraft* minecraft, IRakNet
requestNextChunkPosition(0), requestNextChunkPosition(0),
requestNextChunkIndex(0) requestNextChunkIndex(0)
{ {
NumRequestChunks = LevelConstants::CHUNK_CACHE_WIDTH * LevelConstants::CHUNK_CACHE_WIDTH;
requestNextChunkIndexList.resize(NumRequestChunks);
chunksLoaded.resize(NumRequestChunks);
rakPeer = raknetInstance->getPeer(); rakPeer = raknetInstance->getPeer();
} }
@@ -66,7 +59,7 @@ void ClientSideNetworkHandler::requestNextChunk()
//LOGI("requesting chunks @ (%d, %d)\n", chunk.x, chunk.y); //LOGI("requesting chunks @ (%d, %d)\n", chunk.x, chunk.y);
//raknetInstance->send(new RequestChunkPacket(requestNextChunkPosition % LevelConstants::CHUNK_CACHE_WIDTH, requestNextChunkPosition / LevelConstants::CHUNK_CACHE_WIDTH)); //raknetInstance->send(new RequestChunkPacket(requestNextChunkPosition % CHUNK_CACHE_WIDTH, requestNextChunkPosition / CHUNK_CACHE_WIDTH));
requestNextChunkIndex++; requestNextChunkIndex++;
requestNextChunkPosition++; requestNextChunkPosition++;
} }
@@ -74,16 +67,16 @@ void ClientSideNetworkHandler::requestNextChunk()
bool ClientSideNetworkHandler::areAllChunksLoaded() bool ClientSideNetworkHandler::areAllChunksLoaded()
{ {
return (requestNextChunkPosition >= (LevelConstants::CHUNK_CACHE_WIDTH * LevelConstants::CHUNK_CACHE_WIDTH)); return (requestNextChunkPosition >= (CHUNK_CACHE_WIDTH * CHUNK_CACHE_WIDTH));
} }
bool ClientSideNetworkHandler::isChunkLoaded(int x, int z) bool ClientSideNetworkHandler::isChunkLoaded(int x, int z)
{ {
if (x < 0 || x >= LevelConstants::CHUNK_CACHE_WIDTH || z < 0 || z >= LevelConstants::CHUNK_CACHE_WIDTH) { if (x < 0 || x >= CHUNK_CACHE_WIDTH || z < 0 || z >= CHUNK_CACHE_WIDTH) {
LOGE("Error: Tried to request chunk (%d, %d)\n", x, z); LOGE("Error: Tried to request chunk (%d, %d)\n", x, z);
return true; return true;
} }
return chunksLoaded[x * LevelConstants::CHUNK_CACHE_WIDTH + z]; return chunksLoaded[x * CHUNK_CACHE_WIDTH + z];
//return areAllChunksLoaded(); //return areAllChunksLoaded();
} }
@@ -93,7 +86,7 @@ void ClientSideNetworkHandler::onConnect(const RakNet::RakNetGUID& hostGuid)
serverGuid = hostGuid; serverGuid = hostGuid;
clearChunksLoaded(); clearChunksLoaded();
LoginPacket packet(minecraft->options.getStringValue(OPTIONS_USERNAME).c_str(), SharedConstants::NetworkProtocolVersion, true); LoginPacket packet(minecraft->options.getStringValue(OPTIONS_USERNAME).c_str(), SharedConstants::NetworkProtocolVersion);
raknetInstance->send(packet); raknetInstance->send(packet);
} }
@@ -104,11 +97,6 @@ void ClientSideNetworkHandler::onUnableToConnect()
void ClientSideNetworkHandler::onDisconnect(const RakNet::RakNetGUID& guid) void ClientSideNetworkHandler::onDisconnect(const RakNet::RakNetGUID& guid)
{ {
LevelConstants::CHUNK_CACHE_WIDTH = 16;
LevelConstants::LEVEL_WIDTH = LevelConstants::CHUNK_CACHE_WIDTH * LevelConstants::CHUNK_WIDTH;
LevelConstants::LEVEL_DEPTH = LevelConstants::CHUNK_CACHE_WIDTH * LevelConstants::CHUNK_DEPTH;
// TODO: Good disconnecting
LOGI("onDisconnect\n"); LOGI("onDisconnect\n");
if (level) if (level)
{ {
@@ -121,13 +109,9 @@ void ClientSideNetworkHandler::onDisconnect(const RakNet::RakNetGUID& guid)
} }
} }
} }
minecraft->leaveGame(); #ifndef STANDALONE_SERVER
// minecraft->setLevel(NULL); minecraft->gui.addMessage("Disconnected from server");
// #ifndef STANDALONE_SERVER #endif
// minecraft->gui.addMessage("Disconnected from server");
// // TODO: screen with error
// minecraft->screenChooser.setScreen(SCREEN_STARTMENU);
// #endif
} }
void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, LoginStatusPacket* packet) { void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, LoginStatusPacket* packet) {
@@ -146,18 +130,6 @@ void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, LoginSta
LOGI("Disconnect! Server is outdated!\n"); LOGI("Disconnect! Server is outdated!\n");
#ifndef STANDALONE_SERVER #ifndef STANDALONE_SERVER
minecraft->setScreen(new DisconnectionScreen("Could not connect: Outdated server!")); minecraft->setScreen(new DisconnectionScreen("Could not connect: Outdated server!"));
#endif
}
if (packet->status == LoginStatus::Failed_TakenNickname) {
LOGI("Disconnect! Nickname is taken!\n");
#ifndef STANDALONE_SERVER
minecraft->setScreen(new DisconnectionScreen("Could not connect: Nickname is taken!"));
#endif
}
if (packet->status == LoginStatus::Failed_Banned) {
LOGI("Disconnect! You're banned from this server!\n");
#ifndef STANDALONE_SERVER
minecraft->setScreen(new DisconnectionScreen("Could not connect: You're banned from this server!"));
#endif #endif
} }
} }
@@ -174,19 +146,6 @@ void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, StartGam
} }
#endif #endif
// @todo @note i think its trash
// we can put it directly to selectLevel?
if (packet->chunkCacheWidth != 0) {
printf("lol \n");
LevelConstants::CHUNK_CACHE_WIDTH = packet->chunkCacheWidth;
LevelConstants::LEVEL_WIDTH = LevelConstants::CHUNK_CACHE_WIDTH * LevelConstants::CHUNK_WIDTH;
LevelConstants::LEVEL_DEPTH = LevelConstants::CHUNK_CACHE_WIDTH * LevelConstants::CHUNK_DEPTH;
LevelChunk::ChunkBlockCount = LevelConstants::CHUNK_BLOCK_COUNT;
}
NumRequestChunks = LevelConstants::CHUNK_CACHE_WIDTH * LevelConstants::CHUNK_CACHE_WIDTH;
requestNextChunkIndexList.resize(NumRequestChunks);
chunksLoaded.resize(NumRequestChunks);
const std::string& levelId = LevelStorageSource::TempLevelId; const std::string& levelId = LevelStorageSource::TempLevelId;
LevelStorageSource* storageSource = minecraft->getLevelSource(); LevelStorageSource* storageSource = minecraft->getLevelSource();
storageSource->deleteLevel(levelId); storageSource->deleteLevel(levelId);
@@ -223,7 +182,7 @@ void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, SetTimeP
if (!level) if (!level)
return; return;
// LOGI("SetTimePacket\n"); LOGI("SetTimePacket\n");
level->setTime(packet->time); level->setTime(packet->time);
} }
@@ -279,7 +238,7 @@ void ClientSideNetworkHandler::handle( const RakNet::RakNetGUID& source, AddPain
} }
void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, AddMobPacket* packet) void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, AddMobPacket* packet)
{ {
// LOGI("AddMobPacket (%p)\n", level); LOGI("AddMobPacket (%p)\n", level);
if (!level) { if (!level) {
LOGW("Trying to add a mob with no level!\n"); LOGW("Trying to add a mob with no level!\n");
@@ -365,7 +324,7 @@ void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, RemoveEn
if (!level) return; if (!level) return;
Entity* entity = level->getEntity(packet->entityId); Entity* entity = level->getEntity(packet->entityId);
// LOGI("RemoveEntityPacket %p %p, %d\n", entity, minecraft->player, entity?(int)(entity->isPlayer()): -1); LOGI("RemoveEntityPacket %p %p, %d\n", entity, minecraft->player, entity?(int)(entity->isPlayer()): -1);
if (!entity) return; if (!entity) return;
level->removeEntity(entity); level->removeEntity(entity);
@@ -385,7 +344,6 @@ void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, AddItemE
} }
void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, TakeItemEntityPacket* packet) { void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, TakeItemEntityPacket* packet) {
// printf("TakeItemEntityPacket \n");
if (!level) return; if (!level) return;
Entity* e = level->getEntity(packet->itemId); Entity* e = level->getEntity(packet->itemId);
@@ -428,54 +386,6 @@ void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, MovePlay
} }
} }
void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, SendInventoryPacket* packet) {
if (!level) return;
if (packet->entityId == minecraft->player->entityId) {
auto items = packet->items;
minecraft->player->inventory->replace(items);
for (int i = 0; i < packet->linkedSlot.size(); i++) {
minecraft->player->inventory->linkSlot(i, packet->linkedSlot[i].inventorySlot, true);
LOGI("%i -> %i\n", packet->linkedSlot[i].inventorySlot, i);
}
}
}
void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, TakeItemPacket* packet) {
if (!level) return;
LOGI("TakeItemPacket\n");
ItemInstance* item = new ItemInstance();
item->count = packet->count;
item->id = packet->itemId;
item->setAuxValue(packet->auxValue);
// if (minecraft->player->entityId == packet->playerId) {
if (!minecraft->player->inventory->add(item)) {
minecraft->player->drop(new ItemInstance(*item), false);
}
// }
}
void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, RemoveItemPacket* packet) {
// Idk how it works...
if (!level) return;
ItemInstance item;
item.count = packet->count;
item.id = packet->itemId;
item.setAuxValue(packet->auxValue);
// if (minecraft->player->entityId == packet->playerId) {
minecraft->player->inventory->removeResource(item);
// }
}
void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, MoveEntityPacket* packet) void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, MoveEntityPacket* packet)
{ {
if (!level) if (!level)
@@ -565,19 +475,19 @@ void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, ChunkDat
//unsigned char* blockIds = chunk->getBlockData(); //unsigned char* blockIds = chunk->getBlockData();
DataLayer& blockData = chunk->data; DataLayer& blockData = chunk->data;
const int setSize = LevelConstants::LEVEL_HEIGHT / 8; const int setSize = LEVEL_HEIGHT / 8;
const int setShift = 4; // power of LevelConstants::LEVEL_HEIGHT / 8 const int setShift = 4; // power of LEVEL_HEIGHT / 8
bool recalcHeight = false; bool recalcHeight = false;
int x0 = 16, x1 = 0, z0 = 16, z1 = 0, y0 = LevelConstants::LEVEL_HEIGHT, y1 = 0; int x0 = 16, x1 = 0, z0 = 16, z1 = 0, y0 = LEVEL_HEIGHT, y1 = 0;
int rx = packet->x << 4; int rx = packet->x << 4;
int rz = packet->z << 4; int rz = packet->z << 4;
unsigned char* readBlockBuffer = new unsigned char[setSize]; unsigned char readBlockBuffer[setSize];
unsigned char* readDataBuffer = new unsigned char[setSize / 2]; unsigned char readDataBuffer[setSize / 2];
for (int i = 0; i < LevelConstants::CHUNK_COLUMNS; i++) for (int i = 0; i < CHUNK_COLUMNS; i++)
{ {
unsigned char updateBits = 0; unsigned char updateBits = 0;
packet->chunkData.Read(updateBits); packet->chunkData.Read(updateBits);
@@ -586,8 +496,8 @@ void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, ChunkDat
{ {
recalcHeight = true; recalcHeight = true;
int colX = (i % LevelConstants::CHUNK_WIDTH); int colX = (i % CHUNK_WIDTH);
int colZ = (i / LevelConstants::CHUNK_WIDTH); int colZ = (i / CHUNK_WIDTH);
int colDataPosition = colX << 11 | colZ << 7; int colDataPosition = colX << 11 | colZ << 7;
for (int set = 0; set < 8; set++) for (int set = 0; set < 8; set++)
@@ -621,33 +531,30 @@ void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, ChunkDat
{ {
y0 = ((1 << set) << setShift); y0 = ((1 << set) << setShift);
} }
if (((1 << set) << setShift) + (LevelConstants::LEVEL_HEIGHT / 8) - 1 > y1) if (((1 << set) << setShift) + (LEVEL_HEIGHT / 8) - 1 > y1)
{ {
y1 = ((1 << set) << setShift) + (LevelConstants::LEVEL_HEIGHT / 8) - 1; y1 = ((1 << set) << setShift) + (LEVEL_HEIGHT / 8) - 1;
} }
} }
if ((i % LevelConstants::CHUNK_WIDTH) < x0) if ((i % CHUNK_WIDTH) < x0)
{ {
x0 = (i % LevelConstants::CHUNK_WIDTH); x0 = (i % CHUNK_WIDTH);
} }
if ((i % LevelConstants::CHUNK_WIDTH) > x1) if ((i % CHUNK_WIDTH) > x1)
{ {
x1 = (i % LevelConstants::CHUNK_WIDTH); x1 = (i % CHUNK_WIDTH);
} }
if ((i / LevelConstants::CHUNK_WIDTH) < z0) if ((i / CHUNK_WIDTH) < z0)
{ {
z0 = (i / LevelConstants::CHUNK_WIDTH); z0 = (i / CHUNK_WIDTH);
} }
if ((i / LevelConstants::CHUNK_WIDTH) > z1) if ((i / CHUNK_WIDTH) > z1)
{ {
z1 = (i / LevelConstants::CHUNK_WIDTH); z1 = (i / CHUNK_WIDTH);
} }
} }
} }
delete[] readBlockBuffer;
delete[] readDataBuffer;
if (recalcHeight) if (recalcHeight)
{ {
// chunk->recalcHeightmap(); // chunk->recalcHeightmap();
@@ -672,7 +579,7 @@ void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, ChunkDat
//chunk->terrainPopulated = true; //chunk->terrainPopulated = true;
chunk->unsaved = false; chunk->unsaved = false;
chunksLoaded[packet->x * LevelConstants::CHUNK_CACHE_WIDTH + packet->z] = true; chunksLoaded[packet->x * CHUNK_CACHE_WIDTH + packet->z] = true;
if (areAllChunksLoaded()) if (areAllChunksLoaded())
{ {
@@ -720,18 +627,18 @@ void ClientSideNetworkHandler::arrangeRequestChunkOrder() {
clearChunksLoaded(); clearChunksLoaded();
// Default sort is around center of the world // Default sort is around center of the world
int cx = LevelConstants::CHUNK_CACHE_WIDTH / 2; int cx = CHUNK_CACHE_WIDTH / 2;
int cz = LevelConstants::CHUNK_CACHE_WIDTH / 2; int cz = CHUNK_CACHE_WIDTH / 2;
// If player exists, let's sort around him // If player exists, let's sort around him
Player* p = minecraft? minecraft->player : NULL; Player* p = minecraft? minecraft->player : NULL;
if (p) { if (p) {
cx = Mth::floor(p->x / (float)LevelConstants::CHUNK_WIDTH); cx = Mth::floor(p->x / (float)CHUNK_WIDTH);
cz = Mth::floor(p->z / (float)LevelConstants::CHUNK_DEPTH); cz = Mth::floor(p->z / (float)CHUNK_DEPTH);
} }
_ChunkSorter sorter(cx, cz); _ChunkSorter sorter(cx, cz);
std::sort(requestNextChunkIndexList.begin(), requestNextChunkIndexList.end(), sorter); std::sort(requestNextChunkIndexList, requestNextChunkIndexList + NumRequestChunks, sorter);
} }
void ClientSideNetworkHandler::levelGenerated(Level* level) void ClientSideNetworkHandler::levelGenerated(Level* level)
@@ -821,7 +728,7 @@ void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, SetEntit
if (!level) if (!level)
return; return;
// LOGI("SetEntityDataPacket\n"); LOGI("SetEntityDataPacket\n");
Entity* e = level->getEntity(packet->id); Entity* e = level->getEntity(packet->id);
if (e) { if (e) {
@@ -875,10 +782,6 @@ void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, AnimateP
} }
} }
void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, WantCreatePacket* packet)
{
}
void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, UseItemPacket* packet) void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, UseItemPacket* packet)
{ {
} }
@@ -888,7 +791,6 @@ void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, SetHealt
if (!level || !minecraft->player) if (!level || !minecraft->player)
return; return;
printf("SetHealthPacket \n");
minecraft->player->hurtTo(packet->health); minecraft->player->hurtTo(packet->health);
} }
@@ -984,11 +886,7 @@ void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, Containe
void ClientSideNetworkHandler::handle( const RakNet::RakNetGUID& source, ChatPacket* packet ) void ClientSideNetworkHandler::handle( const RakNet::RakNetGUID& source, ChatPacket* packet )
{ {
#ifndef STANDALONE_SERVER #ifndef STANDALONE_SERVER
// minecraft->gui.displayClientMessage(packet->message); minecraft->gui.displayClientMessage(packet->message);
std::istringstream iss(packet->message);
for (std::string line; std::getline(iss, line); ) {
minecraft->gui.addMessage(line);
}
#endif #endif
} }
@@ -1021,8 +919,8 @@ void ClientSideNetworkHandler::clearChunksLoaded()
{ {
// Init the chunk positions // Init the chunk positions
for (int i = 0; i < NumRequestChunks; ++i) { for (int i = 0; i < NumRequestChunks; ++i) {
requestNextChunkIndexList[i].x = i / LevelConstants::CHUNK_WIDTH; requestNextChunkIndexList[i].x = i/CHUNK_WIDTH;
requestNextChunkIndexList[i].y = i % LevelConstants::CHUNK_WIDTH; requestNextChunkIndexList[i].y = i%CHUNK_WIDTH;
chunksLoaded[i] = false; chunksLoaded[i] = false;
} }
} }

View File

@@ -77,11 +77,6 @@ public:
virtual void handle(const RakNet::RakNetGUID& source, ChatPacket* packet); virtual void handle(const RakNet::RakNetGUID& source, ChatPacket* packet);
virtual void handle(const RakNet::RakNetGUID& source, AdventureSettingsPacket* packet); virtual void handle(const RakNet::RakNetGUID& source, AdventureSettingsPacket* packet);
virtual void handle(const RakNet::RakNetGUID& source, SignUpdatePacket* packet); virtual void handle(const RakNet::RakNetGUID& source, SignUpdatePacket* packet);
virtual void handle(const RakNet::RakNetGUID& source, RemoveItemPacket* packet);
virtual void handle(const RakNet::RakNetGUID& source, TakeItemPacket* packet);
virtual void handle(const RakNet::RakNetGUID& source, WantCreatePacket* packet);
virtual void handle(const RakNet::RakNetGUID& source, SendInventoryPacket* packet);
private: private:
void requestNextChunk(); void requestNextChunk();
@@ -102,11 +97,11 @@ private:
BlockUpdateList bufferedBlockUpdates; BlockUpdateList bufferedBlockUpdates;
int requestNextChunkPosition; int requestNextChunkPosition;
int NumRequestChunks; static const int NumRequestChunks = CHUNK_CACHE_WIDTH * CHUNK_CACHE_WIDTH;
int requestNextChunkIndex; int requestNextChunkIndex;
std::vector<IntPair> requestNextChunkIndexList; IntPair requestNextChunkIndexList[NumRequestChunks];
std::vector<bool> chunksLoaded; bool chunksLoaded[NumRequestChunks];
}; };
#endif #endif

33
src/network/NATPunchHandler.cpp Executable file
View File

@@ -0,0 +1,33 @@
#include "NATPunchHandler.h"
#include "../raknet/TCPInterface.h"
#include "../raknet/HTTPConnection.h"
#include "PHPDirectoryServer2.h"
using namespace RakNet;
NATPuchHandler::NATPuchHandler() {
tcpInterface = new TCPInterface;
}
NATPuchHandler::~NATPuchHandler() {
delete tcpInterface;
}
void NATPuchHandler::initialize() {
tcpInterface->Start(0, 64);
}
void NATPuchHandler::registerToGameList(const RakNet::RakString& serverName, int port) {
HTTPConnection httpConnection;
httpConnection.Init(tcpInterface, "johanbernhardsson.se");
PHPDirectoryServer2 directoryServer;
directoryServer.Init(&httpConnection, "/DirectoryServer.php");
directoryServer.UploadTable("", serverName, port, true);
}
void NATPuchHandler::removeFromGameList() {
}
void NATPuchHandler::close() {
}

24
src/network/NATPunchHandler.h Executable file
View File

@@ -0,0 +1,24 @@
#ifndef _MINECRAFT_NETWORK_NATPUNCHHANDLER_H_
#define _MINECRAFT_NETWORK_NATPUNCHHANDLER_H_
#include "../raknet/TCPInterface.h"
#include "../raknet/RakString.h"
class NATPuchHandler {
public:
enum NATPuchHandlerStatus {
NATPuchInitilized = 0,
NATPuchFetchingServerList = 1,
NATPuchConnecting = 2,
NATPuchConnected = 3,
NATPuchDissconnected = 4
};
NATPuchHandler();
~NATPuchHandler();
void initialize();
void registerToGameList(const RakNet::RakString& serverName, int port);
void removeFromGameList();
void close();
private:
RakNet::TCPInterface *tcpInterface;
};
#endif /* _MINECRAFT_NETWORK_NATPUNCHHANDLER_H_ */

View File

@@ -18,8 +18,6 @@ class RemovePlayerPacket;
class RemoveEntityPacket; class RemoveEntityPacket;
class MoveEntityPacket; class MoveEntityPacket;
//class TeleportEntityPacket; //class TeleportEntityPacket;
class RemoveItemPacket;
class TakeItemPacket;
class MovePlayerPacket; class MovePlayerPacket;
class PlaceBlockPacket; class PlaceBlockPacket;
class RemoveBlockPacket; class RemoveBlockPacket;
@@ -50,7 +48,6 @@ class ContainerClosePacket;
class ContainerSetSlotPacket; class ContainerSetSlotPacket;
class ContainerSetDataPacket; class ContainerSetDataPacket;
class ContainerSetContentPacket; class ContainerSetContentPacket;
class WantCreatePacket;
class ChatPacket; class ChatPacket;
class SignUpdatePacket; class SignUpdatePacket;
class Minecraft; class Minecraft;
@@ -122,9 +119,6 @@ public:
virtual void handle(const RakNet::RakNetGUID& source, SignUpdatePacket* packet) {} virtual void handle(const RakNet::RakNetGUID& source, SignUpdatePacket* packet) {}
virtual void handle(const RakNet::RakNetGUID& source, AdventureSettingsPacket* packet) {} virtual void handle(const RakNet::RakNetGUID& source, AdventureSettingsPacket* packet) {}
virtual void handle(const RakNet::RakNetGUID& source, AnimatePacket* packet) {} virtual void handle(const RakNet::RakNetGUID& source, AnimatePacket* packet) {}
virtual void handle(const RakNet::RakNetGUID& source, RemoveItemPacket* packet) {}
virtual void handle(const RakNet::RakNetGUID& source, TakeItemPacket* packet) {}
virtual void handle(const RakNet::RakNetGUID& source, WantCreatePacket* packet) {}
// //
// Common implementation for Client and Server // Common implementation for Client and Server

View File

@@ -2,7 +2,6 @@
#include "Packet.h" #include "Packet.h"
#include "../world/level/chunk/LevelChunk.h" #include "../world/level/chunk/LevelChunk.h"
#include "network/packet/TakeItemPacket.h"
#include "packet/PacketInclude.h" #include "packet/PacketInclude.h"
Packet::Packet() Packet::Packet()
@@ -42,12 +41,6 @@ Packet* MinecraftPackets::createPacket(int id)
case PACKET_ADDITEMENTITY: case PACKET_ADDITEMENTITY:
packet = new AddItemEntityPacket(); packet = new AddItemEntityPacket();
break; break;
case PACKET_REMOVEITEM:
packet = new RemoveItemPacket();
break;
case PACKET_TAKEITEM:
packet = new TakeItemPacket();
break;
case PACKET_TAKEITEMENTITY: case PACKET_TAKEITEMENTITY:
packet = new TakeItemEntityPacket(); packet = new TakeItemEntityPacket();
break; break;
@@ -75,9 +68,6 @@ Packet* MinecraftPackets::createPacket(int id)
case PACKET_RESPAWN: case PACKET_RESPAWN:
packet = new RespawnPacket(); packet = new RespawnPacket();
break; break;
case PACKET_WANTCREATEITEM:
packet = new WantCreatePacket();
break;
case PACKET_REMOVEENTITY: case PACKET_REMOVEENTITY:
packet = new RemoveEntityPacket(); packet = new RemoveEntityPacket();
break; break;

View File

@@ -33,9 +33,6 @@ enum MinecraftPacketIds
PACKET_REMOVEENTITY, PACKET_REMOVEENTITY,
PACKET_ADDITEMENTITY, PACKET_ADDITEMENTITY,
PACKET_TAKEITEMENTITY, PACKET_TAKEITEMENTITY,
PACKET_TAKEITEM,
PACKET_REMOVEITEM,
PACKET_WANTCREATEITEM,
PACKET_MOVEENTITY, PACKET_MOVEENTITY,
PACKET_MOVEENTITY_POS, PACKET_MOVEENTITY_POS,

View File

@@ -173,7 +173,6 @@ bool RakNetInstance::isMyLocalGuid(const RakNet::RakNetGUID& guid)
void RakNetInstance::runEvents(NetEventCallback* callback) void RakNetInstance::runEvents(NetEventCallback* callback)
{ {
RakNet::Packet* currentEvent; RakNet::Packet* currentEvent;
bool disconnect = false;
while ((currentEvent = rakPeer->Receive()) != NULL) while ((currentEvent = rakPeer->Receive()) != NULL)
{ {
@@ -201,7 +200,6 @@ void RakNetInstance::runEvents(NetEventCallback* callback)
case ID_DISCONNECTION_NOTIFICATION: case ID_DISCONNECTION_NOTIFICATION:
case ID_CONNECTION_LOST: case ID_CONNECTION_LOST:
callback->onDisconnect(currentEvent->guid); callback->onDisconnect(currentEvent->guid);
disconnect = true;
break; break;
case ID_UNCONNECTED_PONG: case ID_UNCONNECTED_PONG:
{ {
@@ -235,9 +233,8 @@ void RakNetInstance::runEvents(NetEventCallback* callback)
} }
} }
} }
if (!disconnect) {
rakPeer->DeallocatePacket(currentEvent); rakPeer->DeallocatePacket(currentEvent);
}
//delete activeBitStream; //delete activeBitStream;
} }

View File

@@ -5,16 +5,6 @@
#include "../world/entity/player/Inventory.h" #include "../world/entity/player/Inventory.h"
#include "../world/Container.h" #include "../world/Container.h"
#include "../world/inventory/BaseContainerMenu.h" #include "../world/inventory/BaseContainerMenu.h"
#include "network/packet/ChatPacket.h"
#include "network/packet/ContainerSetSlotPacket.h"
#include "network/packet/LoginStatusPacket.h"
#include "network/packet/MovePlayerPacket.h"
#include "network/packet/RemoveBlockPacket.h"
#include "network/packet/SendInventoryPacket.h"
#include "network/packet/UpdateBlockPacket.h"
#include "network/packet/RemoveItemPacket.h"
#include "network/packet/TakeItemPacket.h"
#include "network/packet/WantCreatePacket.h"
#include "packet/PacketInclude.h" #include "packet/PacketInclude.h"
#include "RakNetInstance.h" #include "RakNetInstance.h"
@@ -23,24 +13,11 @@
#include "../client/gamemode/GameMode.h" #include "../client/gamemode/GameMode.h"
#include "../raknet/RakPeerInterface.h" #include "../raknet/RakPeerInterface.h"
#include "../raknet/PacketPriority.h" #include "../raknet/PacketPriority.h"
#include "platform/log.h"
#include "util/Mth.h"
#include "util/StringUtils.h"
#include "world/item/ItemInstance.h"
#include "world/level/LevelConstants.h"
#include "world/level/storage/LevelStorage.h"
#include "world/phys/Vec3.h"
#include "world/item/crafting/Recipe.h"
#include "world/item/crafting/Recipes.h"
#include <cstddef>
#include <cstdio>
#ifndef STANDALONE_SERVER #ifndef STANDALONE_SERVER
#include "../client/sound/SoundEngine.h" #include "../client/sound/SoundEngine.h"
#endif #endif
#include "../server/ServerPlayer.h" #include "../server/ServerPlayer.h"
#include "../world/entity/item/FallingTile.h" #include "../world/entity/item/FallingTile.h"
#include <plugins/LuaPlayer.hpp>
#include <plugins/MessageEvent.hpp>
#define TIMES(x) for(int itc ## __LINE__ = 0; itc ## __LINE__ < x; ++ itc ## __LINE__) #define TIMES(x) for(int itc ## __LINE__ = 0; itc ## __LINE__ < x; ++ itc ## __LINE__)
@@ -76,11 +53,11 @@ void ServerSideNetworkHandler::tileChanged(int x, int y, int z)
Packet* ServerSideNetworkHandler::getAddPacketFromEntity( Entity* entity ) { Packet* ServerSideNetworkHandler::getAddPacketFromEntity( Entity* entity ) {
if (entity->isMob() && !entity->isPlayer()) { //@fix: This code is duplicated. See if it can be unified. if (entity->isMob() && !entity->isPlayer()) { //@fix: This code is duplicated. See if it can be unified.
// if (minecraft->player) { if (minecraft->player) {
// I guess this should always be true, but it crashed somewhere in this // I guess this should always be true, but it crashed somewhere in this
// function once and I only see this one as a potential problem // function once and I only see this one as a potential problem
return new AddMobPacket((Mob*)entity); return new AddMobPacket((Mob*)entity);
// } }
} }
else if (entity->isPlayer()) { else if (entity->isPlayer()) {
@@ -157,62 +134,9 @@ void ServerSideNetworkHandler::displayGameMessage(const std::string& message)
raknetInstance->send(packet); raknetInstance->send(packet);
} }
void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, MessagePacket* packet)
{
auto player = getPlayer(source);
if (player == nullptr) return; // @todo maybe kick?
auto msg = std::string(packet->message.C_String());
MessageEvent event;
event.m_decline = false;
PluginsManager::get().emit("Message", LuaPlayer(source), msg, event);
if (!event.m_decline) {
if (packet->message[0] == '/') {
// This is a command
auto cmd = Util::stringTrim(msg.substr(1));
if (PluginsManager::get().emitCommands(cmd, source)) {
ChatPacket resp(minecraft->commandManager().execute(*minecraft, *player, cmd));
return sendPrivate(resp, source);
} else {
return;
}
}
displayGameMessage("<" + player->name + "> " + msg);
}
}
void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, ChatPacket* packet) void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, ChatPacket* packet)
{ {
auto player = getPlayer(source); displayGameMessage(packet->message);
if (player == nullptr) return; // @todo maybe kick?
MessageEvent event;
event.m_decline = false;
PluginsManager::get().emit("Message", LuaPlayer(source), packet->message, event);
if (!event.m_decline) {
if (packet->message[0] == '/') {
// This is a command
auto cmd = Util::stringTrim(packet->message.substr(1));
if (PluginsManager::get().emitCommands(cmd, source)) {
ChatPacket resp(minecraft->commandManager().execute(*minecraft, *player, cmd));
return sendPrivate(resp, source);
} else {
return;
}
}
displayGameMessage("<" + player->name + "> " + packet->message);
}
} }
void ServerSideNetworkHandler::onNewClient(const RakNet::RakNetGUID& clientGuid) void ServerSideNetworkHandler::onNewClient(const RakNet::RakNetGUID& clientGuid)
@@ -232,9 +156,6 @@ void ServerSideNetworkHandler::onDisconnect(const RakNet::RakNetGUID& guid)
if (player->owner == guid) if (player->owner == guid)
{ {
PluginsManager::get().emit("PlayerDisconnect", LuaPlayer(guid));
minecraft->level->getLevelStorage()->savePlayer(*player);
std::string message = player->name; std::string message = player->name;
message += " disconnected from the game"; message += " disconnected from the game";
displayGameMessage(message); displayGameMessage(message);
@@ -265,42 +186,8 @@ void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, LoginPac
// //
bool oldClient = packet->clientNetworkVersion < SharedConstants::NetworkProtocolLowestSupportedVersion; bool oldClient = packet->clientNetworkVersion < SharedConstants::NetworkProtocolLowestSupportedVersion;
bool oldServer = packet->clientNetworkLowestSupportedVersion > SharedConstants::NetworkProtocolVersion; bool oldServer = packet->clientNetworkLowestSupportedVersion > SharedConstants::NetworkProtocolVersion;
if (oldClient || oldServer || !packet->newProto) if (oldClient || oldServer)
loginStatus = oldClient || !packet->newProto? LoginStatus::Failed_ClientOld : LoginStatus::Failed_ServerOld; loginStatus = oldClient? LoginStatus::Failed_ClientOld : LoginStatus::Failed_ServerOld;
std::string nicknameLower = packet->clientName.C_String();
std::transform(nicknameLower.begin(), nicknameLower.end(), nicknameLower.begin(), ::tolower);
RakNet::SystemAddress sysAddress = rakPeer->GetSystemAddressFromGuid(source);
char clientIp[32];
sysAddress.ToString(false, clientIp);
for (int i = 0; i < level->players.size(); i++) {
ServerPlayer* player = (ServerPlayer*) level->players.at(i);
std::string clientLower = player->name;
std::transform(clientLower.begin(), clientLower.end(), clientLower.begin(), ::tolower);
// @todo to lower case
if (nicknameLower == clientLower) {
loginStatus = packet->newProto ? LoginStatus::Failed_TakenNickname : LoginStatus::Failed_ClientOld;
break;
}
}
for (auto& banned : level->bannedPpl) {
if (nicknameLower == banned) {
loginStatus = packet->newProto ? LoginStatus::Failed_Banned : LoginStatus::Failed_ClientOld;
break;
}
}
for (auto& banned : level->bannedIps) {
if (clientIp == banned) {
loginStatus = packet->newProto ? LoginStatus::Failed_Banned : LoginStatus::Failed_ClientOld;
break;
}
}
RakNet::BitStream bitStream; RakNet::BitStream bitStream;
LoginStatusPacket(loginStatus).write(&bitStream); LoginStatusPacket(loginStatus).write(&bitStream);
@@ -312,16 +199,13 @@ void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, LoginPac
// //
// Valid client version // Valid client version
// //
Player* newPlayer = new ServerPlayer(minecraft, level);
Player* newPlayer = new ServerPlayer(minecraft, level, packet->newProto);
minecraft->gameMode->initAbilities(newPlayer->abilities); minecraft->gameMode->initAbilities(newPlayer->abilities);
newPlayer->owner = source; newPlayer->owner = source;
newPlayer->name = packet->clientName.C_String(); newPlayer->name = packet->clientName.C_String();
_pendingPlayers.push_back(newPlayer); _pendingPlayers.push_back(newPlayer);
LOGI("Adding new player... isCreative: %i\n", minecraft->isCreativeMode());
// Reset the player so he doesn't spawn inside blocks // Reset the player so he doesn't spawn inside blocks
while (newPlayer->y > 0) { while (newPlayer->y > 0) {
newPlayer->setPos(newPlayer->x, newPlayer->y, newPlayer->z); newPlayer->setPos(newPlayer->x, newPlayer->y, newPlayer->z);
@@ -344,8 +228,7 @@ void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, LoginPac
level->getLevelData()->getGeneratorVersion(), level->getLevelData()->getGeneratorVersion(),
gameType, gameType,
newPlayer->entityId, newPlayer->entityId,
newPlayer->x, newPlayer->y - newPlayer->heightOffset, newPlayer->z, newPlayer->x, newPlayer->y - newPlayer->heightOffset, newPlayer->z
LevelConstants::CHUNK_CACHE_WIDTH
).write(&bitStream); ).write(&bitStream);
rakPeer->Send(&bitStream, HIGH_PRIORITY, RELIABLE_ORDERED, 0, source, false); rakPeer->Send(&bitStream, HIGH_PRIORITY, RELIABLE_ORDERED, 0, source, false);
@@ -405,6 +288,7 @@ void ServerSideNetworkHandler::onReady_ClientGeneration(const RakNet::RakNetGUID
#else #else
LOGW("%s joined the game\n", newPlayer->name.c_str()); LOGW("%s joined the game\n", newPlayer->name.c_str());
#endif #endif
// Send all Entities to the new player // Send all Entities to the new player
for (unsigned int i = 0; i < level->entities.size(); ++i) { for (unsigned int i = 0; i < level->entities.size(); ++i) {
Entity* e = level->entities[i]; Entity* e = level->entities[i];
@@ -417,36 +301,6 @@ void ServerSideNetworkHandler::onReady_ClientGeneration(const RakNet::RakNetGUID
} }
} }
if (!minecraft->level->getLevelStorage()->loadPlayer(*newPlayer)) {
LOGW("Failed to load %s data\n", newPlayer->name.c_str());
}
// Credits to EpikIzCool
bitStream.Reset();
MovePlayerPacket mv(newPlayer->entityId, newPlayer->x, newPlayer->y - newPlayer->heightOffset,
newPlayer->z, newPlayer->xRot, newPlayer->yRot);
mv.write(&bitStream);
rakPeer->Send(&bitStream, HIGH_PRIORITY, RELIABLE_ORDERED, 0, source, false);
bitStream.Reset();
SetHealthPacket hp(newPlayer->health);
hp.write(&bitStream);
rakPeer->Send(&bitStream, HIGH_PRIORITY, RELIABLE_ORDERED, 0, source, false);
if (newPlayer->hasRespawnPosition()) {
bitStream.Reset();
SetSpawnPositionPacket sp(newPlayer->getRespawnPosition());
sp.write(&bitStream);
rakPeer->Send(&bitStream, HIGH_PRIORITY, RELIABLE_ORDERED, 0, source, false);
}
bitStream.Reset();
SendInventoryPacket(newPlayer, false).write(&bitStream);
rakPeer->Send(&bitStream, HIGH_PRIORITY, RELIABLE_ORDERED, 0, source, false);
// Additional packets // Additional packets
// * set spawn // * set spawn
/* /*
@@ -460,8 +314,6 @@ void ServerSideNetworkHandler::onReady_ClientGeneration(const RakNet::RakNetGUID
bitStream.Reset(); bitStream.Reset();
AddPlayerPacket(newPlayer).write(&bitStream); AddPlayerPacket(newPlayer).write(&bitStream);
rakPeer->Send(&bitStream, HIGH_PRIORITY, RELIABLE_ORDERED, 0, source, true); rakPeer->Send(&bitStream, HIGH_PRIORITY, RELIABLE_ORDERED, 0, source, true);
PluginsManager::get().emit("PlayerJoin", LuaPlayer(source));
} }
// //
@@ -487,32 +339,9 @@ void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, MovePlay
{ {
if (!level) return; if (!level) return;
// LOGI("MovePlayerPacket\n"); //LOGI("MovePlayerPacket\n");
if (Entity* entity = level->getEntity(packet->entityId)) { if (Entity* entity = level->getEntity(packet->entityId))
ServerPlayer* player = (ServerPlayer*) getPlayer(source); {
// int timeElapsed = minecraft->getTicks() - player->getLastMoveTicks();
// if (timeElapsed > 0) {
// float dist = player->distanceTo(packet->x, player->y, packet->z);
// float speed = dist / (minecraft->getTicks() - player->getLastMoveTicks());
// player->setLastMoveTicks(minecraft->getTicks());
// float maxSpeed = (minecraft->isCreativeMode()) ? 1.65f : 1.f;
// if (speed > maxSpeed) {
// MovePlayerPacket refuse(player->entityId, player->x, player->y, player->z, player->xRot, player->yRot);
// return raknetInstance->send(refuse);
// }
// }
PluginsManager::get().emit(
"PlayerMovement",
LuaPlayer(source),
packet->x, packet->y, packet->z, packet->yRot, packet->xRot, // newPos
player->x, player->y, player->z, player->yRot, player->xRot // oldPos
);
entity->xd = entity->yd = entity->zd = 0; entity->xd = entity->yd = entity->zd = 0;
entity->lerpTo(packet->x, packet->y, packet->z, packet->yRot, packet->xRot, 3); entity->lerpTo(packet->x, packet->y, packet->z, packet->yRot, packet->xRot, 3);
@@ -521,7 +350,7 @@ void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, MovePlay
} }
} }
void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, RemoveBlockPacket* packet) { void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, RemoveBlockPacket* packet){
if (!level) return; if (!level) return;
Player* player = getPlayer(source); Player* player = getPlayer(source);
@@ -539,31 +368,12 @@ void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, RemoveBl
if (oldTile != NULL && changed) { if (oldTile != NULL && changed) {
level->playSound(x + 0.5f, y + 0.5f, z + 0.5f, oldTile->soundType->getBreakSound(), (oldTile->soundType->getVolume() + 1) / 2, oldTile->soundType->getPitch() * 0.8f); level->playSound(x + 0.5f, y + 0.5f, z + 0.5f, oldTile->soundType->getBreakSound(), (oldTile->soundType->getVolume() + 1) / 2, oldTile->soundType->getPitch() * 0.8f);
if (minecraft->gameMode->isSurvivalType() && player->canDestroy(oldTile)) { if (minecraft->gameMode->isSurvivalType() && player->canDestroy(oldTile))
// From SurvivalMode.cpp //oldTile->spawnResources(level, x, y, z, data, 1); //@todo
// Why tf i have to copy this shit from SurvivalMode class
// Why SurvivalMode class locked to LOCAL MINECRAFT PLAYER :sob: :sob: :sob: :sob: :sob: :sob: :sob: :sob:
// @fix @warn @ahtung @alert
ItemInstance* item = player->inventory->getSelected();
if (item != NULL) {
item->mineBlock(oldTile->id, x, y, z);
if (item->count == 0) {
//item->snap(minecraft->player);
player->inventory->clearSlot(player->inventory->selected);
}
}
// oldTile->spawnResources(level, x, y, z, data, 1); //@todo
oldTile->playerDestroy(level, player, x, y, z, data); oldTile->playerDestroy(level, player, x, y, z, data);
}
oldTile->destroy(level, x, y, z, data); oldTile->destroy(level, x, y, z, data);
// RemoveEntityPacket packet(e->entityId);
// redistributePacket(&packet, rakPeer->GetMyGUID());
} }
LOGI("Remove block [%i, %i, %i]\n", packet->x, packet->y, packet->z);
} }
void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, RequestChunkPacket* packet) void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, RequestChunkPacket* packet)
@@ -593,8 +403,6 @@ void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, RequestC
raknetInstance->send(source, p); raknetInstance->send(source, p);
} }
} }
// LOGI("Requested chunk [%i, %i]\n", packet->x, packet->z);
} }
void ServerSideNetworkHandler::levelGenerated( Level* level ) void ServerSideNetworkHandler::levelGenerated( Level* level )
@@ -621,31 +429,23 @@ void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, PlayerEq
if (!player) return; if (!player) return;
if (rakPeer->GetMyGUID() == player->owner) return; if (rakPeer->GetMyGUID() == player->owner) return;
LOGI("Equip item: id %i aux %i\n", packet->itemId, packet->itemAuxValue);
// override the player's inventory // override the player's inventory
int slot = player->inventory->getSlot(packet->itemId, packet->itemAuxValue); //int slot = player->inventory->getSlot(packet->itemId, packet->itemAuxValue);
int slot = Inventory::MAX_SELECTION_SIZE;
if (slot >= 0 && slot != packet->inventorySlot && packet->itemId != 0) { if (slot >= 0) {
LOGW("PlayerEquipmentPacket: Item in player inventory but slots doesn't match!"); if (packet->itemId == 0) {
packet->inventorySlot = slot; player->inventory->clearSlot(slot);
} else {
// @note: 128 is an ugly hack for depletable items.
// @todo: fix
ItemInstance newItem(packet->itemId, 128, packet->itemAuxValue);
player->inventory->replaceSlot(slot, &newItem);
} }
player->inventory->moveToSelectedSlot(slot, true);
if (slot < 0 && packet->itemId != 0) {
LOGW("PlayerEquipmentPacket: Remote player doesn't have his thing (or crafted it)!\n");
SendInventoryPacket newInventory (player, false);
raknetInstance->send(newInventory);
return;
}
player->inventory->selectSlot(packet->selectedSlot);
player->inventory->linkSlot(packet->selectedSlot, packet->inventorySlot, true);
player->inventory->print();
redistributePacket(packet, source); redistributePacket(packet, source);
} else {
LOGW("Warning: Remote player doesn't have his thing, Odd!\n");
}
} }
void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, PlayerArmorEquipmentPacket* packet) { void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, PlayerArmorEquipmentPacket* packet) {
@@ -655,8 +455,6 @@ void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, PlayerAr
if (!player) return; if (!player) return;
if (rakPeer->GetMyGUID() == player->owner) return; if (rakPeer->GetMyGUID() == player->owner) return;
// LOGI("Equip armor: %i %i %i %i\n", packet->head, packet->torso, packet->legs, packet->feet);
packet->fillIn(player); packet->fillIn(player);
redistributePacket(packet, source); redistributePacket(packet, source);
} }
@@ -668,8 +466,6 @@ void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, Interact
Entity* entity = level->getEntity(packet->targetId); Entity* entity = level->getEntity(packet->targetId);
if (src && entity && src->isPlayer()) if (src && entity && src->isPlayer())
{ {
LOGI("Interact: source %i target %i\n", packet->sourceId, packet->targetId);
Player* player = (Player*) src; Player* player = (Player*) src;
if (InteractPacket::Attack == packet->action) { if (InteractPacket::Attack == packet->action) {
player->swing(); player->swing();
@@ -710,75 +506,14 @@ void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, AnimateP
} }
redistributePacket(packet, source); redistributePacket(packet, source);
} }
void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, WantCreatePacket* packet) {
LOGI("WantCreatePacket\n");
Entity* entity = level->getEntity(packet->playerId);
if (entity && entity->isPlayer()) {
Player* p = (Player*)entity;
auto playerInv = p->inventory;
ItemInstance wantCreate;
wantCreate.id = packet->itemId;
wantCreate.count = packet->count;
wantCreate.setAuxValue(packet->auxValue);
Recipe* recipe = Recipes::getInstance()->getRecipeFor(wantCreate);
std::vector<ItemInstance> items = recipe->getItemPack().getItemInstances();
std::vector<int> checkForExists = {};
for (int i = Inventory::MAX_SELECTION_SIZE; i < p->inventory->getContainerSize(); ++i) {
auto itm = p->inventory->getItem(i);
if (itm != NULL) {
for (int y = 0; y < items.size(); y++) {
auto itmRecipe = items.at(y);
if (itmRecipe.id == itm->id && itm->count >= itmRecipe.count) {
checkForExists.push_back(itm->id);
}
}
}
}
if (checkForExists.empty()) {
return;
}
for (int i = 0; i < items.size(); i++) {
auto item = items.at(i);
auto it = std::find(checkForExists.begin(), checkForExists.end(), item.id);
if (it == checkForExists.end() && checkForExists.size() > 1) {
return;
}
}
for (int i = 0; i < items.size(); i++) {
p->inventory->removeResource(ItemInstance(items.at(i).id, items.at(i).count, items.at(i).getAuxValue()));
}
// TakeItemPacket itemAdd(p->entityId, wantCreate.count, wantCreate.getAuxValue(), wantCreate.id);
// raknetInstance->send(source, itemAdd);
p->inventory->add(new ItemInstance(wantCreate.id, wantCreate.count, wantCreate.getAuxValue()));
}
}
void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, UseItemPacket* packet) void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, UseItemPacket* packet)
{ {
if (!level) return; if (!level) return;
LOGI("UseItemPacket: id %i data %i\n", packet->itemId, packet->itemData); LOGI("UseItemPacket\n");
Entity* entity = level->getEntity(packet->entityId); Entity* entity = level->getEntity(packet->entityId);
if (entity && entity->isPlayer()) { if (entity && entity->isPlayer()) {
LOGI("%f %f %f \n", entity->x, entity->y, entity->z);
Player* player = (Player*) entity; Player* player = (Player*) entity;
int x = packet->x, y = packet->y, z = packet->z; int x = packet->x, y = packet->y, z = packet->z;
Tile* t = Tile::tiles[level->getTile(x, y, z)]; Tile* t = Tile::tiles[level->getTile(x, y, z)];
@@ -787,41 +522,7 @@ void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, UseItemP
if (t && t->use(level, x, y, z, player)) return; if (t && t->use(level, x, y, z, player)) return;
if (packet->item.isNull()) return; if (packet->item.isNull()) return;
ItemInstance* packetItem = &packet->item; ItemInstance* item = &packet->item;
int slot = player->inventory->getSlot(packet->itemId, packet->itemData);
if (slot < 0) {
LOGW("UseItemPacket: Player doesn't have this item!\n");
auto pos = Vec3(packet->x, packet->y, packet->z);
if (ItemInstance::isBlock(packetItem)) {
LOGI("UseItemPacket: This is even block!!!\n");
pos.x += packet->clickX;
pos.y += packet->clickY;
pos.z += packet->clickZ;
}
UpdateBlockPacket refuse(pos.x, pos.y, pos.z, level->getTile(pos.x, pos.y, pos.z), level->getData(pos.x, pos.y, pos.z));
raknetInstance->send(refuse);
return;
}
ItemInstance* item = player->inventory->getItem(slot);
player->x = packet->playerX;
player->y = packet->playerY;
player->z = packet->playerZ;
player->bb.x0 = packet->playerX0;
player->bb.y0 = packet->playerY0;
player->bb.z0 = packet->playerZ0;
player->bb.x1 = packet->playerX1;
player->bb.y1 = packet->playerY1;
player->bb.z1 = packet->playerZ1;
if(packet->face == 255) { if(packet->face == 255) {
// Special case: x,y,z means direction-of-action // Special case: x,y,z means direction-of-action
@@ -833,10 +534,6 @@ void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, UseItemP
Vec3(packet->clickX + packet->x, packet->clickY + packet->y, packet->clickZ + packet->z)); Vec3(packet->clickX + packet->x, packet->clickY + packet->y, packet->clickZ + packet->z));
} }
if (item && item->count <= 0) {
player->inventory->clearSlot(slot);
}
//LOGW("Use Item not working! Out of synch?\n"); //LOGW("Use Item not working! Out of synch?\n");
// Don't have to redistribute (ugg.. this will mess up), cause tileUpdated is sent // Don't have to redistribute (ugg.. this will mess up), cause tileUpdated is sent
@@ -847,8 +544,6 @@ void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, UseItemP
void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, EntityEventPacket* packet) { void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, EntityEventPacket* packet) {
if (!level) return; if (!level) return;
LOGI("EntityEventPacket: id %i\n", packet->eventId);
if (Entity* e = level->getEntity(packet->entityId)) if (Entity* e = level->getEntity(packet->entityId))
e->handleEntityEvent(packet->eventId); e->handleEntityEvent(packet->eventId);
} }
@@ -882,11 +577,6 @@ void ServerSideNetworkHandler::handle( const RakNet::RakNetGUID& source, SendInv
{ {
if (!level) return; if (!level) return;
LOGI("SendInventoryPacket:\n");
for (int i = 0; i < packet->numItems; i++) {
LOGI("\t %i: %s (%i)\n", i, packet->items.at(i).getName().c_str(), packet->items.at(i).count);
}
Entity* entity = level->getEntity(packet->entityId); Entity* entity = level->getEntity(packet->entityId);
if (entity && entity->isPlayer()) { if (entity && entity->isPlayer()) {
Player* p = (Player*)entity; Player* p = (Player*)entity;
@@ -902,27 +592,15 @@ void ServerSideNetworkHandler::handle( const RakNet::RakNetGUID& source, DropIte
{ {
if (!level) return; if (!level) return;
LOGI("DropItemPacket\n");
Entity* entity = level->getEntity(packet->entityId); Entity* entity = level->getEntity(packet->entityId);
if (entity && entity->isPlayer()) { if (entity && entity->isPlayer()) {
Player* p = (Player*)entity; Player* p = (Player*)entity;
// p->drop(new ItemInstance(packet->item), packet->dropType != 0); p->drop(new ItemInstance(packet->item), packet->dropType != 0);
int slot = p->inventory->getSlot(packet->item.id, packet->item.getAuxValue());
if (slot < 0) {
LOGW("DropItemPacket: player doesn't have these items!\n");
return;
}
p->inventory->dropSlot(slot, false, packet->dropType != 0);
} }
} }
void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, ContainerClosePacket* packet) { void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, ContainerClosePacket* packet) {
if (!level) return; if (!level) return;
LOGI("ContainerClosePacket\n");
Player* p = findPlayer(level, &source); Player* p = findPlayer(level, &source);
if (!p) return; if (!p) return;
@@ -934,16 +612,6 @@ void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, Containe
void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, ContainerSetSlotPacket* packet) { void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, ContainerSetSlotPacket* packet) {
if (!level) return; if (!level) return;
const char* type = "unknown";
switch (packet->setType) {
case ContainerSetSlotPacket::SETTYPE_ADD: type = "add"; break;
case ContainerSetSlotPacket::SETTYPE_SET: type = "set"; break;
case ContainerSetSlotPacket::SETTYPE_TAKE: type = "take"; break;
};
LOGI("ContainerSetSlot: slot %i item %s type %s\n", packet->slot, packet->item.getName().c_str(), type);
Player* p = findPlayer(level, &source); Player* p = findPlayer(level, &source);
if (!p) return; if (!p) return;
@@ -951,80 +619,12 @@ void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, Containe
LOGW("User has no container!\n"); LOGW("User has no container!\n");
return; return;
} }
if (p->containerMenu->containerId != packet->containerId)
if (p->containerMenu->containerId != packet->containerId) { {
LOGW("Wrong container id: %d vs %d\n", p->containerMenu->containerId, packet->containerId); LOGW("Wrong container id: %d vs %d\n", p->containerMenu->containerId, packet->containerId);
return; return;
} }
if (packet->item.count > 64) {
LOGW("ContainerSetSlotPacket: player tried to put more than 64");
return;
}
auto contItems = p->containerMenu->getItems();
// find same item in player inventory (used not in all cases)
int invSlot = p->inventory->getSlot(packet->item.id, packet->item.getAuxValue());
auto invItem = p->inventory->getItem(invSlot);
if (contItems.at(packet->slot).id == 0 && packet->item.id != 0) {
LOGI("ContainerSetSlotPacket: player tried to put items to slot %i\n", packet->slot);
if (invSlot < 0) {
LOGW("ContainerSetSlotPacket: player doesn't have this item\n");
return;
}
if (invItem->count < packet->item.count) {
LOGW("ContainerSetSlotPacket: player tried to put more than he have\n");
packet->item.count = invItem->count;
}
invItem->count -= packet->item.count;
if (invItem->count <= 0) {
p->inventory->removeItem(invItem);
}
} else if(contItems.at(packet->slot).id == packet->item.id) {
int deltaItem = packet->item.count - contItems.at(packet->slot).count;
if (deltaItem > 0) {
LOGI("ContainerSetSlotPacket: player tried to add %i items to slot %i\n", deltaItem, packet->slot);
auto invItem = p->inventory->getItem(invSlot);
if (invSlot < 0) {
LOGW("ContainerSetSlotPacket: player doesn't have this item\n");
return;
}
if (invItem->count < deltaItem) {
LOGW("ContainerSetSlotPacket: player tried to put more than he have");
packet->item.count -= (deltaItem - invItem->count);
deltaItem = invItem->count;
}
invItem->count -= deltaItem;
if (invItem->count <= 0) {
p->inventory->removeItem(invItem);
}
} else if (deltaItem < 0) {
LOGW("ContainerSetSlotPacket: player tried to take %i items from slot %i\n", -deltaItem, packet->slot);
p->inventory->add(new ItemInstance(packet->item.getItem(), -deltaItem, contItems.at(packet->slot).getAuxValue()));
}
} else if(contItems.at(packet->slot).id && !packet->item.id) {
LOGI("ContainerSetSlotPacket: player tried to take all items from slot %i\n", packet->slot);
packet->item.count = 0;
packet->item.setAuxValue(0);
p->inventory->add(new ItemInstance(contItems.at(packet->slot).getItem(), contItems.at(packet->slot).count, contItems.at(packet->slot).getAuxValue()));
} else {
LOGW("ContainerSetSlotPacket: illegal container operation in slot %i\n", packet->slot);
return;
}
if (ContainerType::FURNACE == p->containerMenu->containerType) { if (ContainerType::FURNACE == p->containerMenu->containerType) {
//LOGI("Server:Setting slot %d: %s\n", packet->slot, packet->item.toString().c_str()); //LOGI("Server:Setting slot %d: %s\n", packet->slot, packet->item.toString().c_str());
p->containerMenu->setSlot(packet->slot, &packet->item); p->containerMenu->setSlot(packet->slot, &packet->item);
@@ -1035,8 +635,6 @@ void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, Containe
p->containerMenu->setSlot(packet->slot, &packet->item); p->containerMenu->setSlot(packet->slot, &packet->item);
//p->containerMenu->setSlot(packet->slot, packet->item.isNull()? NULL : &packet->item); //p->containerMenu->setSlot(packet->slot, packet->item.isNull()? NULL : &packet->item);
} }
p->inventory->print();
} }
void ServerSideNetworkHandler::handle( const RakNet::RakNetGUID& source, SetHealthPacket* packet ) void ServerSideNetworkHandler::handle( const RakNet::RakNetGUID& source, SetHealthPacket* packet )
@@ -1059,8 +657,6 @@ void ServerSideNetworkHandler::handle( const RakNet::RakNetGUID& source, SignUpd
if (!level) if (!level)
return; return;
LOGI("SignUpdate: [%i, %i, %i]\n", packet->x, packet->y, packet->z);
TileEntity* te = level->getTileEntity(packet->x, packet->y, packet->z); TileEntity* te = level->getTileEntity(packet->x, packet->y, packet->z);
if (TileEntity::isType(te, TileEntityType::Sign)) { if (TileEntity::isType(te, TileEntityType::Sign)) {
SignTileEntity* ste = (SignTileEntity*) te; SignTileEntity* ste = (SignTileEntity*) te;
@@ -1117,9 +713,3 @@ Player* ServerSideNetworkHandler::getPlayer( const RakNet::RakNetGUID& source )
if (source == level->players[i]->owner) return level->players[i]; if (source == level->players[i]->owner) return level->players[i];
return NULL; return NULL;
} }
void ServerSideNetworkHandler::sendPrivate(Packet& packet, const RakNet::RakNetGUID& source) {
RakNet::BitStream bitStream;
packet.write(&bitStream);
rakPeer->Send(&bitStream, HIGH_PRIORITY, RELIABLE_ORDERED, 0, source, false);
}

View File

@@ -58,8 +58,6 @@ public:
virtual void handle(const RakNet::RakNetGUID& source, ContainerClosePacket* packet); virtual void handle(const RakNet::RakNetGUID& source, ContainerClosePacket* packet);
virtual void handle(const RakNet::RakNetGUID& source, SignUpdatePacket* packet); virtual void handle(const RakNet::RakNetGUID& source, SignUpdatePacket* packet);
virtual void handle(const RakNet::RakNetGUID& source, ChatPacket* packet); virtual void handle(const RakNet::RakNetGUID& source, ChatPacket* packet);
virtual void handle(const RakNet::RakNetGUID& source, MessagePacket* packet);
virtual void handle(const RakNet::RakNetGUID& source, WantCreatePacket* packet);
bool allowsIncomingConnections() { return _allowIncoming; } bool allowsIncomingConnections() { return _allowIncoming; }
void allowIncomingConnections(bool doAllow); void allowIncomingConnections(bool doAllow);
@@ -67,21 +65,13 @@ public:
Player* popPendingPlayer(const RakNet::RakNetGUID& source); Player* popPendingPlayer(const RakNet::RakNetGUID& source);
void displayGameMessage(const std::string& message); void displayGameMessage(const std::string& message);
private:
/** /**
* @brief Send packet to all players * @brief Send packet to all players
*/ */
void redistributePacket(Packet* packet, const RakNet::RakNetGUID& fromPlayer); void redistributePacket(Packet* packet, const RakNet::RakNetGUID& fromPlayer);
/**
* @brief Send packer private with GUID
*/
void sendPrivate(Packet& packet, const RakNet::RakNetGUID& source);
Player* getPlayer(const RakNet::RakNetGUID& source); Player* getPlayer(const RakNet::RakNetGUID& source);
private:
Minecraft* minecraft; Minecraft* minecraft;
Level* level; Level* level;
IRakNetInstance* raknetInstance; IRakNetInstance* raknetInstance;

View File

@@ -236,9 +236,9 @@ std::string CommandServer::parse(ConnectedClient& client, const std::string& s)
if (x0 < 0) x0 = 0; if (x0 < 0) x0 = 0;
if (y0 < 0) y0 = 0; if (y0 < 0) y0 = 0;
if (z0 < 0) z0 = 0; if (z0 < 0) z0 = 0;
if (x1 >= LevelConstants::LEVEL_WIDTH ) x1 = LevelConstants::LEVEL_WIDTH - 1; if (x1 >= LEVEL_WIDTH ) x1 = LEVEL_WIDTH - 1;
if (y1 >= LevelConstants::LEVEL_HEIGHT) y1 = LevelConstants::LEVEL_HEIGHT - 1; if (y1 >= LEVEL_HEIGHT) y1 = LEVEL_HEIGHT - 1;
if (z1 >= LevelConstants::LEVEL_DEPTH ) z1 = LevelConstants::LEVEL_DEPTH - 1; if (z1 >= LEVEL_DEPTH ) z1 = LEVEL_DEPTH - 1;
for (int y = y0; y <= y1; ++y) for (int y = y0; y <= y1; ++y)
for (int z = z0; z <= z1; ++z) for (int z = z0; z <= z1; ++z)
@@ -456,7 +456,7 @@ std::string CommandServer::parse(ConnectedClient& client, const std::string& s)
sw.start(); sw.start();
// Save a cuboid around the player // Save a cuboid around the player
const int CSize = LevelConstants::CHUNK_CACHE_WIDTH; const int CSize = CHUNK_CACHE_WIDTH;
int cx = (int)e->x / CSize; int cx = (int)e->x / CSize;
int cz = (int)e->z / CSize; int cz = (int)e->z / CSize;
@@ -504,7 +504,7 @@ bool CommandServer::handleCheckpoint(bool doRestore ) {
const int cz = restorePos.z; const int cz = restorePos.z;
const int y0 = restorePos.y; const int y0 = restorePos.y;
const int y1 = y0 + RestoreHeight; const int y1 = y0 + RestoreHeight;
const int CSize = LevelConstants::CHUNK_CACHE_WIDTH; const int CSize = CHUNK_CACHE_WIDTH;
const int numChunkBytes = RestoreHeight * CSize * CSize * 20 / 8; const int numChunkBytes = RestoreHeight * CSize * CSize * 20 / 8;
if (!restoreBuffer) { if (!restoreBuffer) {

View File

@@ -33,18 +33,18 @@ public:
unsigned char* blockIds = chunk->getBlockData(); unsigned char* blockIds = chunk->getBlockData();
DataLayer& blockData = chunk->data; DataLayer& blockData = chunk->data;
const int setSize = LevelConstants::LEVEL_HEIGHT / 8; const int setSize = LEVEL_HEIGHT / 8;
const int setShift = 4; // power of LevelConstants::LEVEL_HEIGHT / 8 const int setShift = 4; // power of LEVEL_HEIGHT / 8
chunkData.Reset(); chunkData.Reset();
for (int i = 0; i < LevelConstants::CHUNK_COLUMNS; i++) for (int i = 0; i < CHUNK_COLUMNS; i++)
{ {
unsigned char updateBits = chunk->updateMap[i]; unsigned char updateBits = chunk->updateMap[i];
chunkData.Write(updateBits); chunkData.Write(updateBits);
if (updateBits > 0) if (updateBits > 0)
{ {
int colDataPosition = (i % LevelConstants::CHUNK_WIDTH) << 11 | (i / LevelConstants::CHUNK_WIDTH) << 7; int colDataPosition = (i % CHUNK_WIDTH) << 11 | (i / CHUNK_WIDTH) << 7;
for (int set = 0; set < 8; set++) for (int set = 0; set < 8; set++)
{ {

View File

@@ -9,20 +9,17 @@ public:
RakNet::RakString clientName; RakNet::RakString clientName;
int clientNetworkVersion; int clientNetworkVersion;
int clientNetworkLowestSupportedVersion; int clientNetworkLowestSupportedVersion;
bool newProto;
LoginPacket() LoginPacket()
: clientNetworkVersion(-1), : clientNetworkVersion(-1),
clientNetworkLowestSupportedVersion(-1), clientNetworkLowestSupportedVersion(-1)
newProto(false)
{ {
} }
LoginPacket(const RakNet::RakString& clientName, int clientVersion, bool newProto) LoginPacket(const RakNet::RakString& clientName, int clientVersion)
: clientName(clientName), : clientName(clientName),
clientNetworkVersion(clientVersion), clientNetworkVersion(clientVersion),
clientNetworkLowestSupportedVersion(clientVersion), clientNetworkLowestSupportedVersion(clientVersion)
newProto(newProto)
{ {
} }
@@ -32,7 +29,6 @@ public:
bitStream->Write(clientName); bitStream->Write(clientName);
bitStream->Write(clientNetworkVersion); bitStream->Write(clientNetworkVersion);
bitStream->Write(clientNetworkLowestSupportedVersion); bitStream->Write(clientNetworkLowestSupportedVersion);
bitStream->Write(newProto);
} }
void read(RakNet::BitStream* bitStream) void read(RakNet::BitStream* bitStream)
@@ -43,11 +39,6 @@ public:
if (bitStream->GetNumberOfUnreadBits() > 0) { if (bitStream->GetNumberOfUnreadBits() > 0) {
bitStream->Read(clientNetworkVersion); bitStream->Read(clientNetworkVersion);
bitStream->Read(clientNetworkLowestSupportedVersion); bitStream->Read(clientNetworkLowestSupportedVersion);
// Checking for new proto
if (bitStream->GetNumberOfUnreadBits() > 0) {
bitStream->Read(newProto);
}
} }
} }

View File

@@ -3,13 +3,10 @@
#include "../Packet.h" #include "../Packet.h"
// wtf why not enum
namespace LoginStatus { namespace LoginStatus {
const int Success = 0; const int Success = 0;
const int Failed_ClientOld = 1; const int Failed_ClientOld = 1;
const int Failed_ServerOld = 2; const int Failed_ServerOld = 2;
const int Failed_TakenNickname = 3;
const int Failed_Banned = 4;
} }
class LoginStatusPacket : public Packet { class LoginStatusPacket : public Packet {

View File

@@ -50,7 +50,5 @@
#include "TileEventPacket.h" #include "TileEventPacket.h"
#include "UpdateBlockPacket.h" #include "UpdateBlockPacket.h"
#include "UseItemPacket.h" #include "UseItemPacket.h"
#include "RemoveItemPacket.h"
#include "WantCreatePacket.h"
#include "TakeItemPacket.h"
#endif /*NET_MINECRAFT_NETWORK_PACKET__PacketInclude_H__*/ #endif /*NET_MINECRAFT_NETWORK_PACKET__PacketInclude_H__*/

View File

@@ -9,19 +9,15 @@ public:
int entityId; int entityId;
unsigned short itemId; unsigned short itemId;
unsigned short itemAuxValue; unsigned short itemAuxValue;
unsigned char selectedSlot;
unsigned char inventorySlot;
PlayerEquipmentPacket() PlayerEquipmentPacket()
{ {
} }
PlayerEquipmentPacket(int entityId, int itemId, int data, int selSlot, int invSlot) PlayerEquipmentPacket(int entityId, int itemId, int data)
: entityId(entityId), : entityId(entityId),
itemId(itemId), itemId(itemId),
itemAuxValue(data), itemAuxValue(data)
selectedSlot(selSlot),
inventorySlot(invSlot)
{ {
} }
@@ -32,8 +28,6 @@ public:
bitStream->Write(entityId); bitStream->Write(entityId);
bitStream->Write(itemId); bitStream->Write(itemId);
bitStream->Write(itemAuxValue); bitStream->Write(itemAuxValue);
bitStream->Write(selectedSlot);
bitStream->Write(inventorySlot);
} }
void read(RakNet::BitStream* bitStream) void read(RakNet::BitStream* bitStream)
@@ -41,8 +35,6 @@ public:
bitStream->Read(entityId); bitStream->Read(entityId);
bitStream->Read(itemId); bitStream->Read(itemId);
bitStream->Read(itemAuxValue); bitStream->Read(itemAuxValue);
bitStream->Read(selectedSlot);
bitStream->Read(inventorySlot);
} }
void handle(const RakNet::RakNetGUID& source, NetEventCallback* callback) void handle(const RakNet::RakNetGUID& source, NetEventCallback* callback)

View File

@@ -1,54 +0,0 @@
#ifndef NET_MINECRAFT_NETWORK_PACKET__RemoveItemPacket_H__
#define NET_MINECRAFT_NETWORK_PACKET__RemoveItemPacket_H__
//package net.minecraft.network.packet;
#include "../Packet.h"
class RemoveItemPacket: public Packet
{
public:
RemoveItemPacket() {
}
RemoveItemPacket(int playerId, int count, int auxValue, int itemId)
:
playerId(playerId),
count(count),
auxValue(auxValue),
itemId(itemId)
{
}
void write(RakNet::BitStream* bitStream)
{
bitStream->Write((RakNet::MessageID)(ID_USER_PACKET_ENUM + PACKET_REMOVEITEM));
bitStream->Write(itemId);
bitStream->Write(count);
bitStream->Write(auxValue);
bitStream->Write(playerId);
}
void read(RakNet::BitStream* bitStream)
{
bitStream->Read(itemId);
bitStream->Read(count);
bitStream->Read(auxValue);
bitStream->Read(playerId);
}
void handle(const RakNet::RakNetGUID& source, NetEventCallback* callback)
{
callback->handle(source, (RemoveItemPacket*)this);
}
int playerId;
int itemId;
int count;
int auxValue;
};
#endif /*NET_MINECRAFT_NETWORK_PACKET__RemoveItemPacket_H__*/

View File

@@ -2,14 +2,13 @@
#define NET_MINECRAFT_NETWORK_PACKET__SendInventoryPacket_H__ #define NET_MINECRAFT_NETWORK_PACKET__SendInventoryPacket_H__
#include "../Packet.h" #include "../Packet.h"
#include "world/entity/player/Inventory.h"
#include "world/inventory/FillingContainer.h"
#include <array>
class SendInventoryPacket: public Packet class SendInventoryPacket: public Packet
{ {
public: public:
SendInventoryPacket() {} SendInventoryPacket()
{
}
SendInventoryPacket(Player* player, bool dropItems) SendInventoryPacket(Player* player, bool dropItems)
: entityId(player->entityId), : entityId(player->entityId),
@@ -22,15 +21,10 @@ public:
ItemInstance* item = inv->getItem(i); ItemInstance* item = inv->getItem(i);
items.push_back(item? *item : ItemInstance()); items.push_back(item? *item : ItemInstance());
} }
for (int i = 0; i < NumArmorItems; ++i) { for (int i = 0; i < NumArmorItems; ++i) {
ItemInstance* item = player->getArmor(i); ItemInstance* item = player->getArmor(i);
items.push_back(item? *item : ItemInstance()); items.push_back(item? *item : ItemInstance());
} }
for (int i = 0; i < inv->numLinkedSlots; ++i) {
linkedSlot[i] = inv->linkedSlots[i];
}
} }
void write(RakNet::BitStream* bitStream) void write(RakNet::BitStream* bitStream)
@@ -45,13 +39,6 @@ public:
// Armor // Armor
for (int i = 0; i < NumArmorItems; ++i) for (int i = 0; i < NumArmorItems; ++i)
PacketUtil::writeItemInstance(items[i + numItems], bitStream); PacketUtil::writeItemInstance(items[i + numItems], bitStream);
int lSlots = Inventory::MAX_SELECTION_SIZE;
// Linked slots
bitStream->Write(lSlots);
for (int i = 0; i < lSlots; ++i)
bitStream->Write(linkedSlot[i]);
} }
void read(RakNet::BitStream* bitStream) void read(RakNet::BitStream* bitStream)
@@ -63,12 +50,6 @@ public:
// Inventory, Armor // Inventory, Armor
for (int i = 0; i < numItems + NumArmorItems; ++i) for (int i = 0; i < numItems + NumArmorItems; ++i)
items.push_back(PacketUtil::readItemInstance(bitStream)); items.push_back(PacketUtil::readItemInstance(bitStream));
// Linked slots
int lSlots = 0;
bitStream->Read(lSlots);
for (int i = 0; i < lSlots; ++i)
bitStream->Read(linkedSlot[i]);
} }
void handle(const RakNet::RakNetGUID& source, NetEventCallback* callback) void handle(const RakNet::RakNetGUID& source, NetEventCallback* callback)
@@ -81,8 +62,6 @@ public:
short numItems; short numItems;
unsigned char extra; unsigned char extra;
std::array<FillingContainer::LinkedSlot, Inventory::MAX_SELECTION_SIZE> linkedSlot;
static const int ExtraDrop = 1; static const int ExtraDrop = 1;
static const int NumArmorItems = 4; static const int NumArmorItems = 4;
}; };

View File

@@ -2,7 +2,6 @@
#define NET_MINECRAFT_NETWORK_PACKET__StartGamePacket_H__ #define NET_MINECRAFT_NETWORK_PACKET__StartGamePacket_H__
#include "../Packet.h" #include "../Packet.h"
#include "world/level/LevelConstants.h"
#include <cstdint> #include <cstdint>
class StartGamePacket : public Packet class StartGamePacket : public Packet
@@ -15,20 +14,18 @@ public:
int entityId; int entityId;
float x, y, z; float x, y, z;
int chunkCacheWidth = 0;
StartGamePacket() StartGamePacket()
{ {
} }
StartGamePacket(long seed, int levelGeneratorVersion, int gameType, int entityId, float x, float y, float z, int chunkCacheWidth) StartGamePacket(long seed, int levelGeneratorVersion, int gameType, int entityId, float x, float y, float z)
: levelSeed((int32_t)seed), : levelSeed((int32_t)seed),
levelGeneratorVersion(levelGeneratorVersion), levelGeneratorVersion(levelGeneratorVersion),
gameType(gameType), gameType(gameType),
entityId(entityId), entityId(entityId),
x(x), x(x),
y(y), y(y),
z(z), z(z)
chunkCacheWidth(chunkCacheWidth)
{ {
} }
@@ -43,7 +40,6 @@ public:
bitStream->Write(x); bitStream->Write(x);
bitStream->Write(y); bitStream->Write(y);
bitStream->Write(z); bitStream->Write(z);
bitStream->Write(LevelConstants::CHUNK_CACHE_WIDTH);
} }
void read(RakNet::BitStream* bitStream) void read(RakNet::BitStream* bitStream)
@@ -55,10 +51,6 @@ public:
bitStream->Read(x); bitStream->Read(x);
bitStream->Read(y); bitStream->Read(y);
bitStream->Read(z); bitStream->Read(z);
if (bitStream->GetNumberOfUnreadBits() > 0) {
bitStream->Read(chunkCacheWidth);
}
} }
void handle(const RakNet::RakNetGUID& source, NetEventCallback* callback) void handle(const RakNet::RakNetGUID& source, NetEventCallback* callback)

View File

@@ -1,54 +0,0 @@
#ifndef NET_MINECRAFT_NETWORK_PACKET__TakeItemPacket_H__
#define NET_MINECRAFT_NETWORK_PACKET__TakeItemPacket_H__
//package net.minecraft.network.packet;
#include "../Packet.h"
class TakeItemPacket: public Packet
{
public:
TakeItemPacket() {
}
TakeItemPacket(int playerId, int count, int auxValue, int itemId)
:
playerId(playerId),
count(count),
auxValue(auxValue),
itemId(itemId)
{
}
void write(RakNet::BitStream* bitStream)
{
bitStream->Write((RakNet::MessageID)(ID_USER_PACKET_ENUM + PACKET_TAKEITEM));
bitStream->Write(itemId);
bitStream->Write(count);
bitStream->Write(auxValue);
bitStream->Write(playerId);
}
void read(RakNet::BitStream* bitStream)
{
bitStream->Read(itemId);
bitStream->Read(count);
bitStream->Read(auxValue);
bitStream->Read(playerId);
}
void handle(const RakNet::RakNetGUID& source, NetEventCallback* callback)
{
callback->handle(source, (TakeItemPacket*)this);
}
int playerId;
int itemId;
int count;
int auxValue;
};
#endif /*NET_MINECRAFT_NETWORK_PACKET__TakeItemPacket_H__*/

View File

@@ -16,14 +16,10 @@ public:
short itemId; short itemId;
unsigned char itemData; unsigned char itemData;
ItemInstance item; ItemInstance item;
float playerX, playerY, playerZ;
float playerX0, playerY0, playerZ0;
float playerX1, playerY1, playerZ1;
UseItemPacket() {} UseItemPacket() {}
UseItemPacket(int x, int y, int z, int face, const ItemInstance* item, int entityId, float clickX, float clickY, float clickZ, UseItemPacket(int x, int y, int z, int face, const ItemInstance* item, int entityId, float clickX, float clickY, float clickZ)
float plrX, float plrY, float plrZ, float plrX0, float plrY0, float plrZ0, float plrX1, float plrY1, float plrZ1)
: x(x), : x(x),
y(y), y(y),
z(z), z(z),
@@ -33,36 +29,17 @@ public:
entityId(entityId), entityId(entityId),
clickX(clickX), clickX(clickX),
clickY(clickY), clickY(clickY),
clickZ(clickZ), clickZ(clickZ)
playerX(plrX),
playerY(plrY),
playerZ(plrZ),
playerX0(plrX0),
playerY0(plrY0),
playerZ0(plrZ0),
playerX1(plrX1),
playerY1(plrY1),
playerZ1(plrZ1)
{} {}
UseItemPacket(const ItemInstance* item, int entityId, const Vec3& aim, float plrX, float plrY, float plrZ, UseItemPacket(const ItemInstance* item, int entityId, const Vec3& aim)
float plrX0, float plrY0, float plrZ0, float plrX1, float plrY1, float plrZ1)
: face(255), : face(255),
itemId(item? item->id : 0), itemId(item? item->id : 0),
itemData(item? item->getAuxValue() : 0), itemData(item? item->getAuxValue() : 0),
entityId(entityId), entityId(entityId),
x((int)(aim.x * 32768.0f)), x((int)(aim.x * 32768.0f)),
y((int)(aim.y * 32768.0f)), y((int)(aim.y * 32768.0f)),
z((int)(aim.z * 32768.0f)), z((int)(aim.z * 32768.0f))
playerX(plrX),
playerY(plrY),
playerZ(plrZ),
playerX0(plrX0),
playerY0(plrY0),
playerZ0(plrZ0),
playerX1(plrX1),
playerY1(plrY1),
playerZ1(plrZ1)
{ {
} }
@@ -80,15 +57,6 @@ public:
bitStream->Write(clickX); bitStream->Write(clickX);
bitStream->Write(clickY); bitStream->Write(clickY);
bitStream->Write(clickZ); bitStream->Write(clickZ);
bitStream->Write(playerX);
bitStream->Write(playerY);
bitStream->Write(playerZ);
bitStream->Write(playerX0);
bitStream->Write(playerY0);
bitStream->Write(playerZ0);
bitStream->Write(playerX1);
bitStream->Write(playerY1);
bitStream->Write(playerZ1);
} }
void read(RakNet::BitStream* bitStream) void read(RakNet::BitStream* bitStream)
@@ -106,15 +74,7 @@ public:
item.id = itemId; item.id = itemId;
item.setAuxValue(itemData); item.setAuxValue(itemData);
item.count = (itemId == 0 && itemData == 0)? 0 : 1; item.count = (itemId == 0 && itemData == 0)? 0 : 1;
bitStream->Read(playerX);
bitStream->Read(playerY);
bitStream->Read(playerZ);
bitStream->Read(playerX0);
bitStream->Read(playerY0);
bitStream->Read(playerZ0);
bitStream->Read(playerX1);
bitStream->Read(playerY1);
bitStream->Read(playerZ1);
} }
void handle(const RakNet::RakNetGUID& source, NetEventCallback* callback) void handle(const RakNet::RakNetGUID& source, NetEventCallback* callback)

View File

@@ -1,54 +0,0 @@
#ifndef NET_MINECRAFT_NETWORK_PACKET__WantCreatePacket_H__
#define NET_MINECRAFT_NETWORK_PACKET__WantCreatePacket_H__
//package net.minecraft.network.packet;
#include "../Packet.h"
class WantCreatePacket: public Packet
{
public:
WantCreatePacket() {
}
WantCreatePacket(int playerId, int count, int auxValue, int itemId)
:
playerId(playerId),
count(count),
auxValue(auxValue),
itemId(itemId)
{
}
void write(RakNet::BitStream* bitStream)
{
bitStream->Write((RakNet::MessageID)(ID_USER_PACKET_ENUM + PACKET_WANTCREATEITEM));
bitStream->Write(itemId);
bitStream->Write(count);
bitStream->Write(auxValue);
bitStream->Write(playerId);
}
void read(RakNet::BitStream* bitStream)
{
bitStream->Read(itemId);
bitStream->Read(count);
bitStream->Read(auxValue);
bitStream->Read(playerId);
}
void handle(const RakNet::RakNetGUID& source, NetEventCallback* callback)
{
callback->handle(source, (WantCreatePacket*)this);
}
int playerId;
int itemId;
int count;
int auxValue;
};
#endif /*NET_MINECRAFT_NETWORK_PACKET__WantCreatePacket_H__*/

View File

@@ -1,160 +0,0 @@
#pragma once
#include <cstdint>
#include <raknet/RakNetTypes.h>
#include <plugins/PluginsManager.hpp>
#include <network/ServerSideNetworkHandler.h>
#include <world/entity/player/Player.h>
#include <client/Minecraft.h>
#include <network/packet/ChatPacket.h>
#include <network/packet/MovePlayerPacket.h>
#include <network/packet/RemoveItemPacket.h>
#include <network/packet/SetHealthPacket.h>
#include <network/packet/TakeItemPacket.h>
#include <world/entity/player/Inventory.h>
// TODO: Optimize includes
class LuaPlayer {
public:
LuaPlayer(const RakNet::RakNetGUID source) : m_source(source) {}
Player* getPlayer() {
auto mc = PluginsManager::get().getMinecraft();
ServerSideNetworkHandler* ss = (ServerSideNetworkHandler*) mc->netCallback;
auto plr = ss->getPlayer(m_source);
return plr;
}
std::string getNickname() {
auto plr = getPlayer();
if (plr != nullptr) return plr->name;
return "";
}
std::tuple<float, float, float, float, float> getPos() {
auto plr = getPlayer();
if (plr != nullptr) return {plr->x, plr->y, plr->z, plr->yRot, plr->xRot};
return {0, 0, 0, 0, 0};
}
void setPos(float x, float y, float z, float yRot, float xRot) {
auto plr = getPlayer();
if (plr == nullptr) return;
auto mc = PluginsManager::get().getMinecraft();
ServerSideNetworkHandler* ss = (ServerSideNetworkHandler*) mc->netCallback;
// plr->x = x;
// plr->y = y;
// plr->z = z;
// plr->yRot = yRot;
// plr->xRot = xRot;
plr->xd = plr->yd = plr->zd = 0;
plr->lerpTo(x, y, z, yRot, xRot, 3);
MovePlayerPacket move(plr->entityId, x, y, z, yRot, xRot);
ss->sendPrivate(move, m_source);
}
void sendMessage(std::string msg) {
auto mc = PluginsManager::get().getMinecraft();
ServerSideNetworkHandler* ss = (ServerSideNetworkHandler*) mc->netCallback;
ChatPacket packet(msg);
ss->sendPrivate(packet, m_source);
}
void addItem(int id, int count, int auxValue) {
auto plr = getPlayer();
if (plr == nullptr) return;
auto mc = PluginsManager::get().getMinecraft();
ServerSideNetworkHandler* ss = (ServerSideNetworkHandler*) mc->netCallback;
auto item = new ItemInstance(id, count, auxValue);
if (!plr->inventory->add(item)) {
plr->inventory->add(item);
}
TakeItemPacket itemAdd(plr->entityId, count, auxValue, id);
ss->sendPrivate(itemAdd, m_source);
}
std::tuple<int, int, int> getItem(int index) {
auto plr = getPlayer();
if (plr == nullptr) return {0, 0, 0};
auto item = plr->inventory->getItem(index);
if (item != nullptr) {
return {item->id, item->count, item->getAuxValue()};
} else {
return {0, 0, 0};
}
}
void clearInventory() {
auto plr = getPlayer();
if (plr == nullptr) return;
auto mc = PluginsManager::get().getMinecraft();
ServerSideNetworkHandler* ss = (ServerSideNetworkHandler*) mc->netCallback;
for (int i = Inventory::MAX_SELECTION_SIZE; i < plr->inventory->getContainerSize(); i++) {
auto itm = plr->inventory->getItem(i);
if (itm != NULL) {
printf("remove %d \n", plr->inventory->removeResource(ItemInstance(itm->id, itm->count, itm->getAuxValue())));
RemoveItemPacket itemAdd(plr->entityId, itm->count, itm->getAuxValue(), itm->id);
ss->sendPrivate(itemAdd, m_source);
}
}
}
sol::table getInventory() {
auto plr = getPlayer();
if (plr == nullptr) return {};
sol::table inv = PluginsManager::get().getLua().create_table();
for (int i = Inventory::MAX_SELECTION_SIZE; i < plr->inventory->getContainerSize(); i++) {
auto itm = plr->inventory->getItem(i);
if (itm != NULL) {
inv[i - 8] = {itm->id, itm->count, itm->getAuxValue()};
} else {
inv[i - 8] = sol::lua_nil;
}
}
return inv;
}
int getHp() {
auto plr = getPlayer();
if (plr == nullptr) return -1;
return plr->health;
}
void setHp(int hp) {
auto plr = getPlayer();
if (plr == nullptr) return;
plr->health = hp;
auto mc = PluginsManager::get().getMinecraft();
ServerSideNetworkHandler* ss = (ServerSideNetworkHandler*) mc->netCallback;
SetHealthPacket hpPacket(plr->health);
ss->sendPrivate(hpPacket, m_source);
}
private:
const RakNet::RakNetGUID m_source;
};

View File

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

View File

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

View File

@@ -1,9 +0,0 @@
#pragma once
class MessageEvent {
public:
bool m_decline;
void setDecline(bool decline) { m_decline = decline; }
private:
};

View File

@@ -1,103 +0,0 @@
#include <plugins/PluginsManager.hpp>
#include <plugins/LuaPlayer.hpp>
#include <plugins/LuaServer.hpp>
#include <client/Minecraft.h>
#include <filesystem>
#include "MessageEvent.hpp"
namespace fs = std::filesystem;
int PluginsManager::emitCommands(std::string command, const RakNet::RakNetGUID& source) {
std::vector<std::string> args;
std::string cmd;
int i = 0;
std::string word;
std::stringstream ss(command);
while (ss >> word) {
if (i == 0) {
cmd = word;
} else {
args.push_back(word);
}
i++;
}
auto it = m_luaCommands.find(cmd);
if (it == m_luaCommands.end()) return 1;
for (auto& callback : it->second) {
sol::protected_function_result result = callback(LuaPlayer(source), sol::as_table(args));
if (!result.valid()) {
sol::error err = result;
std::cout << err.what() << std::endl;
}
}
return 0;
}
void PluginsManager::init(Minecraft& minecraft) {
m_lua.open_libraries(sol::lib::base, sol::lib::package, sol::lib::string, sol::lib::math, sol::lib::table, sol::lib::io);
registerTypes();
m_minecraft = &minecraft;
}
void PluginsManager::registerTypes() {
// @note you cant just do that, because lua doesnt have access to the class in this case
// m_lua.set_function("subscribe", &PluginsManager::subscribe);
m_lua.set_function("subscribe", [this](std::string event, sol::protected_function func) {
m_callbacks[event].push_back(func);
});
m_lua.set_function("addCommand", [this](std::string commandName, sol::function func) {
m_luaCommands[commandName].push_back(func);
});
m_lua.new_usertype<LuaServer>(
"Server",
"sendMessage", &LuaServer::sendServerMessage
);
m_lua.new_usertype<LuaPlayer>(
"Player",
"getNickname", &LuaPlayer::getNickname,
"getPos", &LuaPlayer::getPos,
"setPos", &LuaPlayer::setPos,
"sendMessage", &LuaPlayer::sendMessage,
"getInventory", &LuaPlayer::getInventory,
"addItem", &LuaPlayer::addItem,
"getItem", &LuaPlayer::getItem,
"clearInventory", &LuaPlayer::clearInventory,
"getHp", &LuaPlayer::getHp,
"setHp", &LuaPlayer::setHp
);
m_lua.new_usertype<MessageEvent>(
"MessageEvent",
"setDecline", &MessageEvent::setDecline
);
m_lua["Server"] = &m_srv;
}
void PluginsManager::loadPlugins() {
std::string path = "plugins/";
if (fs::exists(path)) {
for (const auto& entry : fs::directory_iterator(path)) {
if (!fs::is_directory(entry.path().string())) {
m_lua.script_file(entry.path().string());
}
}
} else {
std::filesystem::create_directory(path);
}
}

View File

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

View File

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

View File

@@ -17,11 +17,6 @@ ArgumentsSettings::ArgumentsSettings(int numArguments, char** arguments)
levelName = std::string(arguments[a+1]); levelName = std::string(arguments[a+1]);
a++; // Skip the next argument since it's part of this one. a++; // Skip the next argument since it's part of this one.
} }
} else if(strcmp(arguments[a], "--gamemode") == 0) {
if(a + 1 < numArguments) {
gamemode = std::string(arguments[a+1]);
a++; // Skip the next argument since it's part of this one.
}
} else if(strcmp(arguments[a], "--leveldir") == 0) { } else if(strcmp(arguments[a], "--leveldir") == 0) {
if(a + 1 < numArguments) { if(a + 1 < numArguments) {
levelDir = std::string(arguments[a+1]); levelDir = std::string(arguments[a+1]);
@@ -56,9 +51,6 @@ std::string ArgumentsSettings::getServerKey() {
std::string ArgumentsSettings::getCachePath() { std::string ArgumentsSettings::getCachePath() {
return cachePath; return cachePath;
} }
std::string ArgumentsSettings::getGamemode() {
return gamemode;
}
std::string ArgumentsSettings::getLevelDir() { std::string ArgumentsSettings::getLevelDir() {
return levelDir; return levelDir;
} }

View File

@@ -4,27 +4,20 @@
class ArgumentsSettings { class ArgumentsSettings {
public: public:
ArgumentsSettings(int numArguments, char** arguments); ArgumentsSettings(int numArguments, char** arguments);
std::string getExternalPath(); std::string getExternalPath();
std::string getLevelName(); std::string getLevelName();
std::string getServerKey(); std::string getServerKey();
std::string getCachePath(); std::string getCachePath();
std::string getLevelDir(); std::string getLevelDir();
std::string getGamemode();
bool getShowHelp(); bool getShowHelp();
int getPort(); int getPort();
private: private:
std::string cachePath; std::string cachePath;
std::string externalPath; std::string externalPath;
std::string levelName; std::string levelName;
std::string gamemode;
std::string levelDir; std::string levelDir;
std::string serverKey; std::string serverKey;
bool showHelp; bool showHelp;
int port; int port;
}; };

View File

@@ -12,19 +12,16 @@ ServerLevel::ServerLevel(LevelStorage* levelStorage, const std::string& levelNam
void ServerLevel::updateSleepingPlayerList() { void ServerLevel::updateSleepingPlayerList() {
bool allPlayersWasSleeping = allPlayersAreSleeping; bool allPlayersWasSleeping = allPlayersAreSleeping;
allPlayersAreSleeping = !players.empty(); allPlayersAreSleeping = !players.empty();
for(PlayerList::iterator it = players.begin(); it != players.end(); ++it) {
for (PlayerList::iterator it = players.begin(); it != players.end(); ++it) {
Player* player = *it; Player* player = *it;
if(!player->isSleeping()) {
if (!player->isSleeping()) {
allPlayersAreSleeping = false; allPlayersAreSleeping = false;
break; break;
} }
} }
if (!allPlayersWasSleeping && allPlayersAreSleeping) { if(!allPlayersWasSleeping && allPlayersAreSleeping) {
levelEvent(NULL, LevelEvent::ALL_PLAYERS_SLEEPING, 0, 0, 0, 0); levelEvent(NULL, LevelEvent::ALL_PLAYERS_SLEEPING, 0, 0, 0, 0);
for(PlayerList::iterator it = players.begin(); it != players.end(); ++it) {
for (PlayerList::iterator it = players.begin(); it != players.end(); ++it) {
(*it)->setAllPlayersSleeping(); (*it)->setAllPlayersSleeping();
} }
} }
@@ -32,26 +29,23 @@ void ServerLevel::updateSleepingPlayerList() {
void ServerLevel::awakenAllPlayers() { void ServerLevel::awakenAllPlayers() {
allPlayersAreSleeping = false; allPlayersAreSleeping = false;
for(PlayerList::iterator it = players.begin(); it != players.end(); ++it) {
for (PlayerList::iterator it = players.begin(); it != players.end(); ++it) {
Player* player = *it; Player* player = *it;
if(player->isSleeping()) {
if (player->isSleeping()) {
player->stopSleepInBed(false, false, true); player->stopSleepInBed(false, false, true);
player->health = Player::MAX_HEALTH; player->health = Player::MAX_HEALTH;
player->lastHealth = Player::MAX_HEALTH; player->lastHealth = Player::MAX_HEALTH;
} }
} }
SetHealthPacket packet(Player::MAX_HEALTH); SetHealthPacket packet(Player::MAX_HEALTH);
raknetInstance->send(packet); raknetInstance->send(packet);
} }
bool ServerLevel::allPlayersSleeping() { bool ServerLevel::allPlayersSleeping() {
if (allPlayersAreSleeping && !isClientSide) { if(allPlayersAreSleeping && !isClientSide) {
// all players are sleeping, but have they slept long enough? // all players are sleeping, but have they slept long enough?
for (PlayerList::iterator it = players.begin(); it != players.end(); ++it) { for(PlayerList::iterator it = players.begin(); it != players.end(); ++it) {
if (!(*it)->isSleepingLongEnough()) { if(!(*it)->isSleepingLongEnough()) {
return false; return false;
} }
} }
@@ -61,17 +55,13 @@ bool ServerLevel::allPlayersSleeping() {
return false; return false;
} }
void ServerLevel::tick() { void ServerLevel::tick(){
super::tick(); super::tick();
if(allPlayersSleeping()) {
if (allPlayersSleeping()) {
long newTime = levelData.getTime() + TICKS_PER_DAY; long newTime = levelData.getTime() + TICKS_PER_DAY;
levelData.setTime(newTime - (newTime % TICKS_PER_DAY)); levelData.setTime(newTime - (newTime % TICKS_PER_DAY));
SetTimePacket packet(levelData.getTime()); SetTimePacket packet(levelData.getTime());
raknetInstance->send(packet); raknetInstance->send(packet);
awakenAllPlayers(); awakenAllPlayers();
} }
} }

View File

@@ -19,17 +19,14 @@
#include "../network/packet/AnimatePacket.h" #include "../network/packet/AnimatePacket.h"
#include "../world/level/tile/entity/ChestTileEntity.h" #include "../world/level/tile/entity/ChestTileEntity.h"
#include "../network/packet/HurtArmorPacket.h" #include "../network/packet/HurtArmorPacket.h"
#include "network/packet/SendInventoryPacket.h"
#include "world/entity/player/Inventory.h"
ServerPlayer::ServerPlayer( Minecraft* minecraft, Level* level, bool proto) ServerPlayer::ServerPlayer( Minecraft* minecraft, Level* level )
: super(level, minecraft->isCreativeMode()), : super(level, minecraft->isCreativeMode()),
_mc(minecraft), _mc(minecraft),
_prevHealth(-999), _prevHealth(-999),
_containerCounter(0), _containerCounter(0)
isNewProto(proto)
{ {
// hasFakeInventory = true; hasFakeInventory = true;
footSize = 0; footSize = 0;
} }
@@ -70,16 +67,7 @@ void ServerPlayer::tick() {
void ServerPlayer::take( Entity* e, int orgCount ) { void ServerPlayer::take( Entity* e, int orgCount ) {
TakeItemEntityPacket packet(e->entityId, entityId); TakeItemEntityPacket packet(e->entityId, entityId);
// SendInventoryPacket packet(this, false);
_mc->raknetInstance->send(packet); _mc->raknetInstance->send(packet);
printf("TakeItemEntityPacket \n");
LOGI("Inventory:\n");
for (int i = 0; i < inventory->numLinkedSlots; i++) {
auto item = inventory->getItem(i);
if (item)
LOGI("\t %i: %s (%i)\n", i, item->getName().c_str(), item->count);
}
super::take(e, orgCount); super::take(e, orgCount);
} }
@@ -130,20 +118,20 @@ bool ServerPlayer::hasResource( int id ) {
void ServerPlayer::setContainerData( BaseContainerMenu* menu, int id, int value ) { void ServerPlayer::setContainerData( BaseContainerMenu* menu, int id, int value ) {
ContainerSetDataPacket p(menu->containerId, id, value); ContainerSetDataPacket p(menu->containerId, id, value);
_mc->raknetInstance->send(owner, p); _mc->raknetInstance->send(owner, p);
LOGI("Setting container data for id %d: %d\n", id, value); //LOGI("Setting container data for id %d: %d\n", id, value);
} }
void ServerPlayer::slotChanged( BaseContainerMenu* menu, int slot, const ItemInstance& item, bool isResultSlot ) { void ServerPlayer::slotChanged( BaseContainerMenu* menu, int slot, const ItemInstance& item, bool isResultSlot ) {
if (isResultSlot) return; if (isResultSlot) return;
ContainerSetSlotPacket p(menu->containerId, slot, item); ContainerSetSlotPacket p(menu->containerId, slot, item);
_mc->raknetInstance->send(owner, p); _mc->raknetInstance->send(owner, p);
LOGI("Slot %d changed\n", slot); //LOGI("Slot %d changed\n", slot);
} }
void ServerPlayer::refreshContainer( BaseContainerMenu* menu, const std::vector<ItemInstance>& items ) { void ServerPlayer::refreshContainer( BaseContainerMenu* menu, const std::vector<ItemInstance>& items ) {
ContainerSetContentPacket p(menu->containerId, menu->getItems()); ContainerSetContentPacket p(menu->containerId, menu->getItems());
_mc->raknetInstance->send(owner, p); _mc->raknetInstance->send(owner, p);
LOGI("Refreshing container with %zu items\n", items.size()); //LOGI("Refreshing container with %d items\n", items.size());
} }
void ServerPlayer::nextContainerCounter() { void ServerPlayer::nextContainerCounter() {
@@ -175,12 +163,3 @@ void ServerPlayer::displayClientMessage( const std::string& messageId ) {
ChatPacket package(messageId); ChatPacket package(messageId);
_mc->raknetInstance->send(owner, package); _mc->raknetInstance->send(owner, package);
} }
void ServerPlayer::causeFallDamage(float distance) {
int dmg = (int) ceil((distance - 3));
if (dmg > 0) {
SetHealthPacket packet(SetHealthPacket::HEALTH_MODIFY_OFFSET + dmg);
_mc->raknetInstance->send(owner, packet);
}
super::causeFallDamage(distance);
}

View File

@@ -15,7 +15,7 @@ class ServerPlayer: public Player,
{ {
typedef Player super; typedef Player super;
public: public:
ServerPlayer(Minecraft* minecraft, Level* level, bool proto); ServerPlayer(Minecraft* minecraft, Level* level);
~ServerPlayer(); ~ServerPlayer();
@@ -43,17 +43,6 @@ public:
virtual void stopSleepInBed(bool forcefulWakeUp, bool updateLevelList, bool saveRespawnPoint); virtual void stopSleepInBed(bool forcefulWakeUp, bool updateLevelList, bool saveRespawnPoint);
void completeUsingItem(); void completeUsingItem();
void setLastMoveTicks(int lastMoveTicks) { this->lastMoveTicks = lastMoveTicks; }
int getLastMoveTicks() { return lastMoveTicks; }
void setTicksInAir(int ticksInAir) { this->ticksInAir = ticksInAir; }
int getTicksInAir() { return ticksInAir; }
void setNewProto(bool proto) { isNewProto = proto; }
bool getProto() { return isNewProto; }
virtual void causeFallDamage(float distance);
private: private:
void nextContainerCounter(); void nextContainerCounter();
void setContainerMenu( BaseContainerMenu* menu ); void setContainerMenu( BaseContainerMenu* menu );
@@ -61,11 +50,6 @@ private:
Minecraft* _mc; Minecraft* _mc;
int _prevHealth; int _prevHealth;
int _containerCounter; int _containerCounter;
int lastMoveTicks = 0;
int ticksInAir = 0;
bool isNewProto = false;
}; };
#endif /*ServerPlayer_H__*/ #endif /*ServerPlayer_H__*/

Some files were not shown because too many files have changed in this diff Show More