mirror of
https://github.com/smartcmd/MinecraftConsoles.git
synced 2026-08-20 09:57:09 +00:00
Merge branch 'main' into fixchat
This commit is contained in:
commit
763ca13817
|
|
@ -739,9 +739,9 @@ void Chunk::rebuild_SPU()
|
||||||
{
|
{
|
||||||
// 4J - get tile from those copied into our local array in earlier optimisation
|
// 4J - get tile from those copied into our local array in earlier optimisation
|
||||||
unsigned char tileId = pOutData->getTile(x,y,z);
|
unsigned char tileId = pOutData->getTile(x,y,z);
|
||||||
if (tileId > 0)
|
if (tileId > 0 && tileId != 0xff)
|
||||||
{
|
{
|
||||||
if (currentLayer == 0 && Tile::tiles[tileId]->isEntityTile())
|
if (currentLayer == 0 && Tile::tiles[tileId] && Tile::tiles[tileId]->isEntityTile())
|
||||||
{
|
{
|
||||||
shared_ptr<TileEntity> et = region.getTileEntity(x, y, z);
|
shared_ptr<TileEntity> et = region.getTileEntity(x, y, z);
|
||||||
if (TileEntityRenderDispatcher::instance->hasRenderer(et))
|
if (TileEntityRenderDispatcher::instance->hasRenderer(et))
|
||||||
|
|
@ -754,6 +754,7 @@ void Chunk::rebuild_SPU()
|
||||||
{
|
{
|
||||||
|
|
||||||
Tile *tile = Tile::tiles[tileId];
|
Tile *tile = Tile::tiles[tileId];
|
||||||
|
if (!tile) continue;
|
||||||
int renderLayer = tile->getRenderLayer();
|
int renderLayer = tile->getRenderLayer();
|
||||||
|
|
||||||
if (renderLayer != currentLayer)
|
if (renderLayer != currentLayer)
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "ClientConstants.h"
|
#include "ClientConstants.h"
|
||||||
|
|
||||||
const wstring ClientConstants::VERSION_STRING = wstring(L"Minecraft LCE ") + VER_FILEVERSION_STR_W;//+ SharedConstants::VERSION_STRING;
|
const wstring ClientConstants::VERSION_STRING = wstring(L"Minecraft LCE ") + VER_FILEVERSION_STR_W;//+ SharedConstants::VERSION_STRING;
|
||||||
|
const wstring ClientConstants::BRANCH_STRING = VER_BRANCHVERSION_STR_W;
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ class ClientConstants
|
||||||
// INTERNAL DEVELOPMENT SETTINGS
|
// INTERNAL DEVELOPMENT SETTINGS
|
||||||
public:
|
public:
|
||||||
static const wstring VERSION_STRING;
|
static const wstring VERSION_STRING;
|
||||||
|
static const wstring BRANCH_STRING;
|
||||||
|
|
||||||
static const bool DEADMAU5_CAMERA_CHEATS = false;
|
static const bool DEADMAU5_CAMERA_CHEATS = false;
|
||||||
};
|
};
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define VER_PRODUCTBUILD 560
|
#define VER_PRODUCTBUILD 560
|
||||||
#define VER_PRODUCTVERSION_STR_W L"DEV (unknown)"
|
#define VER_PRODUCTVERSION_STR_W L"DEV (unknown version)"
|
||||||
#define VER_FILEVERSION_STR_W VER_PRODUCTVERSION_STR_W
|
#define VER_FILEVERSION_STR_W VER_PRODUCTVERSION_STR_W
|
||||||
|
#define VER_BRANCHVERSION_STR_W L"UNKNOWN BRANCH"
|
||||||
#define VER_NETWORK VER_PRODUCTBUILD
|
#define VER_NETWORK VER_PRODUCTBUILD
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,10 @@ private:
|
||||||
struct GammaCBData
|
struct GammaCBData
|
||||||
{
|
{
|
||||||
float gamma;
|
float gamma;
|
||||||
float pad[3];
|
float pad;
|
||||||
|
float uvOffsetX, uvOffsetY;
|
||||||
|
float uvScaleX, uvScaleY;
|
||||||
|
float pad2[2];
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char* g_gammaVSCode;
|
static const char* g_gammaVSCode;
|
||||||
|
|
|
||||||
|
|
@ -143,13 +143,17 @@ void UIComponent_Chat::render(S32 width, S32 height, C4JRender::eViewportType vi
|
||||||
|
|
||||||
F32 scale;
|
F32 scale;
|
||||||
ComputeTileScale(tileWidth, tileHeight, m_movieWidth, m_movieHeight, needsYTile, scale, tileYStart);
|
ComputeTileScale(tileWidth, tileHeight, m_movieWidth, m_movieHeight, needsYTile, scale, tileYStart);
|
||||||
IggyPlayerSetDisplaySize( getMovie(), (S32)(m_movieWidth * scale), (S32)(m_movieHeight * scale) );
|
|
||||||
|
|
||||||
S32 contentOffX, contentOffY;
|
// For vertical split, scale down to fit the full SWF height when the
|
||||||
ComputeSplitContentOffset(viewport, m_movieWidth, m_movieHeight, scale, tileWidth, tileHeight, tileYStart, contentOffX, contentOffY);
|
// window is shorter than the movie (same fix as HUD).
|
||||||
xPos += contentOffX;
|
if(!needsYTile && m_movieHeight > 0)
|
||||||
yPos += contentOffY;
|
{
|
||||||
ui.setupRenderPosition(xPos, yPos);
|
F32 scaleH = (F32)tileHeight / (F32)m_movieHeight;
|
||||||
|
if(scaleH < scale)
|
||||||
|
scale = scaleH;
|
||||||
|
}
|
||||||
|
|
||||||
|
IggyPlayerSetDisplaySize( getMovie(), (S32)(m_movieWidth * scale), (S32)(m_movieHeight * scale) );
|
||||||
|
|
||||||
IggyPlayerDrawTilesStart ( getMovie() );
|
IggyPlayerDrawTilesStart ( getMovie() );
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -247,13 +247,17 @@ void UIComponent_Tooltips::render(S32 width, S32 height, C4JRender::eViewportTyp
|
||||||
|
|
||||||
F32 scale;
|
F32 scale;
|
||||||
ComputeTileScale(tileWidth, tileHeight, m_movieWidth, m_movieHeight, needsYTile, scale, tileYStart);
|
ComputeTileScale(tileWidth, tileHeight, m_movieWidth, m_movieHeight, needsYTile, scale, tileYStart);
|
||||||
IggyPlayerSetDisplaySize( getMovie(), (S32)(m_movieWidth * scale), (S32)(m_movieHeight * scale) );
|
|
||||||
|
|
||||||
S32 contentOffX, contentOffY;
|
// For vertical split, scale down to fit the full SWF height when the
|
||||||
ComputeSplitContentOffset(viewport, m_movieWidth, m_movieHeight, scale, tileWidth, tileHeight, tileYStart, contentOffX, contentOffY);
|
// window is shorter than the movie (same fix as HUD).
|
||||||
xPos += contentOffX;
|
if(!needsYTile && m_movieHeight > 0)
|
||||||
yPos += contentOffY;
|
{
|
||||||
ui.setupRenderPosition(xPos, yPos);
|
F32 scaleH = (F32)tileHeight / (F32)m_movieHeight;
|
||||||
|
if(scaleH < scale)
|
||||||
|
scale = scaleH;
|
||||||
|
}
|
||||||
|
|
||||||
|
IggyPlayerSetDisplaySize( getMovie(), (S32)(m_movieWidth * scale), (S32)(m_movieHeight * scale) );
|
||||||
|
|
||||||
IggyPlayerDrawTilesStart ( getMovie() );
|
IggyPlayerDrawTilesStart ( getMovie() );
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -522,33 +522,9 @@ void UIController::tick()
|
||||||
|
|
||||||
void UIController::loadSkins()
|
void UIController::loadSkins()
|
||||||
{
|
{
|
||||||
wstring platformSkinPath = L"";
|
|
||||||
|
|
||||||
#ifdef __PS3__
|
#ifdef __PS3__
|
||||||
platformSkinPath = L"skinPS3.swf";
|
m_iggyLibraries[eLibrary_Platform] = loadSkin(L"skinPS3.swf", L"platformskin.swf");
|
||||||
#elif defined __PSVITA__
|
|
||||||
platformSkinPath = L"skinVita.swf";
|
|
||||||
#elif defined _WINDOWS64
|
|
||||||
// Windows64/Durango/Orbis always load HD skin libraries unconditionally,
|
|
||||||
// which import "platformskinHD.swf" by name. The platform skin must
|
|
||||||
// therefore always be the HD variant regardless of screen resolution.
|
|
||||||
platformSkinPath = L"skinHDWin.swf";
|
|
||||||
#elif defined _DURANGO
|
|
||||||
platformSkinPath = L"skinHDDurango.swf";
|
|
||||||
#elif defined __ORBIS__
|
|
||||||
platformSkinPath = L"skinHDOrbis.swf";
|
|
||||||
|
|
||||||
#endif
|
|
||||||
// Every platform has one of these, so nothing shared.
|
|
||||||
// On HD platforms (Win64/Durango/Orbis) the skin libraries always import
|
|
||||||
// "platformskinHD.swf", so we must register under that name at any resolution.
|
|
||||||
#if defined(_WINDOWS64) || defined(_DURANGO) || defined(__ORBIS__)
|
|
||||||
m_iggyLibraries[eLibrary_Platform] = loadSkin(platformSkinPath, L"platformskinHD.swf");
|
|
||||||
#else
|
|
||||||
m_iggyLibraries[eLibrary_Platform] = loadSkin(platformSkinPath, L"platformskin.swf");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__PS3__) || defined(__PSVITA__)
|
|
||||||
m_iggyLibraries[eLibrary_GraphicsDefault] = loadSkin(L"skinGraphics.swf", L"skinGraphics.swf");
|
m_iggyLibraries[eLibrary_GraphicsDefault] = loadSkin(L"skinGraphics.swf", L"skinGraphics.swf");
|
||||||
m_iggyLibraries[eLibrary_GraphicsHUD] = loadSkin(L"skinGraphicsHud.swf", L"skinGraphicsHud.swf");
|
m_iggyLibraries[eLibrary_GraphicsHUD] = loadSkin(L"skinGraphicsHud.swf", L"skinGraphicsHud.swf");
|
||||||
m_iggyLibraries[eLibrary_GraphicsInGame] = loadSkin(L"skinGraphicsInGame.swf", L"skinGraphicsInGame.swf");
|
m_iggyLibraries[eLibrary_GraphicsInGame] = loadSkin(L"skinGraphicsInGame.swf", L"skinGraphicsInGame.swf");
|
||||||
|
|
@ -559,13 +535,28 @@ void UIController::loadSkins()
|
||||||
m_iggyLibraries[eLibrary_HUD] = loadSkin(L"skinHud.swf", L"skinHud.swf");
|
m_iggyLibraries[eLibrary_HUD] = loadSkin(L"skinHud.swf", L"skinHud.swf");
|
||||||
m_iggyLibraries[eLibrary_Tooltips] = loadSkin(L"skinTooltips.swf", L"skinTooltips.swf");
|
m_iggyLibraries[eLibrary_Tooltips] = loadSkin(L"skinTooltips.swf", L"skinTooltips.swf");
|
||||||
m_iggyLibraries[eLibrary_Default] = loadSkin(L"skin.swf", L"skin.swf");
|
m_iggyLibraries[eLibrary_Default] = loadSkin(L"skin.swf", L"skin.swf");
|
||||||
#endif
|
|
||||||
|
|
||||||
#if ( defined(_WINDOWS64) || defined(_DURANGO) || defined(__ORBIS__) )
|
#elif defined __PSVITA__
|
||||||
|
m_iggyLibraries[eLibrary_Platform] = loadSkin(L"skinVita.swf", L"platformskin.swf");
|
||||||
|
|
||||||
#if defined(_WINDOWS64)
|
m_iggyLibraries[eLibrary_GraphicsDefault] = loadSkin(L"skinGraphics.swf", L"skinGraphics.swf");
|
||||||
// 4J Stu - Load the 720/480 skins so that we have something to fallback on during development
|
m_iggyLibraries[eLibrary_GraphicsHUD] = loadSkin(L"skinGraphicsHud.swf", L"skinGraphicsHud.swf");
|
||||||
#ifndef _FINAL_BUILD
|
m_iggyLibraries[eLibrary_GraphicsInGame] = loadSkin(L"skinGraphicsInGame.swf", L"skinGraphicsInGame.swf");
|
||||||
|
m_iggyLibraries[eLibrary_GraphicsTooltips] = loadSkin(L"skinGraphicsTooltips.swf", L"skinGraphicsTooltips.swf");
|
||||||
|
m_iggyLibraries[eLibrary_GraphicsLabels] = loadSkin(L"skinGraphicsLabels.swf", L"skinGraphicsLabels.swf");
|
||||||
|
m_iggyLibraries[eLibrary_Labels] = loadSkin(L"skinLabels.swf", L"skinLabels.swf");
|
||||||
|
m_iggyLibraries[eLibrary_InGame] = loadSkin(L"skinInGame.swf", L"skinInGame.swf");
|
||||||
|
m_iggyLibraries[eLibrary_HUD] = loadSkin(L"skinHud.swf", L"skinHud.swf");
|
||||||
|
m_iggyLibraries[eLibrary_Tooltips] = loadSkin(L"skinTooltips.swf", L"skinTooltips.swf");
|
||||||
|
m_iggyLibraries[eLibrary_Default] = loadSkin(L"skin.swf", L"skin.swf");
|
||||||
|
|
||||||
|
#elif defined _WINDOWS64
|
||||||
|
// HD platform skin — required by skinHD*.swf (1080p scene SWFs)
|
||||||
|
m_iggyLibraries[eLibrary_Platform] = loadSkin(L"skinHDWin.swf", L"platformskinHD.swf");
|
||||||
|
// Non-HD platform skin — required by skin*.swf (720p/480p scene SWFs)
|
||||||
|
m_iggyLibraries[eLibraryFallback_Platform] = loadSkin(L"skinWin.swf", L"platformskin.swf");
|
||||||
|
|
||||||
|
// Non-HD skin set (720p/480p scenes import these)
|
||||||
m_iggyLibraries[eLibraryFallback_GraphicsDefault] = loadSkin(L"skinGraphics.swf", L"skinGraphics.swf");
|
m_iggyLibraries[eLibraryFallback_GraphicsDefault] = loadSkin(L"skinGraphics.swf", L"skinGraphics.swf");
|
||||||
m_iggyLibraries[eLibraryFallback_GraphicsHUD] = loadSkin(L"skinGraphicsHud.swf", L"skinGraphicsHud.swf");
|
m_iggyLibraries[eLibraryFallback_GraphicsHUD] = loadSkin(L"skinGraphicsHud.swf", L"skinGraphicsHud.swf");
|
||||||
m_iggyLibraries[eLibraryFallback_GraphicsInGame] = loadSkin(L"skinGraphicsInGame.swf", L"skinGraphicsInGame.swf");
|
m_iggyLibraries[eLibraryFallback_GraphicsInGame] = loadSkin(L"skinGraphicsInGame.swf", L"skinGraphicsInGame.swf");
|
||||||
|
|
@ -576,8 +567,21 @@ void UIController::loadSkins()
|
||||||
m_iggyLibraries[eLibraryFallback_HUD] = loadSkin(L"skinHud.swf", L"skinHud.swf");
|
m_iggyLibraries[eLibraryFallback_HUD] = loadSkin(L"skinHud.swf", L"skinHud.swf");
|
||||||
m_iggyLibraries[eLibraryFallback_Tooltips] = loadSkin(L"skinTooltips.swf", L"skinTooltips.swf");
|
m_iggyLibraries[eLibraryFallback_Tooltips] = loadSkin(L"skinTooltips.swf", L"skinTooltips.swf");
|
||||||
m_iggyLibraries[eLibraryFallback_Default] = loadSkin(L"skin.swf", L"skin.swf");
|
m_iggyLibraries[eLibraryFallback_Default] = loadSkin(L"skin.swf", L"skin.swf");
|
||||||
#endif
|
|
||||||
#endif
|
// HD skin set (1080p scenes import these)
|
||||||
|
m_iggyLibraries[eLibrary_GraphicsDefault] = loadSkin(L"skinHDGraphics.swf", L"skinHDGraphics.swf");
|
||||||
|
m_iggyLibraries[eLibrary_GraphicsHUD] = loadSkin(L"skinHDGraphicsHud.swf", L"skinHDGraphicsHud.swf");
|
||||||
|
m_iggyLibraries[eLibrary_GraphicsInGame] = loadSkin(L"skinHDGraphicsInGame.swf", L"skinHDGraphicsInGame.swf");
|
||||||
|
m_iggyLibraries[eLibrary_GraphicsTooltips] = loadSkin(L"skinHDGraphicsTooltips.swf", L"skinHDGraphicsTooltips.swf");
|
||||||
|
m_iggyLibraries[eLibrary_GraphicsLabels] = loadSkin(L"skinHDGraphicsLabels.swf", L"skinHDGraphicsLabels.swf");
|
||||||
|
m_iggyLibraries[eLibrary_Labels] = loadSkin(L"skinHDLabels.swf", L"skinHDLabels.swf");
|
||||||
|
m_iggyLibraries[eLibrary_InGame] = loadSkin(L"skinHDInGame.swf", L"skinHDInGame.swf");
|
||||||
|
m_iggyLibraries[eLibrary_HUD] = loadSkin(L"skinHDHud.swf", L"skinHDHud.swf");
|
||||||
|
m_iggyLibraries[eLibrary_Tooltips] = loadSkin(L"skinHDTooltips.swf", L"skinHDTooltips.swf");
|
||||||
|
m_iggyLibraries[eLibrary_Default] = loadSkin(L"skinHD.swf", L"skinHD.swf");
|
||||||
|
|
||||||
|
#elif defined _DURANGO
|
||||||
|
m_iggyLibraries[eLibrary_Platform] = loadSkin(L"skinHDDurango.swf", L"platformskinHD.swf");
|
||||||
|
|
||||||
m_iggyLibraries[eLibrary_GraphicsDefault] = loadSkin(L"skinHDGraphics.swf", L"skinHDGraphics.swf");
|
m_iggyLibraries[eLibrary_GraphicsDefault] = loadSkin(L"skinHDGraphics.swf", L"skinHDGraphics.swf");
|
||||||
m_iggyLibraries[eLibrary_GraphicsHUD] = loadSkin(L"skinHDGraphicsHud.swf", L"skinHDGraphicsHud.swf");
|
m_iggyLibraries[eLibrary_GraphicsHUD] = loadSkin(L"skinHDGraphicsHud.swf", L"skinHDGraphicsHud.swf");
|
||||||
|
|
@ -589,7 +593,21 @@ void UIController::loadSkins()
|
||||||
m_iggyLibraries[eLibrary_HUD] = loadSkin(L"skinHDHud.swf", L"skinHDHud.swf");
|
m_iggyLibraries[eLibrary_HUD] = loadSkin(L"skinHDHud.swf", L"skinHDHud.swf");
|
||||||
m_iggyLibraries[eLibrary_Tooltips] = loadSkin(L"skinHDTooltips.swf", L"skinHDTooltips.swf");
|
m_iggyLibraries[eLibrary_Tooltips] = loadSkin(L"skinHDTooltips.swf", L"skinHDTooltips.swf");
|
||||||
m_iggyLibraries[eLibrary_Default] = loadSkin(L"skinHD.swf", L"skinHD.swf");
|
m_iggyLibraries[eLibrary_Default] = loadSkin(L"skinHD.swf", L"skinHD.swf");
|
||||||
#endif // HD platforms
|
|
||||||
|
#elif defined __ORBIS__
|
||||||
|
m_iggyLibraries[eLibrary_Platform] = loadSkin(L"skinHDOrbis.swf", L"platformskinHD.swf");
|
||||||
|
|
||||||
|
m_iggyLibraries[eLibrary_GraphicsDefault] = loadSkin(L"skinHDGraphics.swf", L"skinHDGraphics.swf");
|
||||||
|
m_iggyLibraries[eLibrary_GraphicsHUD] = loadSkin(L"skinHDGraphicsHud.swf", L"skinHDGraphicsHud.swf");
|
||||||
|
m_iggyLibraries[eLibrary_GraphicsInGame] = loadSkin(L"skinHDGraphicsInGame.swf", L"skinHDGraphicsInGame.swf");
|
||||||
|
m_iggyLibraries[eLibrary_GraphicsTooltips] = loadSkin(L"skinHDGraphicsTooltips.swf", L"skinHDGraphicsTooltips.swf");
|
||||||
|
m_iggyLibraries[eLibrary_GraphicsLabels] = loadSkin(L"skinHDGraphicsLabels.swf", L"skinHDGraphicsLabels.swf");
|
||||||
|
m_iggyLibraries[eLibrary_Labels] = loadSkin(L"skinHDLabels.swf", L"skinHDLabels.swf");
|
||||||
|
m_iggyLibraries[eLibrary_InGame] = loadSkin(L"skinHDInGame.swf", L"skinHDInGame.swf");
|
||||||
|
m_iggyLibraries[eLibrary_HUD] = loadSkin(L"skinHDHud.swf", L"skinHDHud.swf");
|
||||||
|
m_iggyLibraries[eLibrary_Tooltips] = loadSkin(L"skinHDTooltips.swf", L"skinHDTooltips.swf");
|
||||||
|
m_iggyLibraries[eLibrary_Default] = loadSkin(L"skinHD.swf", L"skinHD.swf");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
IggyLibrary UIController::loadSkin(const wstring &skinPath, const wstring &skinName)
|
IggyLibrary UIController::loadSkin(const wstring &skinPath, const wstring &skinName)
|
||||||
|
|
@ -1810,14 +1828,24 @@ GDrawTexture * RADLINK UIController::TextureSubstitutionCreateCallback ( void *
|
||||||
|
|
||||||
// 4J Stu - All our flash controls that allow replacing textures use a special 64x64 symbol
|
// 4J Stu - All our flash controls that allow replacing textures use a special 64x64 symbol
|
||||||
// Force this size here so that our images don't get scaled wildly
|
// Force this size here so that our images don't get scaled wildly
|
||||||
#if (defined __ORBIS__ || defined _DURANGO || defined _WINDOWS64 )
|
#if (defined __ORBIS__ || defined _DURANGO )
|
||||||
*width = 96;
|
*width = 96;
|
||||||
*height = 96;
|
*height = 96;
|
||||||
#else
|
#else
|
||||||
*width = 64;
|
*width = 64;
|
||||||
*height = 64;
|
*height = 64;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined _WINDOWS64
|
||||||
|
// Only set the size to 96x96 for 1080p on Windows
|
||||||
|
UIScene *scene = uiController->GetTopScene(0);
|
||||||
|
if (scene->getSceneResolution() == UIScene::eSceneResolution_1080)
|
||||||
|
{
|
||||||
|
*width = 96;
|
||||||
|
*height = 96;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
*destroy_callback_data = (void *)id;
|
*destroy_callback_data = (void *)id;
|
||||||
|
|
||||||
app.DebugPrintf("Found substitution texture %ls (%d) - %dx%d\n", static_cast<wchar_t *>(texture_name), id, image.getWidth(), image.getHeight());
|
app.DebugPrintf("Found substitution texture %ls (%d) - %dx%d\n", static_cast<wchar_t *>(texture_name), id, image.getWidth(), image.getHeight());
|
||||||
|
|
|
||||||
|
|
@ -101,9 +101,8 @@ private:
|
||||||
eLibrary_Tooltips,
|
eLibrary_Tooltips,
|
||||||
eLibrary_Default,
|
eLibrary_Default,
|
||||||
|
|
||||||
#if ( defined(_WINDOWS64) )
|
#if defined(_WINDOWS64)
|
||||||
// 4J Stu - Load the 720/480 skins so that we have something to fallback on during development
|
// Non-HD skin libraries needed by 720p/480p scene SWFs.
|
||||||
#ifndef _FINAL_BUILD
|
|
||||||
eLibraryFallback_Platform,
|
eLibraryFallback_Platform,
|
||||||
eLibraryFallback_GraphicsDefault,
|
eLibraryFallback_GraphicsDefault,
|
||||||
eLibraryFallback_GraphicsHUD,
|
eLibraryFallback_GraphicsHUD,
|
||||||
|
|
@ -115,7 +114,6 @@ private:
|
||||||
eLibraryFallback_HUD,
|
eLibraryFallback_HUD,
|
||||||
eLibraryFallback_Tooltips,
|
eLibraryFallback_Tooltips,
|
||||||
eLibraryFallback_Default,
|
eLibraryFallback_Default,
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
eLibrary_Count,
|
eLibrary_Count,
|
||||||
|
|
|
||||||
|
|
@ -286,8 +286,16 @@ void UIScene::loadMovie()
|
||||||
moviePath.append(L"Vita.swf");
|
moviePath.append(L"Vita.swf");
|
||||||
m_loadedResolution = eSceneResolution_Vita;
|
m_loadedResolution = eSceneResolution_Vita;
|
||||||
#elif defined _WINDOWS64
|
#elif defined _WINDOWS64
|
||||||
moviePath.append(L"1080.swf");
|
if(ui.getScreenHeight() > 720.0f)
|
||||||
m_loadedResolution = eSceneResolution_1080;
|
{
|
||||||
|
moviePath.append(L"1080.swf");
|
||||||
|
m_loadedResolution = eSceneResolution_1080;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
moviePath.append(L"720.swf");
|
||||||
|
m_loadedResolution = eSceneResolution_720;
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
moviePath.append(L"1080.swf");
|
moviePath.append(L"1080.swf");
|
||||||
m_loadedResolution = eSceneResolution_1080;
|
m_loadedResolution = eSceneResolution_1080;
|
||||||
|
|
|
||||||
|
|
@ -954,91 +954,70 @@ float GameRenderer::ComputeGammaFromSlider(float slider0to100)
|
||||||
|
|
||||||
void GameRenderer::CachePlayerGammas()
|
void GameRenderer::CachePlayerGammas()
|
||||||
{
|
{
|
||||||
for (int j = 0; j < XUSER_MAX_COUNT && j < NUM_LIGHT_TEXTURES; ++j)
|
const float slider = app.GetGameSettings(ProfileManager.GetPrimaryPad(), eGameSetting_Gamma);
|
||||||
{
|
const float gamma = ComputeGammaFromSlider(slider);
|
||||||
std::shared_ptr<MultiplayerLocalPlayer> player = Minecraft::GetInstance()->localplayers[j];
|
|
||||||
if (!player)
|
|
||||||
{
|
|
||||||
m_cachedGammaPerPlayer[j] = 1.0f;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const float slider = app.GetGameSettings(j, eGameSetting_Gamma); // 0..100
|
for (int j = 0; j < XUSER_MAX_COUNT && j < NUM_LIGHT_TEXTURES; ++j)
|
||||||
m_cachedGammaPerPlayer[j] = ComputeGammaFromSlider(slider);
|
m_cachedGammaPerPlayer[j] = gamma;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GameRenderer::ComputeViewportForPlayer(int j, D3D11_VIEWPORT &outViewport) const
|
bool GameRenderer::ComputeViewportForPlayer(int j, D3D11_VIEWPORT &outViewport) const
|
||||||
{
|
{
|
||||||
// Use the actual backbuffer dimensions so viewports adapt to window resize.
|
|
||||||
extern int g_rScreenWidth;
|
extern int g_rScreenWidth;
|
||||||
extern int g_rScreenHeight;
|
extern int g_rScreenHeight;
|
||||||
|
|
||||||
int active = 0;
|
std::shared_ptr<MultiplayerLocalPlayer> player = Minecraft::GetInstance()->localplayers[j];
|
||||||
int indexMap[NUM_LIGHT_TEXTURES] = {-1, -1, -1, -1};
|
if (!player)
|
||||||
for (int i = 0; i < XUSER_MAX_COUNT && i < NUM_LIGHT_TEXTURES; ++i)
|
|
||||||
{
|
|
||||||
if (Minecraft::GetInstance()->localplayers[i])
|
|
||||||
indexMap[active++] = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (active <= 1)
|
|
||||||
{
|
|
||||||
outViewport.TopLeftX = 0.0f;
|
|
||||||
outViewport.TopLeftY = 0.0f;
|
|
||||||
outViewport.Width = static_cast<FLOAT>(g_rScreenWidth);
|
|
||||||
outViewport.Height = static_cast<FLOAT>(g_rScreenHeight);
|
|
||||||
outViewport.MinDepth = 0.0f;
|
|
||||||
outViewport.MaxDepth = 1.0f;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
int k = -1;
|
|
||||||
for (int ord = 0; ord < active; ++ord)
|
|
||||||
if (indexMap[ord] == j)
|
|
||||||
{
|
|
||||||
k = ord;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (k < 0)
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
const float width = static_cast<float>(g_rScreenWidth);
|
const float w = static_cast<float>(g_rScreenWidth);
|
||||||
const float height = static_cast<float>(g_rScreenHeight);
|
const float h = static_cast<float>(g_rScreenHeight);
|
||||||
|
const float halfW = w * 0.5f;
|
||||||
|
const float halfH = h * 0.5f;
|
||||||
|
|
||||||
if (active == 2)
|
outViewport.MinDepth = 0.0f;
|
||||||
|
outViewport.MaxDepth = 1.0f;
|
||||||
|
|
||||||
|
switch (static_cast<C4JRender::eViewportType>(player->m_iScreenSection))
|
||||||
{
|
{
|
||||||
const float halfH = height * 0.5f;
|
case C4JRender::VIEWPORT_TYPE_SPLIT_TOP:
|
||||||
outViewport.TopLeftX = 0.0f;
|
outViewport.TopLeftX = 0; outViewport.TopLeftY = 0;
|
||||||
outViewport.Width = width;
|
outViewport.Width = w; outViewport.Height = halfH;
|
||||||
outViewport.MinDepth = 0.0f;
|
break;
|
||||||
outViewport.MaxDepth = 1.0f;
|
case C4JRender::VIEWPORT_TYPE_SPLIT_BOTTOM:
|
||||||
if (k == 0)
|
outViewport.TopLeftX = 0; outViewport.TopLeftY = halfH;
|
||||||
{
|
outViewport.Width = w; outViewport.Height = halfH;
|
||||||
outViewport.TopLeftY = 0.0f;
|
break;
|
||||||
outViewport.Height = halfH;
|
case C4JRender::VIEWPORT_TYPE_SPLIT_LEFT:
|
||||||
}
|
outViewport.TopLeftX = 0; outViewport.TopLeftY = 0;
|
||||||
else
|
outViewport.Width = halfW; outViewport.Height = h;
|
||||||
{
|
break;
|
||||||
outViewport.TopLeftY = halfH;
|
case C4JRender::VIEWPORT_TYPE_SPLIT_RIGHT:
|
||||||
outViewport.Height = halfH;
|
outViewport.TopLeftX = halfW; outViewport.TopLeftY = 0;
|
||||||
}
|
outViewport.Width = halfW; outViewport.Height = h;
|
||||||
return true;
|
break;
|
||||||
}
|
case C4JRender::VIEWPORT_TYPE_QUADRANT_TOP_LEFT:
|
||||||
else
|
outViewport.TopLeftX = 0; outViewport.TopLeftY = 0;
|
||||||
{
|
outViewport.Width = halfW; outViewport.Height = halfH;
|
||||||
const float halfW = width * 0.5f;
|
break;
|
||||||
const float halfH = height * 0.5f;
|
case C4JRender::VIEWPORT_TYPE_QUADRANT_TOP_RIGHT:
|
||||||
const int row = (k >= 2) ? 1 : 0;
|
outViewport.TopLeftX = halfW; outViewport.TopLeftY = 0;
|
||||||
const int col = (k % 2);
|
outViewport.Width = halfW; outViewport.Height = halfH;
|
||||||
outViewport.TopLeftX = col ? halfW : 0.0f;
|
break;
|
||||||
outViewport.TopLeftY = row ? halfH : 0.0f;
|
case C4JRender::VIEWPORT_TYPE_QUADRANT_BOTTOM_LEFT:
|
||||||
outViewport.Width = halfW;
|
outViewport.TopLeftX = 0; outViewport.TopLeftY = halfH;
|
||||||
outViewport.Height = halfH;
|
outViewport.Width = halfW; outViewport.Height = halfH;
|
||||||
outViewport.MinDepth = 0.0f;
|
break;
|
||||||
outViewport.MaxDepth = 1.0f;
|
case C4JRender::VIEWPORT_TYPE_QUADRANT_BOTTOM_RIGHT:
|
||||||
return true;
|
outViewport.TopLeftX = halfW; outViewport.TopLeftY = halfH;
|
||||||
|
outViewport.Width = halfW; outViewport.Height = halfH;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
outViewport.TopLeftX = 0; outViewport.TopLeftY = 0;
|
||||||
|
outViewport.Width = w; outViewport.Height = h;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t GameRenderer::BuildPlayerViewports(D3D11_VIEWPORT *outViewports, float *outGammas, UINT maxCount) const
|
uint32_t GameRenderer::BuildPlayerViewports(D3D11_VIEWPORT *outViewports, float *outGammas, UINT maxCount) const
|
||||||
|
|
|
||||||
|
|
@ -851,7 +851,10 @@ void Gui::render(float a, bool mouseFree, int xMouse, int yMouse)
|
||||||
|
|
||||||
#ifndef _FINAL_BUILD
|
#ifndef _FINAL_BUILD
|
||||||
MemSect(31);
|
MemSect(31);
|
||||||
if (minecraft->options->renderDebug && minecraft->player != nullptr && minecraft->level != nullptr)
|
|
||||||
|
// temporarily render overlay at all times so version is more obvious in bug reports
|
||||||
|
// we can turn this off once things stabilize
|
||||||
|
if (true)// minecraft->options->renderDebug && minecraft->player != nullptr && minecraft->level != nullptr)
|
||||||
{
|
{
|
||||||
const int debugLeft = 1;
|
const int debugLeft = 1;
|
||||||
const int debugTop = 1;
|
const int debugTop = 1;
|
||||||
|
|
@ -870,117 +873,120 @@ void Gui::render(float a, bool mouseFree, int xMouse, int yMouse)
|
||||||
vector<wstring> lines;
|
vector<wstring> lines;
|
||||||
|
|
||||||
lines.push_back(ClientConstants::VERSION_STRING);
|
lines.push_back(ClientConstants::VERSION_STRING);
|
||||||
lines.push_back(minecraft->fpsString);
|
lines.push_back(ClientConstants::BRANCH_STRING);
|
||||||
lines.push_back(L"E: " + std::to_wstring(minecraft->level->getAllEntities().size())); // Could maybe use entity::shouldRender to work out how many are rendered but thats like expensive
|
if (minecraft->options->renderDebug && minecraft->player != nullptr && minecraft->level != nullptr)
|
||||||
// TODO Add server information with packet counts - once multiplayer is more stable
|
|
||||||
int renderDistance = app.GetGameSettings(iPad, eGameSetting_RenderDistance);
|
|
||||||
// Calculate the chunk sections using 16 * (2n + 1)^2
|
|
||||||
lines.push_back(L"C: " + std::to_wstring(16 * (2 * renderDistance + 1) * (2 * renderDistance + 1)) + L" D: " + std::to_wstring(renderDistance));
|
|
||||||
lines.push_back(minecraft->gatherStats4()); // Chunk Cache
|
|
||||||
|
|
||||||
// Dimension
|
|
||||||
wstring dimension = L"unknown";
|
|
||||||
switch (minecraft->player->dimension)
|
|
||||||
{
|
{
|
||||||
case -1:
|
lines.push_back(minecraft->fpsString);
|
||||||
dimension = L"minecraft:the_nether";
|
lines.push_back(L"E: " + std::to_wstring(minecraft->level->getAllEntities().size())); // Could maybe use entity::shouldRender to work out how many are rendered but thats like expensive
|
||||||
break;
|
// TODO Add server information with packet counts - once multiplayer is more stable
|
||||||
case 0:
|
int renderDistance = app.GetGameSettings(iPad, eGameSetting_RenderDistance);
|
||||||
dimension = L"minecraft:overworld";
|
// Calculate the chunk sections using 16 * (2n + 1)^2
|
||||||
break;
|
lines.push_back(L"C: " + std::to_wstring(16 * (2 * renderDistance + 1) * (2 * renderDistance + 1)) + L" D: " + std::to_wstring(renderDistance));
|
||||||
case 1:
|
lines.push_back(minecraft->gatherStats4()); // Chunk Cache
|
||||||
dimension = L"minecraft:the_end";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
lines.push_back(dimension);
|
|
||||||
|
|
||||||
lines.push_back(L""); // Spacer
|
// Dimension
|
||||||
|
wstring dimension = L"unknown";
|
||||||
|
switch (minecraft->player->dimension)
|
||||||
|
{
|
||||||
|
case -1:
|
||||||
|
dimension = L"minecraft:the_nether";
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
dimension = L"minecraft:overworld";
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
dimension = L"minecraft:the_end";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
lines.push_back(dimension);
|
||||||
|
|
||||||
// Players block pos
|
lines.push_back(L""); // Spacer
|
||||||
int xBlockPos = Mth::floor(minecraft->player->x);
|
|
||||||
int yBlockPos = Mth::floor(minecraft->player->y);
|
|
||||||
int zBlockPos = Mth::floor(minecraft->player->z);
|
|
||||||
|
|
||||||
// Chunk player is in
|
// Players block pos
|
||||||
int xChunkPos = xBlockPos >> 4;
|
int xBlockPos = Mth::floor(minecraft->player->x);
|
||||||
int yChunkPos = yBlockPos >> 4;
|
int yBlockPos = Mth::floor(minecraft->player->y);
|
||||||
int zChunkPos = zBlockPos >> 4;
|
int zBlockPos = Mth::floor(minecraft->player->z);
|
||||||
|
|
||||||
// Players offset within the chunk
|
// Chunk player is in
|
||||||
int xChunkOffset = xBlockPos & 15;
|
int xChunkPos = xBlockPos >> 4;
|
||||||
int yChunkOffset = yBlockPos & 15;
|
int yChunkPos = yBlockPos >> 4;
|
||||||
int zChunkOffset = zBlockPos & 15;
|
int zChunkPos = zBlockPos >> 4;
|
||||||
|
|
||||||
// Format the position like java with limited decumal places
|
// Players offset within the chunk
|
||||||
WCHAR posString[44]; // Allows upto 7 digit positions (+-9_999_999)
|
int xChunkOffset = xBlockPos & 15;
|
||||||
swprintf(posString, 44, L"%.3f / %.5f / %.3f", minecraft->player->x, minecraft->player->y, minecraft->player->z);
|
int yChunkOffset = yBlockPos & 15;
|
||||||
|
int zChunkOffset = zBlockPos & 15;
|
||||||
|
|
||||||
lines.push_back(L"XYZ: " + std::wstring(posString));
|
// Format the position like java with limited decumal places
|
||||||
lines.push_back(L"Block: " + std::to_wstring(static_cast<int>(xBlockPos)) + L" " + std::to_wstring(static_cast<int>(yBlockPos)) + L" " + std::to_wstring(static_cast<int>(zBlockPos)));
|
WCHAR posString[44]; // Allows upto 7 digit positions (+-9_999_999)
|
||||||
lines.push_back(L"Chunk: " + std::to_wstring(xChunkOffset) + L" " + std::to_wstring(yChunkOffset) + L" " + std::to_wstring(zChunkOffset) + L" in " + std::to_wstring(xChunkPos) + L" " + std::to_wstring(yChunkPos) + L" " + std::to_wstring(zChunkPos));
|
swprintf(posString, 44, L"%.3f / %.5f / %.3f", minecraft->player->x, minecraft->player->y, minecraft->player->z);
|
||||||
|
|
||||||
// Wrap the yRot to 360 then adjust to (-180 to 180) range to match java
|
lines.push_back(L"XYZ: " + std::wstring(posString));
|
||||||
float yRotDisplay = fmod(minecraft->player->yRot, 360.0f);
|
lines.push_back(L"Block: " + std::to_wstring(static_cast<int>(xBlockPos)) + L" " + std::to_wstring(static_cast<int>(yBlockPos)) + L" " + std::to_wstring(static_cast<int>(zBlockPos)));
|
||||||
if (yRotDisplay > 180.0f)
|
lines.push_back(L"Chunk: " + std::to_wstring(xChunkOffset) + L" " + std::to_wstring(yChunkOffset) + L" " + std::to_wstring(zChunkOffset) + L" in " + std::to_wstring(xChunkPos) + L" " + std::to_wstring(yChunkPos) + L" " + std::to_wstring(zChunkPos));
|
||||||
{
|
|
||||||
yRotDisplay -= 360.0f;
|
// Wrap the yRot to 360 then adjust to (-180 to 180) range to match java
|
||||||
|
float yRotDisplay = fmod(minecraft->player->yRot, 360.0f);
|
||||||
|
if (yRotDisplay > 180.0f)
|
||||||
|
{
|
||||||
|
yRotDisplay -= 360.0f;
|
||||||
|
}
|
||||||
|
if (yRotDisplay < -180.0f)
|
||||||
|
{
|
||||||
|
yRotDisplay += 360.0f;
|
||||||
|
}
|
||||||
|
// Generate the angle string in the format "yRot / xRot" with one decimal place, similar to java edition
|
||||||
|
WCHAR angleString[16];
|
||||||
|
swprintf(angleString, 16, L"%.1f / %.1f", yRotDisplay, minecraft->player->xRot);
|
||||||
|
|
||||||
|
// Work out the named direction
|
||||||
|
int direction = Mth::floor(minecraft->player->yRot * 4.0f / 360.0f + 0.5) & 0x3;
|
||||||
|
wstring cardinalDirection;
|
||||||
|
switch (direction)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
cardinalDirection = L"south";
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
cardinalDirection = L"west";
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
cardinalDirection = L"north";
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
cardinalDirection = L"east";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
lines.push_back(L"Facing: " + cardinalDirection + L" (" + angleString + L")");
|
||||||
|
|
||||||
|
// We have to limit y to 256 as we don't get any information past that
|
||||||
|
if (minecraft->level != NULL && minecraft->level->hasChunkAt(xBlockPos, fmod(yBlockPos, 256), zBlockPos))
|
||||||
|
{
|
||||||
|
LevelChunk *chunkAt = minecraft->level->getChunkAt(xBlockPos, zBlockPos);
|
||||||
|
if (chunkAt != NULL)
|
||||||
|
{
|
||||||
|
int skyLight = chunkAt->getBrightness(LightLayer::Sky, xChunkOffset, yChunkOffset, zChunkOffset);
|
||||||
|
int blockLight = chunkAt->getBrightness(LightLayer::Block, xChunkOffset, yChunkOffset, zChunkOffset);
|
||||||
|
int maxLight = fmax(skyLight, blockLight);
|
||||||
|
lines.push_back(L"Light: " + std::to_wstring(maxLight) + L" (" + std::to_wstring(skyLight) + L" sky, " + std::to_wstring(blockLight) + L" block)");
|
||||||
|
|
||||||
|
lines.push_back(L"CH S: " + std::to_wstring(chunkAt->getHeightmap(xChunkOffset, zChunkOffset)));
|
||||||
|
|
||||||
|
Biome *biome = chunkAt->getBiome(xChunkOffset, zChunkOffset, minecraft->level->getBiomeSource());
|
||||||
|
lines.push_back(L"Biome: " + biome->m_name + L" (" + std::to_wstring(biome->id) + L")");
|
||||||
|
|
||||||
|
lines.push_back(L"Difficulty: " + std::to_wstring(minecraft->level->difficulty) + L" (Day " + std::to_wstring(minecraft->level->getGameTime() / Level::TICKS_PER_DAY) + L")");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is all LCE only stuff, it was never on java
|
||||||
|
lines.push_back(L""); // Spacer
|
||||||
|
lines.push_back(L"Seed: " + std::to_wstring(minecraft->level->getLevelData()->getSeed()));
|
||||||
|
lines.push_back(minecraft->gatherStats1()); // Time to autosave
|
||||||
|
lines.push_back(minecraft->gatherStats2()); // Empty currently - CPlatformNetworkManagerStub::GatherStats()
|
||||||
|
lines.push_back(minecraft->gatherStats3()); // RTT
|
||||||
}
|
}
|
||||||
if (yRotDisplay < -180.0f)
|
|
||||||
{
|
|
||||||
yRotDisplay += 360.0f;
|
|
||||||
}
|
|
||||||
// Generate the angle string in the format "yRot / xRot" with one decimal place, similar to java edition
|
|
||||||
WCHAR angleString[16];
|
|
||||||
swprintf(angleString, 16, L"%.1f / %.1f", yRotDisplay, minecraft->player->xRot);
|
|
||||||
|
|
||||||
// Work out the named direction
|
|
||||||
int direction = Mth::floor(minecraft->player->yRot * 4.0f / 360.0f + 0.5) & 0x3;
|
|
||||||
wstring cardinalDirection;
|
|
||||||
switch (direction)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
cardinalDirection = L"south";
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
cardinalDirection = L"west";
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
cardinalDirection = L"north";
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
cardinalDirection = L"east";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
lines.push_back(L"Facing: " + cardinalDirection + L" (" + angleString + L")");
|
|
||||||
|
|
||||||
// We have to limit y to 256 as we don't get any information past that
|
|
||||||
if (minecraft->level != NULL && minecraft->level->hasChunkAt(xBlockPos, fmod(yBlockPos, 256), zBlockPos))
|
|
||||||
{
|
|
||||||
LevelChunk *chunkAt = minecraft->level->getChunkAt(xBlockPos, zBlockPos);
|
|
||||||
if (chunkAt != NULL)
|
|
||||||
{
|
|
||||||
int skyLight = chunkAt->getBrightness(LightLayer::Sky, xChunkOffset, yChunkOffset, zChunkOffset);
|
|
||||||
int blockLight = chunkAt->getBrightness(LightLayer::Block, xChunkOffset, yChunkOffset, zChunkOffset);
|
|
||||||
int maxLight = fmax(skyLight, blockLight);
|
|
||||||
lines.push_back(L"Light: " + std::to_wstring(maxLight) + L" (" + std::to_wstring(skyLight) + L" sky, " + std::to_wstring(blockLight) + L" block)");
|
|
||||||
|
|
||||||
lines.push_back(L"CH S: " + std::to_wstring(chunkAt->getHeightmap(xChunkOffset, zChunkOffset)));
|
|
||||||
|
|
||||||
Biome *biome = chunkAt->getBiome(xChunkOffset, zChunkOffset, minecraft->level->getBiomeSource());
|
|
||||||
lines.push_back(L"Biome: " + biome->m_name + L" (" + std::to_wstring(biome->id) + L")");
|
|
||||||
|
|
||||||
lines.push_back(L"Difficulty: " + std::to_wstring(minecraft->level->difficulty) + L" (Day " + std::to_wstring(minecraft->level->getGameTime() / Level::TICKS_PER_DAY) + L")");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// This is all LCE only stuff, it was never on java
|
|
||||||
lines.push_back(L""); // Spacer
|
|
||||||
lines.push_back(L"Seed: " + std::to_wstring(minecraft->level->getLevelData()->getSeed()));
|
|
||||||
lines.push_back(minecraft->gatherStats1()); // Time to autosave
|
|
||||||
lines.push_back(minecraft->gatherStats2()); // Empty currently - CPlatformNetworkManagerStub::GatherStats()
|
|
||||||
lines.push_back(minecraft->gatherStats3()); // RTT
|
|
||||||
|
|
||||||
#ifdef _DEBUG // Only show terrain features in debug builds not release
|
#ifdef _DEBUG // Only show terrain features in debug builds not release
|
||||||
// TERRAIN FEATURES
|
// TERRAIN FEATURES
|
||||||
|
|
|
||||||
|
|
@ -190,34 +190,11 @@ void PendingConnection::handleLogin(shared_ptr<LoginPacket> packet)
|
||||||
}
|
}
|
||||||
else if (duplicateXuid)
|
else if (duplicateXuid)
|
||||||
{
|
{
|
||||||
// The old player is still in PlayerList (disconnect hasn't been
|
// Reject the incoming connection — a player with this UID is already
|
||||||
// processed yet). Force-close the stale connection so the
|
// on the server. Allowing duplicates causes invisible players and
|
||||||
// reconnecting client isn't rejected.
|
// other undefined behaviour.
|
||||||
app.DebugPrintf("RECONNECT: Duplicate xuid for name: %ls, forcing old connection closed\n", name.c_str());
|
app.DebugPrintf("LOGIN: Rejecting duplicate xuid for name: %ls\n", name.c_str());
|
||||||
shared_ptr<ServerPlayer> stalePlayer = server->getPlayers()->getPlayer(loginXuid);
|
disconnect(DisconnectPacket::eDisconnect_Banned);
|
||||||
if (stalePlayer == nullptr && packet->m_onlineXuid != INVALID_XUID)
|
|
||||||
stalePlayer = server->getPlayers()->getPlayer(packet->m_onlineXuid);
|
|
||||||
|
|
||||||
if (stalePlayer != nullptr && stalePlayer->connection != nullptr)
|
|
||||||
{
|
|
||||||
BYTE oldSmallId = 0;
|
|
||||||
if (stalePlayer->connection->connection != nullptr && stalePlayer->connection->connection->getSocket() != nullptr)
|
|
||||||
oldSmallId = stalePlayer->connection->connection->getSocket()->getSmallId();
|
|
||||||
app.DebugPrintf("RECONNECT: Force-disconnecting old player smallId=%d\n", oldSmallId);
|
|
||||||
stalePlayer->connection->disconnect(DisconnectPacket::eDisconnect_Closed);
|
|
||||||
|
|
||||||
// Queue the old SmallId for recycling so it's not permanently leaked.
|
|
||||||
// PlayerList::tick() will call PushFreeSmallId/ClearSocketForSmallId.
|
|
||||||
if (oldSmallId != 0)
|
|
||||||
server->getPlayers()->queueSmallIdForRecycle(oldSmallId);
|
|
||||||
|
|
||||||
app.DebugPrintf("RECONNECT: Old player force-disconnect complete\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Accept the login now that the old entry is removed.
|
|
||||||
app.DebugPrintf("RECONNECT: Calling handleAcceptedLogin for new connection\n");
|
|
||||||
handleAcceptedLogin(packet);
|
|
||||||
app.DebugPrintf("RECONNECT: handleAcceptedLogin complete\n");
|
|
||||||
}
|
}
|
||||||
#ifdef _WINDOWS64
|
#ifdef _WINDOWS64
|
||||||
else if (g_bRejectDuplicateNames)
|
else if (g_bRejectDuplicateNames)
|
||||||
|
|
|
||||||
|
|
@ -1588,13 +1588,13 @@ void PlayerConnection::handleCraftItem(shared_ptr<CraftItemPacket> packet)
|
||||||
if(iRecipe == -1)
|
if(iRecipe == -1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
int recipeCount = (int)Recipes::getInstance()->getRecipies()->size();
|
||||||
|
if(iRecipe < 0 || iRecipe >= recipeCount)
|
||||||
|
return;
|
||||||
|
|
||||||
Recipy::INGREDIENTS_REQUIRED *pRecipeIngredientsRequired=Recipes::getInstance()->getRecipeIngredientsArray();
|
Recipy::INGREDIENTS_REQUIRED *pRecipeIngredientsRequired=Recipes::getInstance()->getRecipeIngredientsArray();
|
||||||
shared_ptr<ItemInstance> pTempItemInst=pRecipeIngredientsRequired[iRecipe].pRecipy->assemble(nullptr);
|
shared_ptr<ItemInstance> pTempItemInst=pRecipeIngredientsRequired[iRecipe].pRecipy->assemble(nullptr);
|
||||||
|
|
||||||
size_t recipeCount = Recipes::getInstance()->getRecipies()->size();
|
|
||||||
if (iRecipe < 0 || iRecipe >= (int)recipeCount)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if(app.DebugSettingsOn() && (player->GetDebugOptions()&(1L<<eDebugSetting_CraftAnything)))
|
if(app.DebugSettingsOn() && (player->GetDebugOptions()&(1L<<eDebugSetting_CraftAnything)))
|
||||||
{
|
{
|
||||||
pTempItemInst->onCraftedBy(player->level, dynamic_pointer_cast<Player>( player->shared_from_this() ), pTempItemInst->count );
|
pTempItemInst->onCraftedBy(player->level, dynamic_pointer_cast<Player>( player->shared_from_this() ), pTempItemInst->count );
|
||||||
|
|
|
||||||
|
|
@ -1077,7 +1077,12 @@ void ServerLevel::entityRemoved(shared_ptr<Entity> e)
|
||||||
|
|
||||||
shared_ptr<Entity> ServerLevel::getEntity(int id)
|
shared_ptr<Entity> ServerLevel::getEntity(int id)
|
||||||
{
|
{
|
||||||
return entitiesById[id];
|
auto it = entitiesById.find(id);
|
||||||
|
if (it != entitiesById.end())
|
||||||
|
{
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ServerLevel::addGlobalEntity(shared_ptr<Entity> e)
|
bool ServerLevel::addGlobalEntity(shared_ptr<Entity> e)
|
||||||
|
|
|
||||||
|
|
@ -998,11 +998,7 @@ static void RADLINK gdraw_SetViewSizeAndWorldScale(S32 w, S32 h, F32 scalex, F32
|
||||||
{
|
{
|
||||||
static S32 s_lastW = 0, s_lastH = 0;
|
static S32 s_lastW = 0, s_lastH = 0;
|
||||||
static F32 s_lastSx = 0, s_lastSy = 0;
|
static F32 s_lastSx = 0, s_lastSy = 0;
|
||||||
if (w != s_lastW || h != s_lastH || scalex != s_lastSx || scaley != s_lastSy) {
|
|
||||||
app.DebugPrintf("[GDRAW] SetViewSize: fw=%d fh=%d scale=%.6f,%.6f frametex=%dx%d vx=%d vy=%d\n",
|
|
||||||
w, h, scalex, scaley, gdraw->frametex_width, gdraw->frametex_height, gdraw->vx, gdraw->vy);
|
|
||||||
s_lastW = w; s_lastH = h; s_lastSx = scalex; s_lastSy = scaley;
|
|
||||||
}
|
|
||||||
memset(gdraw->frame, 0, sizeof(gdraw->frame));
|
memset(gdraw->frame, 0, sizeof(gdraw->frame));
|
||||||
gdraw->cur = gdraw->frame;
|
gdraw->cur = gdraw->frame;
|
||||||
gdraw->fw = w;
|
gdraw->fw = w;
|
||||||
|
|
|
||||||
|
|
@ -404,7 +404,7 @@ bool WinsockNetLayer::JoinGame(const char* ip, int port)
|
||||||
|
|
||||||
bool WinsockNetLayer::SendOnSocket(SOCKET sock, const void* data, int dataSize)
|
bool WinsockNetLayer::SendOnSocket(SOCKET sock, const void* data, int dataSize)
|
||||||
{
|
{
|
||||||
if (sock == INVALID_SOCKET || dataSize <= 0) return false;
|
if (sock == INVALID_SOCKET || dataSize <= 0 || dataSize > WIN64_NET_MAX_PACKET_SIZE) return false;
|
||||||
|
|
||||||
// TODO: s_sendLock is a single global lock for ALL sockets. If one client's
|
// TODO: s_sendLock is a single global lock for ALL sockets. If one client's
|
||||||
// send() blocks (TCP window full, slow WiFi), every other write thread stalls
|
// send() blocks (TCP window full, slow WiFi), every other write thread stalls
|
||||||
|
|
|
||||||
|
|
@ -21,13 +21,17 @@ const char* PostProcesser::g_gammaPSCode =
|
||||||
"cbuffer GammaCB : register(b0)\n"
|
"cbuffer GammaCB : register(b0)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" float gamma;\n"
|
" float gamma;\n"
|
||||||
" float3 pad;\n"
|
" float _pad;\n"
|
||||||
|
" float2 uvOffset;\n"
|
||||||
|
" float2 uvScale;\n"
|
||||||
|
" float2 _pad2;\n"
|
||||||
"};\n"
|
"};\n"
|
||||||
"Texture2D sceneTex : register(t0);\n"
|
"Texture2D sceneTex : register(t0);\n"
|
||||||
"SamplerState sceneSampler : register(s0);\n"
|
"SamplerState sceneSampler : register(s0);\n"
|
||||||
"float4 main(float4 pos : SV_Position, float2 uv : TEXCOORD0) : SV_Target\n"
|
"float4 main(float4 pos : SV_Position, float2 uv : TEXCOORD0) : SV_Target\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" float4 color = sceneTex.Sample(sceneSampler, uv);\n"
|
" float2 texUV = uvOffset + uv * uvScale;\n"
|
||||||
|
" float4 color = sceneTex.Sample(sceneSampler, texUV);\n"
|
||||||
"\n"
|
"\n"
|
||||||
" color.rgb = max(color.rgb, 0.0);\n"
|
" color.rgb = max(color.rgb, 0.0);\n"
|
||||||
"\n"
|
"\n"
|
||||||
|
|
@ -158,7 +162,7 @@ void PostProcesser::Init()
|
||||||
cbDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
|
cbDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
|
||||||
cbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
|
cbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
|
||||||
|
|
||||||
GammaCBData initData = {1.0f, {0, 0, 0}};
|
GammaCBData initData = {1.0f, 0, 0.0f, 0.0f, 1.0f, 1.0f, {0, 0}};
|
||||||
D3D11_SUBRESOURCE_DATA srData;
|
D3D11_SUBRESOURCE_DATA srData;
|
||||||
srData.pSysMem = &initData;
|
srData.pSysMem = &initData;
|
||||||
srData.SysMemPitch = 0;
|
srData.SysMemPitch = 0;
|
||||||
|
|
@ -237,6 +241,10 @@ void PostProcesser::Apply() const
|
||||||
{
|
{
|
||||||
GammaCBData *cb = static_cast<GammaCBData *>(mapped.pData);
|
GammaCBData *cb = static_cast<GammaCBData *>(mapped.pData);
|
||||||
cb->gamma = m_gamma;
|
cb->gamma = m_gamma;
|
||||||
|
cb->uvOffsetX = 0.0f;
|
||||||
|
cb->uvOffsetY = 0.0f;
|
||||||
|
cb->uvScaleX = 1.0f;
|
||||||
|
cb->uvScaleY = 1.0f;
|
||||||
ctx->Unmap(m_pGammaCB, 0);
|
ctx->Unmap(m_pGammaCB, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -333,27 +341,6 @@ void PostProcesser::ApplyFromCopied() const
|
||||||
|
|
||||||
ID3D11DeviceContext* ctx = g_pImmediateContext;
|
ID3D11DeviceContext* ctx = g_pImmediateContext;
|
||||||
|
|
||||||
D3D11_MAPPED_SUBRESOURCE mapped;
|
|
||||||
const D3D11_MAP mapType = m_wineMode ? D3D11_MAP_WRITE_NO_OVERWRITE : D3D11_MAP_WRITE_DISCARD;
|
|
||||||
const HRESULT hr = ctx->Map(m_pGammaCB, 0, mapType, 0, &mapped);
|
|
||||||
if (SUCCEEDED(hr))
|
|
||||||
{
|
|
||||||
const auto cb = static_cast<GammaCBData*>(mapped.pData);
|
|
||||||
cb->gamma = m_gamma;
|
|
||||||
ctx->Unmap(m_pGammaCB, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
ID3D11RenderTargetView* oldRTV = nullptr;
|
|
||||||
ID3D11DepthStencilView* oldDSV = nullptr;
|
|
||||||
ctx->OMGetRenderTargets(1, &oldRTV, &oldDSV);
|
|
||||||
|
|
||||||
UINT numViewports = 1;
|
|
||||||
D3D11_VIEWPORT oldViewport = {};
|
|
||||||
ctx->RSGetViewports(&numViewports, &oldViewport);
|
|
||||||
|
|
||||||
ID3D11RenderTargetView* bbRTV = g_pRenderTargetView;
|
|
||||||
ctx->OMSetRenderTargets(1, &bbRTV, nullptr);
|
|
||||||
|
|
||||||
D3D11_VIEWPORT vp;
|
D3D11_VIEWPORT vp;
|
||||||
if (m_useCustomViewport)
|
if (m_useCustomViewport)
|
||||||
{
|
{
|
||||||
|
|
@ -369,6 +356,33 @@ void PostProcesser::ApplyFromCopied() const
|
||||||
vp.TopLeftY = 0;
|
vp.TopLeftY = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
D3D11_MAPPED_SUBRESOURCE mapped;
|
||||||
|
const D3D11_MAP mapType = m_wineMode ? D3D11_MAP_WRITE_NO_OVERWRITE : D3D11_MAP_WRITE_DISCARD;
|
||||||
|
const HRESULT hr = ctx->Map(m_pGammaCB, 0, mapType, 0, &mapped);
|
||||||
|
if (SUCCEEDED(hr))
|
||||||
|
{
|
||||||
|
const auto cb = static_cast<GammaCBData*>(mapped.pData);
|
||||||
|
cb->gamma = m_gamma;
|
||||||
|
const float texW = static_cast<float>(m_gammaTexWidth);
|
||||||
|
const float texH = static_cast<float>(m_gammaTexHeight);
|
||||||
|
cb->uvOffsetX = vp.TopLeftX / texW;
|
||||||
|
cb->uvOffsetY = vp.TopLeftY / texH;
|
||||||
|
cb->uvScaleX = vp.Width / texW;
|
||||||
|
cb->uvScaleY = vp.Height / texH;
|
||||||
|
ctx->Unmap(m_pGammaCB, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
ID3D11RenderTargetView* oldRTV = nullptr;
|
||||||
|
ID3D11DepthStencilView* oldDSV = nullptr;
|
||||||
|
ctx->OMGetRenderTargets(1, &oldRTV, &oldDSV);
|
||||||
|
|
||||||
|
UINT numViewports = 1;
|
||||||
|
D3D11_VIEWPORT oldViewport = {};
|
||||||
|
ctx->RSGetViewports(&numViewports, &oldViewport);
|
||||||
|
|
||||||
|
ID3D11RenderTargetView* bbRTV = g_pRenderTargetView;
|
||||||
|
ctx->OMSetRenderTargets(1, &bbRTV, nullptr);
|
||||||
|
|
||||||
ctx->RSSetViewports(1, &vp);
|
ctx->RSSetViewports(1, &vp);
|
||||||
|
|
||||||
ctx->IASetInputLayout(nullptr);
|
ctx->IASetInputLayout(nullptr);
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,18 @@
|
||||||
$sha = (git rev-parse --short=7 HEAD)
|
$sha = (git rev-parse --short=7 HEAD)
|
||||||
$ref = (git symbolic-ref --short HEAD)
|
|
||||||
|
if ($env:GITHUB_REPOSITORY) {
|
||||||
|
$ref = "$env:GITHUB_REPOSITORY/$(git symbolic-ref --short HEAD)"
|
||||||
|
} else {
|
||||||
|
$remoteUrl = (git remote get-url origin)
|
||||||
|
# handle github urls only, can't predict other origins behavior
|
||||||
|
if ($remoteUrl -match '(?:github\.com[:/])([^/:]+/[^/]+?)(?:\.git)?$') {
|
||||||
|
$ref = "$($matches[1])/$(git symbolic-ref --short HEAD)"
|
||||||
|
}else{
|
||||||
|
# fallback to just symbolic ref in case remote isnt what we expect
|
||||||
|
$ref = "UNKNOWN/$(git symbolic-ref --short HEAD)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$build = 560 # Note: Build/network has to stay static for now, as without it builds wont be able to play together. We can change it later when we have a better versioning scheme in place.
|
$build = 560 # Note: Build/network has to stay static for now, as without it builds wont be able to play together. We can change it later when we have a better versioning scheme in place.
|
||||||
$suffix = ""
|
$suffix = ""
|
||||||
|
|
||||||
|
|
@ -18,7 +31,8 @@ if (git status --porcelain) {
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define VER_PRODUCTBUILD $build
|
#define VER_PRODUCTBUILD $build
|
||||||
#define VER_PRODUCTVERSION_STR_W L"$sha$suffix ($ref)"
|
#define VER_PRODUCTVERSION_STR_W L"$sha$suffix"
|
||||||
#define VER_FILEVERSION_STR_W VER_PRODUCTVERSION_STR_W
|
#define VER_FILEVERSION_STR_W VER_PRODUCTVERSION_STR_W
|
||||||
|
#define VER_BRANCHVERSION_STR_W L"$ref"
|
||||||
#define VER_NETWORK VER_PRODUCTBUILD
|
#define VER_NETWORK VER_PRODUCTBUILD
|
||||||
"@ | Set-Content "Common/BuildVer.h"
|
"@ | Set-Content "Common/BuildVer.h"
|
||||||
|
|
|
||||||
|
|
@ -157,6 +157,9 @@ shared_ptr<ItemInstance> AbstractContainerMenu::clicked(int slotIndex, int butto
|
||||||
shared_ptr<ItemInstance> clickedEntity = nullptr;
|
shared_ptr<ItemInstance> clickedEntity = nullptr;
|
||||||
shared_ptr<Inventory> inventory = player->inventory;
|
shared_ptr<Inventory> inventory = player->inventory;
|
||||||
|
|
||||||
|
if (slotIndex < 0 || slotIndex >= (int)slots.size())
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
if (clickType == CLICK_QUICK_CRAFT)
|
if (clickType == CLICK_QUICK_CRAFT)
|
||||||
{
|
{
|
||||||
int expectedStatus = quickcraftStatus;
|
int expectedStatus = quickcraftStatus;
|
||||||
|
|
@ -558,12 +561,13 @@ bool AbstractContainerMenu::isPauseScreen()
|
||||||
|
|
||||||
void AbstractContainerMenu::setItem(unsigned int slot, shared_ptr<ItemInstance> item)
|
void AbstractContainerMenu::setItem(unsigned int slot, shared_ptr<ItemInstance> item)
|
||||||
{
|
{
|
||||||
|
if (slot >= slots.size()) return;
|
||||||
getSlot(slot)->set(item);
|
getSlot(slot)->set(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AbstractContainerMenu::setAll(ItemInstanceArray *items)
|
void AbstractContainerMenu::setAll(ItemInstanceArray *items)
|
||||||
{
|
{
|
||||||
for (unsigned int i = 0; i < items->length; i++)
|
for (unsigned int i = 0; i < items->length && i < slots.size(); i++)
|
||||||
{
|
{
|
||||||
getSlot(i)->set( (*items)[i] );
|
getSlot(i)->set( (*items)[i] );
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ void AwardStatPacket::read(DataInputStream *dis) //throws IOException
|
||||||
|
|
||||||
// Read parameter blob.
|
// Read parameter blob.
|
||||||
int length = dis->readInt();
|
int length = dis->readInt();
|
||||||
if(length > 0)
|
if (length > 0 && length <= 65536)
|
||||||
{
|
{
|
||||||
m_paramData = byteArray(length);
|
m_paramData = byteArray(length);
|
||||||
dis->readFully(m_paramData);
|
dis->readFully(m_paramData);
|
||||||
|
|
|
||||||
|
|
@ -105,6 +105,12 @@ void BlockRegionUpdatePacket::read(DataInputStream *dis) //throws IOException
|
||||||
levelIdx = ( size >> 30 ) & 3;
|
levelIdx = ( size >> 30 ) & 3;
|
||||||
size &= 0x3fffffff;
|
size &= 0x3fffffff;
|
||||||
|
|
||||||
|
const int MAX_COMPRESSED_CHUNK_SIZE = 5 * 1024 * 1024;
|
||||||
|
if (size < 0 || size > MAX_COMPRESSED_CHUNK_SIZE)
|
||||||
|
{
|
||||||
|
size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if(size == 0)
|
if(size == 0)
|
||||||
{
|
{
|
||||||
buffer = byteArray();
|
buffer = byteArray();
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ void Boat::_init()
|
||||||
|
|
||||||
blocksBuilding = true;
|
blocksBuilding = true;
|
||||||
setSize(1.5f, 0.6f);
|
setSize(1.5f, 0.6f);
|
||||||
heightOffset = bbHeight / 2.0f;
|
heightOffset = (bbHeight / 2.0f) + 0.2f;
|
||||||
|
|
||||||
// 4J Stu - This function call had to be moved here from the Entity ctor to ensure that
|
// 4J Stu - This function call had to be moved here from the Entity ctor to ensure that
|
||||||
// the derived version of the function is called
|
// the derived version of the function is called
|
||||||
|
|
@ -194,7 +194,7 @@ void Boat::tick()
|
||||||
yo = y;
|
yo = y;
|
||||||
zo = z;
|
zo = z;
|
||||||
|
|
||||||
|
// Check how much of the boat is in water
|
||||||
int steps = 5;
|
int steps = 5;
|
||||||
double waterPercentage = 0;
|
double waterPercentage = 0;
|
||||||
for (int i = 0; i < steps; i++)
|
for (int i = 0; i < steps; i++)
|
||||||
|
|
@ -208,33 +208,14 @@ void Boat::tick()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create particles
|
||||||
double lastSpeed = sqrt(xd * xd + zd * zd);
|
double lastSpeed = sqrt(xd * xd + zd * zd);
|
||||||
if (lastSpeed > MAX_COLLISION_SPEED)
|
if (lastSpeed > MAX_COLLISION_SPEED && waterPercentage > 0)
|
||||||
{
|
{
|
||||||
double xa = cos(yRot * PI / 180);
|
createSplash(lastSpeed);
|
||||||
double za = sin(yRot * PI / 180);
|
|
||||||
|
|
||||||
for (int i = 0; i < 1 + lastSpeed * 60; i++)
|
|
||||||
{
|
|
||||||
|
|
||||||
double side = (random->nextFloat() * 2 - 1);
|
|
||||||
|
|
||||||
double side2 = (random->nextInt(2) * 2 - 1) * 0.7;
|
|
||||||
if (random->nextBoolean())
|
|
||||||
{
|
|
||||||
double xx = x - xa * side * 0.8 + za * side2;
|
|
||||||
double zz = z - za * side * 0.8 - xa * side2;
|
|
||||||
level->addParticle(eParticleType_splash, xx, y - 2 / 16.0f, zz, +xd, yd, +zd);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
double xx = x + xa + za * side * 0.7;
|
|
||||||
double zz = z + za - xa * side * 0.7;
|
|
||||||
level->addParticle(eParticleType_splash, xx, y - 2 / 16.0f, zz, +xd, yd, +zd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Interpolation
|
||||||
if (level->isClientSide && doLerp)
|
if (level->isClientSide && doLerp)
|
||||||
{
|
{
|
||||||
if (lSteps > 0)
|
if (lSteps > 0)
|
||||||
|
|
@ -254,7 +235,6 @@ void Boat::tick()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
#if 1
|
|
||||||
// Original
|
// Original
|
||||||
//double xt = x + xd;
|
//double xt = x + xd;
|
||||||
//double yt = y + yd;
|
//double yt = y + yd;
|
||||||
|
|
@ -273,51 +253,25 @@ void Boat::tick()
|
||||||
xd *= 0.99f;
|
xd *= 0.99f;
|
||||||
yd *= 0.95f;
|
yd *= 0.95f;
|
||||||
zd *= 0.99f;
|
zd *= 0.99f;
|
||||||
#else
|
|
||||||
// 4J Stu - Fix for #8280 - Gameplay : Boats behave erratically when exited next to land.
|
|
||||||
// The client shouldn't change the position of the boat
|
|
||||||
double xt = x;// + xd;
|
|
||||||
double yt = y + yd;
|
|
||||||
double zt = z;// + zd;
|
|
||||||
this->setPos(xt, yt, zt);
|
|
||||||
|
|
||||||
// 4J Stu - Fix for #9579 - GAMEPLAY: Boats with a player in them slowly sink under the water over time, and with no player in them they float into the sky.
|
|
||||||
// Just make the boats bob up and down rather than any other client-side movement when not receiving packets from server
|
|
||||||
if (waterPercentage > 0)
|
|
||||||
{
|
|
||||||
double bob = waterPercentage * 2 - 1;
|
|
||||||
yd += 0.04f * bob;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (yd < 0) yd /= 2;
|
|
||||||
yd += 0.007f;
|
|
||||||
}
|
|
||||||
//if (onGround)
|
|
||||||
//{
|
|
||||||
xd *= 0.5f;
|
|
||||||
yd *= 0.5f;
|
|
||||||
zd *= 0.5f;
|
|
||||||
//}
|
|
||||||
//xd *= 0.99f;
|
|
||||||
//yd *= 0.95f;
|
|
||||||
//zd *= 0.99f;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Bob in water
|
||||||
if (waterPercentage > 0)
|
if (waterPercentage > 0)
|
||||||
{
|
{
|
||||||
double bob = waterPercentage * 2 - 1;
|
double bob = waterPercentage * 2 - 1;
|
||||||
yd += 0.04f * bob;
|
yd += 0.04f * bob;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
// Reimplement gravity again (??)
|
||||||
|
int tileUnder = level->getTile(Mth::floor(x), Mth::floor(y-0.15), Mth::floor(z));
|
||||||
|
if (tileUnder == 0 && !onGround)
|
||||||
{
|
{
|
||||||
yd = 0;
|
yd -= 0.04f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Rider controls
|
||||||
if ( rider.lock() != nullptr && rider.lock()->instanceof(eTYPE_LIVINGENTITY) )
|
if ( rider.lock() != nullptr && rider.lock()->instanceof(eTYPE_LIVINGENTITY) )
|
||||||
{
|
{
|
||||||
shared_ptr<LivingEntity> livingRider = dynamic_pointer_cast<LivingEntity>(rider.lock());
|
shared_ptr<LivingEntity> livingRider = dynamic_pointer_cast<LivingEntity>(rider.lock());
|
||||||
|
|
@ -354,6 +308,7 @@ void Boat::tick()
|
||||||
if (acceleration < MIN_ACCELERATION) acceleration = MIN_ACCELERATION;
|
if (acceleration < MIN_ACCELERATION) acceleration = MIN_ACCELERATION;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Slow on ground
|
||||||
if (onGround)
|
if (onGround)
|
||||||
{
|
{
|
||||||
xd *= 0.5f;
|
xd *= 0.5f;
|
||||||
|
|
@ -362,6 +317,7 @@ void Boat::tick()
|
||||||
}
|
}
|
||||||
move(xd, yd, zd);
|
move(xd, yd, zd);
|
||||||
|
|
||||||
|
// Break boat on high speed collision
|
||||||
if ((horizontalCollision && lastSpeed > 0.20))
|
if ((horizontalCollision && lastSpeed > 0.20))
|
||||||
{
|
{
|
||||||
if (!level->isClientSide && !removed)
|
if (!level->isClientSide && !removed)
|
||||||
|
|
@ -401,6 +357,7 @@ void Boat::tick()
|
||||||
yRot += (float) rotDiff;
|
yRot += (float) rotDiff;
|
||||||
setRot(yRot, xRot);
|
setRot(yRot, xRot);
|
||||||
|
|
||||||
|
// Server code after this
|
||||||
if(level->isClientSide) return;
|
if(level->isClientSide) return;
|
||||||
|
|
||||||
vector<shared_ptr<Entity> > *entities = level->getEntities(shared_from_this(), bb->grow(0.2f, 0, 0.2f));
|
vector<shared_ptr<Entity> > *entities = level->getEntities(shared_from_this(), bb->grow(0.2f, 0, 0.2f));
|
||||||
|
|
@ -444,13 +401,38 @@ void Boat::tick()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Boat::createSplash(double particleStrengh) {
|
||||||
|
double xa = cos(yRot * PI / 180);
|
||||||
|
double za = sin(yRot * PI / 180);
|
||||||
|
|
||||||
|
for (int i = 0; i < 1 + particleStrengh * 60; i++)
|
||||||
|
{
|
||||||
|
double side = (random->nextFloat() * 2 - 1);
|
||||||
|
|
||||||
|
double side2 = (random->nextInt(2) * 2 - 1) * 0.7;
|
||||||
|
if (random->nextBoolean())
|
||||||
|
{
|
||||||
|
double xx = x - xa * side * 0.8 + za * side2;
|
||||||
|
double zz = z - za * side * 0.8 - xa * side2;
|
||||||
|
level->addParticle(eParticleType_splash, xx, y - 2 / 16.0f, zz, +xd, yd, +zd);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
double xx = x + xa + za * side * 0.7;
|
||||||
|
double zz = z + za - xa * side * 0.7;
|
||||||
|
level->addParticle(eParticleType_splash, xx, y - 2 / 16.0f, zz, +xd, yd, +zd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Boat::positionRider()
|
void Boat::positionRider()
|
||||||
{
|
{
|
||||||
if (rider.lock() == nullptr) return;
|
if (rider.lock() == nullptr) return;
|
||||||
|
|
||||||
double xa = cos(yRot * PI / 180) * 0.4;
|
double xa = cos(yRot * PI / 180) * 0.4;
|
||||||
double za = sin(yRot * PI / 180) * 0.4;
|
double za = sin(yRot * PI / 180) * 0.4;
|
||||||
rider.lock()->setPos(x + xa, y + getRideHeight() + rider.lock()->getRidingHeight(), z + za);
|
// We minus 0.4 to ensure that the player is not hovering above the boat.
|
||||||
|
rider.lock()->setPos(x + xa, y + getRideHeight() + rider.lock()->getRidingHeight()-0.4, z + za);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -523,3 +505,4 @@ void Boat::setDoLerp(bool doLerp)
|
||||||
{
|
{
|
||||||
this->doLerp = doLerp;
|
this->doLerp = doLerp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,117 +2,141 @@
|
||||||
|
|
||||||
#include "InputOutputStream.h"
|
#include "InputOutputStream.h"
|
||||||
|
|
||||||
//Creates ByteArrayInputStream that uses buf as its buffer array. The initial value of pos is offset and
|
// Creates ByteArrayInputStream that uses buf as its buffer array. The initial value of pos is offset and
|
||||||
//the initial value of count is the minimum of offset+length and buf.length. The buffer array is not copied.
|
// the initial value of count is the minimum of offset+length and buf.length. The buffer array is not copied.
|
||||||
//The buffer's mark is set to the specified offset.
|
// The buffer's mark is set to the specified offset.
|
||||||
//Parameters:
|
// Parameters:
|
||||||
//buf - the input buffer.
|
// buf - the input buffer.
|
||||||
//offset - the offset in the buffer of the first byte to read.
|
// offset - the offset in the buffer of the first byte to read.
|
||||||
//length - the maximum number of bytes to read from the buffer.
|
// length - the maximum number of bytes to read from the buffer.
|
||||||
ByteArrayInputStream::ByteArrayInputStream(byteArray buf, unsigned int offset, unsigned int length)
|
ByteArrayInputStream::ByteArrayInputStream(byteArray buf, unsigned int offset, unsigned int length)
|
||||||
: pos( offset ), count( min( offset+length, buf.length ) ), mark( offset )
|
: pos(offset), mark(offset)
|
||||||
{
|
{
|
||||||
this->buf = buf;
|
if (offset > buf.length)
|
||||||
|
{
|
||||||
|
count = buf.length;
|
||||||
|
}
|
||||||
|
else if (length > buf.length - offset)
|
||||||
|
{
|
||||||
|
count = buf.length;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
count = offset + length;
|
||||||
|
}
|
||||||
|
this->buf = buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Creates a ByteArrayInputStream so that it uses buf as its buffer array. The buffer array is not copied.
|
// Creates a ByteArrayInputStream so that it uses buf as its buffer array. The buffer array is not copied.
|
||||||
//The initial value of pos is 0 and the initial value of count is the length of buf.
|
// The initial value of pos is 0 and the initial value of count is the length of buf.
|
||||||
//Parameters:
|
// Parameters:
|
||||||
//buf - the input buffer.
|
// buf - the input buffer.
|
||||||
ByteArrayInputStream::ByteArrayInputStream(byteArray buf)
|
ByteArrayInputStream::ByteArrayInputStream(byteArray buf)
|
||||||
: pos( 0 ), count( buf.length ), mark( 0 )
|
: pos(0), count(buf.length), mark(0)
|
||||||
{
|
{
|
||||||
this->buf = buf;
|
this->buf = buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Reads the next byte of data from this input stream. The value byte is returned as an int in the range 0 to 255.
|
// Reads the next byte of data from this input stream. The value byte is returned as an int in the range 0 to 255.
|
||||||
//If no byte is available because the end of the stream has been reached, the value -1 is returned.
|
// If no byte is available because the end of the stream has been reached, the value -1 is returned.
|
||||||
//This read method cannot block.
|
// This read method cannot block.
|
||||||
//Returns:
|
// Returns:
|
||||||
//the next byte of data, or -1 if the end of the stream has been reached.
|
// the next byte of data, or -1 if the end of the stream has been reached.
|
||||||
int ByteArrayInputStream::read()
|
int ByteArrayInputStream::read()
|
||||||
{
|
{
|
||||||
if( pos >= count )
|
if (pos >= count)
|
||||||
return -1;
|
{
|
||||||
else
|
return -1;
|
||||||
return buf[pos++];
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return buf[pos++];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Reads some number of bytes from the input stream and stores them into the buffer array b.
|
// Reads some number of bytes from the input stream and stores them into the buffer array b.
|
||||||
//The number of bytes actually read is returned as an integer. This method blocks until input data is available,
|
// The number of bytes actually read is returned as an integer. This method blocks until input data is available,
|
||||||
//end of file is detected, or an exception is thrown.
|
// end of file is detected, or an exception is thrown.
|
||||||
//If the length of b is zero, then no bytes are read and 0 is returned; otherwise, there is an attempt to read at least one byte.
|
// If the length of b is zero, then no bytes are read and 0 is returned; otherwise, there is an attempt to read at least one byte.
|
||||||
//If no byte is available because the stream is at the end of the file, the value -1 is returned; otherwise,
|
// If no byte is available because the stream is at the end of the file, the value -1 is returned; otherwise,
|
||||||
//at least one byte is read and stored into b.
|
// at least one byte is read and stored into b.
|
||||||
//
|
//
|
||||||
//The first byte read is stored into element b[0], the next one into b[1], and so on. The number of bytes read is,
|
// The first byte read is stored into element b[0], the next one into b[1], and so on. The number of bytes read is,
|
||||||
//at most, equal to the length of b. Let k be the number of bytes actually read; these bytes will be stored in elements b[0] through b[k-1],
|
// at most, equal to the length of b. Let k be the number of bytes actually read; these bytes will be stored in elements b[0] through b[k-1],
|
||||||
//leaving elements b[k] through b[b.length-1] unaffected.
|
// leaving elements b[k] through b[b.length-1] unaffected.
|
||||||
//
|
//
|
||||||
//The read(b) method for class InputStream has the same effect as:
|
// The read(b) method for class InputStream has the same effect as:
|
||||||
//
|
//
|
||||||
// read(b, 0, b.length)
|
// read(b, 0, b.length)
|
||||||
//Parameters:
|
// Parameters:
|
||||||
//b - the buffer into which the data is read.
|
// b - the buffer into which the data is read.
|
||||||
//Returns:
|
// Returns:
|
||||||
//the total number of bytes read into the buffer, or -1 is there is no more data because the end of the stream has been reached.
|
// the total number of bytes read into the buffer, or -1 is there is no more data because the end of the stream has been reached.
|
||||||
int ByteArrayInputStream::read(byteArray b)
|
int ByteArrayInputStream::read(byteArray b)
|
||||||
{
|
{
|
||||||
return read( b, 0, b.length );
|
return read(b, 0, b.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Reads up to len bytes of data into an array of bytes from this input stream. If pos equals count,
|
// Reads up to len bytes of data into an array of bytes from this input stream. If pos equals count,
|
||||||
//then -1 is returned to indicate end of file. Otherwise, the number k of bytes read is equal to the smaller of len and count-pos.
|
// then -1 is returned to indicate end of file. Otherwise, the number k of bytes read is equal to the smaller of len and count-pos.
|
||||||
//If k is positive, then bytes buf[pos] through buf[pos+k-1] are copied into b[off] through b[off+k-1] in the manner
|
// If k is positive, then bytes buf[pos] through buf[pos+k-1] are copied into b[off] through b[off+k-1] in the manner
|
||||||
//performed by System.arraycopy. The value k is added into pos and k is returned.
|
// performed by System.arraycopy. The value k is added into pos and k is returned.
|
||||||
//This read method cannot block.
|
// This read method cannot block.
|
||||||
//Parameters:
|
// Parameters:
|
||||||
//b - the buffer into which the data is read.
|
// b - the buffer into which the data is read.
|
||||||
//off - the start offset in the destination array b
|
// off - the start offset in the destination array b
|
||||||
//len - the maximum number of bytes read.
|
// len - the maximum number of bytes read.
|
||||||
//Returns:
|
// Returns:
|
||||||
//the total number of bytes read into the buffer, or -1 if there is no more data because the end of the stream has been reached.
|
// the total number of bytes read into the buffer, or -1 if there is no more data because the end of the stream has been reached.
|
||||||
int ByteArrayInputStream::read(byteArray b, unsigned int offset, unsigned int length)
|
int ByteArrayInputStream::read(byteArray b, unsigned int offset, unsigned int length)
|
||||||
{
|
{
|
||||||
if( pos == count )
|
if (pos == count)
|
||||||
return -1;
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
int k = min( length, count-pos );
|
int k = min(length, count - pos);
|
||||||
XMemCpy( &b[offset], &buf[pos], k );
|
XMemCpy(&b[offset], &buf[pos], k);
|
||||||
//std::copy( buf->data+pos, buf->data+pos+k, b->data + offset ); // Or this instead?
|
// std::copy( buf->data+pos, buf->data+pos+k, b->data + offset ); // Or this instead?
|
||||||
|
|
||||||
pos += k;
|
pos += k;
|
||||||
|
|
||||||
return k;
|
return k;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Closing a ByteArrayInputStream has no effect.
|
// Closing a ByteArrayInputStream has no effect.
|
||||||
//The methods in this class can be called after the stream has been closed without generating an IOException.
|
// The methods in this class can be called after the stream has been closed without generating an IOException.
|
||||||
void ByteArrayInputStream::close()
|
void ByteArrayInputStream::close()
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Skips n bytes of input from this input stream. Fewer bytes might be skipped if the end of the input stream is reached. The actual number k of bytes to be skipped is equal to the smaller of n and count-pos. The value k is added into pos and k is returned.
|
// Skips n bytes of input from this input stream. Fewer bytes might be skipped if the end of the input stream is reached. The actual number k of bytes to be skipped is equal to the smaller of n and count-pos. The value k is added into pos and k is returned.
|
||||||
//Overrides:
|
// Overrides:
|
||||||
//skip in class InputStream
|
// skip in class InputStream
|
||||||
//Parameters:
|
// Parameters:
|
||||||
//n - the number of bytes to be skipped.
|
// n - the number of bytes to be skipped.
|
||||||
//Returns:
|
// Returns:
|
||||||
//the actual number of bytes skipped.
|
// the actual number of bytes skipped.
|
||||||
int64_t ByteArrayInputStream::skip(int64_t n)
|
__int64 ByteArrayInputStream::skip(__int64 n)
|
||||||
{
|
{
|
||||||
int newPos = pos + n;
|
int newPos = pos + n;
|
||||||
|
|
||||||
if(newPos > count) newPos = count;
|
if (newPos > count)
|
||||||
|
{
|
||||||
|
newPos = count;
|
||||||
|
}
|
||||||
|
|
||||||
int k = newPos - pos;
|
int k = newPos - pos;
|
||||||
pos = newPos;
|
pos = newPos;
|
||||||
|
|
||||||
return k;
|
return k;
|
||||||
}
|
}
|
||||||
|
|
||||||
ByteArrayInputStream::~ByteArrayInputStream()
|
ByteArrayInputStream::~ByteArrayInputStream()
|
||||||
{
|
{
|
||||||
if(buf.data != nullptr) delete [] buf.data;
|
if (buf.data != NULL)
|
||||||
}
|
{
|
||||||
|
delete[] buf.data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,76 +5,95 @@
|
||||||
// Creates a new byte array output stream. The buffer capacity is initially 32 bytes, though its size increases if necessary.
|
// Creates a new byte array output stream. The buffer capacity is initially 32 bytes, though its size increases if necessary.
|
||||||
ByteArrayOutputStream::ByteArrayOutputStream()
|
ByteArrayOutputStream::ByteArrayOutputStream()
|
||||||
{
|
{
|
||||||
count = 0;
|
count = 0;
|
||||||
buf = byteArray( 32 );
|
buf = byteArray(32);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Creates a new byte array output stream, with a buffer capacity of the specified size, in bytes.
|
// Creates a new byte array output stream, with a buffer capacity of the specified size, in bytes.
|
||||||
//Parameters:
|
// Parameters:
|
||||||
//size - the initial size.
|
// size - the initial size.
|
||||||
ByteArrayOutputStream::ByteArrayOutputStream(unsigned int size)
|
ByteArrayOutputStream::ByteArrayOutputStream(unsigned int size)
|
||||||
{
|
{
|
||||||
count = 0;
|
count = 0;
|
||||||
buf = byteArray( size );
|
buf = byteArray(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
ByteArrayOutputStream::~ByteArrayOutputStream()
|
ByteArrayOutputStream::~ByteArrayOutputStream()
|
||||||
{
|
{
|
||||||
if (buf.data != nullptr)
|
if (buf.data != NULL)
|
||||||
delete[] buf.data;
|
{
|
||||||
|
delete[] buf.data;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Writes the specified byte to this byte array output stream.
|
// Writes the specified byte to this byte array output stream.
|
||||||
//Parameters:
|
// Parameters:
|
||||||
//b - the byte to be written.
|
// b - the byte to be written.
|
||||||
void ByteArrayOutputStream::write(unsigned int b)
|
void ByteArrayOutputStream::write(unsigned int b)
|
||||||
{
|
{
|
||||||
// If we will fill the buffer we need to make it bigger
|
// If we will fill the buffer we need to make it bigger
|
||||||
if( count + 1 >= buf.length )
|
if (count + 1 >= buf.length)
|
||||||
buf.resize( buf.length * 2 );
|
{
|
||||||
|
buf.resize(buf.length * 2);
|
||||||
|
}
|
||||||
|
|
||||||
buf[count] = static_cast<byte>(b);
|
buf[count] = (byte)b;
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Writes b.length bytes from the specified byte array to this output stream.
|
// Writes b.length bytes from the specified byte array to this output stream.
|
||||||
//The general contract for write(b) is that it should have exactly the same effect as the call write(b, 0, b.length).
|
// The general contract for write(b) is that it should have exactly the same effect as the call write(b, 0, b.length).
|
||||||
void ByteArrayOutputStream::write(byteArray b)
|
void ByteArrayOutputStream::write(byteArray b)
|
||||||
{
|
{
|
||||||
write(b, 0, b.length);
|
write(b, 0, b.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Writes len bytes from the specified byte array starting at offset off to this byte array output stream.
|
// Writes len bytes from the specified byte array starting at offset off to this byte array output stream.
|
||||||
//Parameters:
|
// Parameters:
|
||||||
//b - the data.
|
// b - the data.
|
||||||
//off - the start offset in the data.
|
// off - the start offset in the data.
|
||||||
//len - the number of bytes to write.
|
// len - the number of bytes to write.
|
||||||
void ByteArrayOutputStream::write(byteArray b, unsigned int offset, unsigned int length)
|
void ByteArrayOutputStream::write(byteArray b, unsigned int offset, unsigned int length)
|
||||||
{
|
{
|
||||||
assert( b.length >= offset + length );
|
|
||||||
|
|
||||||
// If we will fill the buffer we need to make it bigger
|
if (offset > b.length || length > b.length - offset)
|
||||||
if( count + length >= buf.length )
|
{
|
||||||
buf.resize( max( count + length + 1, buf.length * 2 ) );
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
XMemCpy( &buf[count], &b[offset], length );
|
if (length > 0xFFFFFFFF - count)
|
||||||
//std::copy( b->data+offset, b->data+offset+length, buf->data + count ); // Or this instead?
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
count += length;
|
// If we will fill the buffer we need to make it bigger
|
||||||
|
if (count + length >= buf.length)
|
||||||
|
{
|
||||||
|
unsigned int newSize = (std::max)(count + length + 1, buf.length * 2);
|
||||||
|
if (newSize <= buf.length)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
buf.resize(newSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
XMemCpy(&buf[count], &b[offset], length);
|
||||||
|
|
||||||
|
count += length;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Closing a ByteArrayOutputStream has no effect.
|
// Closing a ByteArrayOutputStream has no effect.
|
||||||
//The methods in this class can be called after the stream has been closed without generating an IOException.
|
// The methods in this class can be called after the stream has been closed without generating an IOException.
|
||||||
void ByteArrayOutputStream::close()
|
void ByteArrayOutputStream::close()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
//Creates a newly allocated byte array. Its size is the current size of this output stream and the valid contents of the buffer have been copied into it.
|
// Creates a newly allocated byte array. Its size is the current size of this output stream and the valid contents of the buffer have been copied into it.
|
||||||
//Returns:
|
// Returns:
|
||||||
//the current contents of this output stream, as a byte array.
|
// the current contents of this output stream, as a byte array.
|
||||||
byteArray ByteArrayOutputStream::toByteArray()
|
byteArray ByteArrayOutputStream::toByteArray()
|
||||||
{
|
{
|
||||||
byteArray out(count);
|
byteArray out(count);
|
||||||
memcpy(out.data,buf.data,count);
|
memcpy(out.data, buf.data, count);
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ public:
|
||||||
void load(DataInput *dis, int tagDepth)
|
void load(DataInput *dis, int tagDepth)
|
||||||
{
|
{
|
||||||
int length = dis->readInt();
|
int length = dis->readInt();
|
||||||
|
if (length < 0 || length > 2 * 1024 * 1024) length = 0;
|
||||||
|
|
||||||
if ( data.data ) delete[] data.data;
|
if ( data.data ) delete[] data.data;
|
||||||
data = byteArray(length);
|
data = byteArray(length);
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,12 @@ void ComplexItemDataPacket::read(DataInputStream *dis) //throws IOException
|
||||||
itemType = dis->readShort();
|
itemType = dis->readShort();
|
||||||
itemId = dis->readShort();
|
itemId = dis->readShort();
|
||||||
|
|
||||||
data = charArray(dis->readUnsignedShort() & 0xffff);
|
int dataLength = dis->readShort() & 0xffff;
|
||||||
|
if (dataLength > 32767)
|
||||||
|
{
|
||||||
|
dataLength = 0;
|
||||||
|
}
|
||||||
|
data = charArray(dataLength);
|
||||||
dis->readFully(data);
|
dis->readFully(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -42,10 +42,16 @@ public:
|
||||||
}
|
}
|
||||||
tags.clear();
|
tags.clear();
|
||||||
Tag *tag;
|
Tag *tag;
|
||||||
while ((tag = Tag::readNamedTag(dis))->getId() != Tag::TAG_End)
|
int tagCount = 0;
|
||||||
{
|
const int MAX_COMPOUND_TAGS = 10000;
|
||||||
tags[tag->getName()] = tag;
|
while ((tag = Tag::readNamedTag(dis))->getId() != Tag::TAG_End)
|
||||||
}
|
{
|
||||||
|
tags[tag->getName()] = tag;
|
||||||
|
if (++tagCount >= MAX_COMPOUND_TAGS)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
delete tag;
|
delete tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -108,8 +108,8 @@ Connection::Connection(Socket *socket, const wstring& id, PacketListener *packet
|
||||||
const char *szId = wstringtofilename(id);
|
const char *szId = wstringtofilename(id);
|
||||||
char readThreadName[256];
|
char readThreadName[256];
|
||||||
char writeThreadName[256];
|
char writeThreadName[256];
|
||||||
sprintf(readThreadName,"%s read\n",szId);
|
sprintf_s(readThreadName, sizeof(readThreadName), "%.240s read\n", szId);
|
||||||
sprintf(writeThreadName,"%s write\n",szId);
|
sprintf_s(writeThreadName, sizeof(writeThreadName), "%.240s write\n", szId);
|
||||||
|
|
||||||
readThread = new C4JThread(runRead, static_cast<void *>(this), readThreadName, READ_STACK_SIZE);
|
readThread = new C4JThread(runRead, static_cast<void *>(this), readThreadName, READ_STACK_SIZE);
|
||||||
writeThread = new C4JThread(runWrite, this, writeThreadName, WRITE_STACK_SIZE);
|
writeThread = new C4JThread(runWrite, this, writeThreadName, WRITE_STACK_SIZE);
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,9 @@ void ContainerSetContentPacket::read(DataInputStream *dis) //throws IOException
|
||||||
{
|
{
|
||||||
containerId = dis->readByte();
|
containerId = dis->readByte();
|
||||||
int count = dis->readShort();
|
int count = dis->readShort();
|
||||||
|
|
||||||
|
if (count < 0 || count > 256) count = 0;
|
||||||
|
|
||||||
items = ItemInstanceArray(count);
|
items = ItemInstanceArray(count);
|
||||||
for (int i = 0; i < count; i++)
|
for (int i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ void ContainerSetSlotPacket::read(DataInputStream *dis) //throws IOException
|
||||||
// 4J Stu - TU-1 hotfix
|
// 4J Stu - TU-1 hotfix
|
||||||
// Fix for #13142 - Holding down the A button on the furnace ingredient slot causes the UI to display incorrect item counts
|
// Fix for #13142 - Holding down the A button on the furnace ingredient slot causes the UI to display incorrect item counts
|
||||||
BYTE byteId = dis->readByte();
|
BYTE byteId = dis->readByte();
|
||||||
containerId = *(char *)&byteId;
|
containerId = (char)(signed char)byteId;
|
||||||
slot = dis->readShort();
|
slot = dis->readShort();
|
||||||
item = readItem(dis);
|
item = readItem(dis);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ void CustomPayloadPacket::read(DataInputStream *dis)
|
||||||
identifier = readUtf(dis, 20);
|
identifier = readUtf(dis, 20);
|
||||||
length = dis->readShort();
|
length = dis->readShort();
|
||||||
|
|
||||||
if (length > 0 && length < Short::MAX_VALUE)
|
if (length > 0 && length <= Short::MAX_VALUE)
|
||||||
{
|
{
|
||||||
if(data.data != nullptr)
|
if(data.data != nullptr)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -303,6 +303,10 @@ wstring DataInputStream::readUTF()
|
||||||
int b = stream->read();
|
int b = stream->read();
|
||||||
unsigned short UTFLength = static_cast<unsigned short>(((a & 0xff) << 8) | (b & 0xff));
|
unsigned short UTFLength = static_cast<unsigned short>(((a & 0xff) << 8) | (b & 0xff));
|
||||||
|
|
||||||
|
const unsigned short MAX_UTF_LENGTH = 32767;
|
||||||
|
if (UTFLength > MAX_UTF_LENGTH)
|
||||||
|
return outputString;
|
||||||
|
|
||||||
//// 4J Stu - I decided while writing DataOutputStream that we didn't need to bother using the UTF8 format
|
//// 4J Stu - I decided while writing DataOutputStream that we didn't need to bother using the UTF8 format
|
||||||
//// used in the java libs, and just write in/out as wchar_t all the time
|
//// used in the java libs, and just write in/out as wchar_t all the time
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,8 @@ void ExplodePacket::read(DataInputStream *dis) //throws IOException
|
||||||
r = dis->readFloat();
|
r = dis->readFloat();
|
||||||
int count = dis->readInt();
|
int count = dis->readInt();
|
||||||
|
|
||||||
|
if (count < 0 || count > 32768) count = 0;
|
||||||
|
|
||||||
int xp = static_cast<int>(x);
|
int xp = static_cast<int>(x);
|
||||||
int yp = static_cast<int>(y);
|
int yp = static_cast<int>(y);
|
||||||
int zp = static_cast<int>(z);
|
int zp = static_cast<int>(z);
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ void GameCommandPacket::read(DataInputStream *dis)
|
||||||
command = static_cast<EGameCommand>(dis->readInt());
|
command = static_cast<EGameCommand>(dis->readInt());
|
||||||
length = dis->readShort();
|
length = dis->readShort();
|
||||||
|
|
||||||
if (length > 0 && length < Short::MAX_VALUE)
|
if (length > 0 && length <= Short::MAX_VALUE)
|
||||||
{
|
{
|
||||||
if(data.data != nullptr)
|
if(data.data != nullptr)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,8 @@ public:
|
||||||
void load(DataInput *dis, int tagDepth)
|
void load(DataInput *dis, int tagDepth)
|
||||||
{
|
{
|
||||||
int length = dis->readInt();
|
int length = dis->readInt();
|
||||||
|
if (length < 0 || length > 65536)
|
||||||
|
length = 0;
|
||||||
|
|
||||||
if ( data.data ) delete[] data.data;
|
if ( data.data ) delete[] data.data;
|
||||||
data = intArray(length);
|
data = intArray(length);
|
||||||
|
|
|
||||||
|
|
@ -26,21 +26,16 @@ public:
|
||||||
|
|
||||||
void load(DataInput *dis, int tagDepth)
|
void load(DataInput *dis, int tagDepth)
|
||||||
{
|
{
|
||||||
if (tagDepth > MAX_DEPTH)
|
|
||||||
{
|
|
||||||
#ifndef _CONTENT_PACKAGE
|
|
||||||
printf("Tried to read NBT tag with too high complexity, depth > %d", MAX_DEPTH);
|
|
||||||
__debugbreak();
|
|
||||||
#endif
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
type = dis->readByte();
|
type = dis->readByte();
|
||||||
int size = dis->readInt();
|
int size = dis->readInt();
|
||||||
|
if (size < 0 || size > MAX_DEPTH)
|
||||||
|
size = 0;
|
||||||
|
|
||||||
list.clear();
|
list.clear();
|
||||||
for (int i = 0; i < size; i++)
|
for (int i = 0; i < size; i++)
|
||||||
{
|
{
|
||||||
Tag *tag = Tag::newTag(type, L"");
|
Tag *tag = Tag::newTag(type, L"");
|
||||||
|
if (tag == nullptr) break;
|
||||||
tag->load(dis, tagDepth);
|
tag->load(dis, tagDepth);
|
||||||
list.push_back(tag);
|
list.push_back(tag);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -267,8 +267,12 @@ void Packet::updatePacketStatsPIX()
|
||||||
|
|
||||||
shared_ptr<Packet> Packet::getPacket(int id)
|
shared_ptr<Packet> Packet::getPacket(int id)
|
||||||
{
|
{
|
||||||
// 4J: Removed try/catch
|
auto it = idToCreateMap.find(id);
|
||||||
return idToCreateMap[id]();
|
if (it == idToCreateMap.end())
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return it->second();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Packet::writeBytes(DataOutputStream *dataoutputstream, byteArray bytes)
|
void Packet::writeBytes(DataOutputStream *dataoutputstream, byteArray bytes)
|
||||||
|
|
@ -334,30 +338,11 @@ shared_ptr<Packet> Packet::readPacket(DataInputStream *dis, bool isServer) // th
|
||||||
|
|
||||||
if ((isServer && serverReceivedPackets.find(id) == serverReceivedPackets.end()) || (!isServer && clientReceivedPackets.find(id) == clientReceivedPackets.end()))
|
if ((isServer && serverReceivedPackets.find(id) == serverReceivedPackets.end()) || (!isServer && clientReceivedPackets.find(id) == clientReceivedPackets.end()))
|
||||||
{
|
{
|
||||||
app.DebugPrintf("*** BAD PACKET ID %d (0x%02X) isServer=%d totalPacketsRead=%d\n", id, id, isServer ? 1 : 0, s_packetCount);
|
return nullptr;
|
||||||
app.DebugPrintf("*** Last %d good packet IDs (oldest first): ", 8);
|
|
||||||
for (int dbg = 0; dbg < 8; dbg++)
|
|
||||||
{
|
|
||||||
int idx = (s_lastIdPos + dbg) % 8;
|
|
||||||
app.DebugPrintf("%d ", s_lastIds[idx]);
|
|
||||||
}
|
|
||||||
app.DebugPrintf("\n");
|
|
||||||
// Dump the next 32 bytes from the stream to see what follows
|
|
||||||
app.DebugPrintf("*** Next bytes in stream: ");
|
|
||||||
for (int dbg = 0; dbg < 32; dbg++)
|
|
||||||
{
|
|
||||||
int b = dis->read();
|
|
||||||
if (b == -1) { app.DebugPrintf("[EOS] "); break; }
|
|
||||||
app.DebugPrintf("%02X ", b);
|
|
||||||
}
|
|
||||||
app.DebugPrintf("\n");
|
|
||||||
__debugbreak();
|
|
||||||
assert(false);
|
|
||||||
// throw new IOException(wstring(L"Bad packet id ") + std::to_wstring(id));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
packet = getPacket(id);
|
packet = getPacket(id);
|
||||||
if (packet == nullptr) assert(false);//throw new IOException(wstring(L"Bad packet id ") + std::to_wstring(id));
|
if (packet == nullptr) return nullptr;//throw new IOException(wstring(L"Bad packet id ") + std::to_wstring(id));
|
||||||
|
|
||||||
s_lastIds[s_lastIdPos] = id;
|
s_lastIds[s_lastIdPos] = id;
|
||||||
s_lastIdPos = (s_lastIdPos + 1) % 8;
|
s_lastIdPos = (s_lastIdPos + 1) % 8;
|
||||||
|
|
@ -418,11 +403,9 @@ wstring Packet::readUtf(DataInputStream *dis, int maxLength) // throws IOExcepti
|
||||||
{
|
{
|
||||||
|
|
||||||
short stringLength = dis->readShort();
|
short stringLength = dis->readShort();
|
||||||
if (stringLength > maxLength)
|
if (stringLength > maxLength || stringLength <= 0)
|
||||||
{
|
{
|
||||||
wstringstream stream;
|
return L"";
|
||||||
stream << L"Received string length longer than maximum allowed (" << stringLength << " > " << maxLength << ")";
|
|
||||||
assert(false);
|
|
||||||
// throw new IOException( stream.str() );
|
// throw new IOException( stream.str() );
|
||||||
}
|
}
|
||||||
if (stringLength < 0)
|
if (stringLength < 0)
|
||||||
|
|
@ -531,7 +514,7 @@ shared_ptr<ItemInstance> Packet::readItem(DataInputStream *dis)
|
||||||
{
|
{
|
||||||
shared_ptr<ItemInstance> item = nullptr;
|
shared_ptr<ItemInstance> item = nullptr;
|
||||||
int id = dis->readShort();
|
int id = dis->readShort();
|
||||||
if (id >= 0)
|
if (id >= 0 && id < 32000) // todo: should turn Item::ITEM_NUM_COUNT into a global define
|
||||||
{
|
{
|
||||||
int count = dis->readByte();
|
int count = dis->readByte();
|
||||||
int damage = dis->readShort();
|
int damage = dis->readShort();
|
||||||
|
|
@ -569,9 +552,16 @@ void Packet::writeItem(shared_ptr<ItemInstance> item, DataOutputStream *dos)
|
||||||
CompoundTag *Packet::readNbt(DataInputStream *dis)
|
CompoundTag *Packet::readNbt(DataInputStream *dis)
|
||||||
{
|
{
|
||||||
int size = dis->readShort();
|
int size = dis->readShort();
|
||||||
if (size < 0) return nullptr;
|
if (size <= 0) return nullptr;
|
||||||
|
|
||||||
|
const int MAX_NBT_SIZE = 32767;
|
||||||
|
if (size > MAX_NBT_SIZE) return nullptr;
|
||||||
byteArray buff(size);
|
byteArray buff(size);
|
||||||
dis->readFully(buff);
|
if (!dis->readFully(buff))
|
||||||
|
{
|
||||||
|
delete [] buff.data;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
CompoundTag *result = (CompoundTag *) NbtIo::decompress(buff);
|
CompoundTag *result = (CompoundTag *) NbtIo::decompress(buff);
|
||||||
delete [] buff.data;
|
delete [] buff.data;
|
||||||
return result;
|
return result;
|
||||||
|
|
|
||||||
|
|
@ -62,6 +62,7 @@ void PreLoginPacket::read(DataInputStream *dis) //throws IOException
|
||||||
m_friendsOnlyBits = dis->readByte();
|
m_friendsOnlyBits = dis->readByte();
|
||||||
m_ugcPlayersVersion = dis->readInt();
|
m_ugcPlayersVersion = dis->readInt();
|
||||||
m_dwPlayerCount = dis->readByte();
|
m_dwPlayerCount = dis->readByte();
|
||||||
|
if( m_dwPlayerCount > MINECRAFT_NET_MAX_PLAYERS ) m_dwPlayerCount = MINECRAFT_NET_MAX_PLAYERS;
|
||||||
if( m_dwPlayerCount > 0 )
|
if( m_dwPlayerCount > 0 )
|
||||||
{
|
{
|
||||||
m_playerXuids = new PlayerUID[m_dwPlayerCount];
|
m_playerXuids = new PlayerUID[m_dwPlayerCount];
|
||||||
|
|
@ -74,6 +75,7 @@ void PreLoginPacket::read(DataInputStream *dis) //throws IOException
|
||||||
{
|
{
|
||||||
m_szUniqueSaveName[i]=dis->readByte();
|
m_szUniqueSaveName[i]=dis->readByte();
|
||||||
}
|
}
|
||||||
|
// m_szUniqueSaveName[m_iSaveNameLen - 1] = 0; // LCEMP does this but I have no idea why, TODO: why?
|
||||||
m_serverSettings = dis->readInt();
|
m_serverSettings = dis->readInt();
|
||||||
m_hostIndex = dis->readByte();
|
m_hostIndex = dis->readByte();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,9 @@ RemoveEntitiesPacket::~RemoveEntitiesPacket()
|
||||||
|
|
||||||
void RemoveEntitiesPacket::read(DataInputStream *dis) //throws IOException
|
void RemoveEntitiesPacket::read(DataInputStream *dis) //throws IOException
|
||||||
{
|
{
|
||||||
ids = intArray(dis->readByte());
|
int count = dis->readByte();
|
||||||
|
if(count < 0) count = 0;
|
||||||
|
ids = intArray(count);
|
||||||
for(unsigned int i = 0; i < ids.length; ++i)
|
for(unsigned int i = 0; i < ids.length; ++i)
|
||||||
{
|
{
|
||||||
ids[i] = dis->readInt();
|
ids[i] = dis->readInt();
|
||||||
|
|
|
||||||
|
|
@ -141,6 +141,11 @@ void Socket::pushDataToQueue(const BYTE * pbData, DWORD dwDataSize, bool fromHos
|
||||||
// dwDataSize, queueIdx, dwDataSize > 0 ? pbData[0] : 0, networkPlayerSmallId);
|
// dwDataSize, queueIdx, dwDataSize > 0 ? pbData[0] : 0, networkPlayerSmallId);
|
||||||
|
|
||||||
EnterCriticalSection(&m_queueLockNetwork[queueIdx]);
|
EnterCriticalSection(&m_queueLockNetwork[queueIdx]);
|
||||||
|
if (m_queueNetwork[queueIdx].size() + dwDataSize > 2 * 1024 * 1024)
|
||||||
|
{
|
||||||
|
LeaveCriticalSection(&m_queueLockNetwork[queueIdx]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
for( unsigned int i = 0; i < dwDataSize; i++ )
|
for( unsigned int i = 0; i < dwDataSize; i++ )
|
||||||
{
|
{
|
||||||
m_queueNetwork[queueIdx].push(*pbData++);
|
m_queueNetwork[queueIdx].push(*pbData++);
|
||||||
|
|
|
||||||
|
|
@ -342,7 +342,10 @@ vector<shared_ptr<SynchedEntityData::DataItem> > *SynchedEntityData::unpack(Data
|
||||||
|
|
||||||
int currentHeader = input->readByte();
|
int currentHeader = input->readByte();
|
||||||
|
|
||||||
while (currentHeader != EOF_MARKER)
|
int itemCount = 0;
|
||||||
|
const int MAX_ENTITY_DATA_ITEMS = 256;
|
||||||
|
|
||||||
|
while (currentHeader != EOF_MARKER && itemCount < MAX_ENTITY_DATA_ITEMS)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (result == nullptr)
|
if (result == nullptr)
|
||||||
|
|
@ -397,6 +400,7 @@ vector<shared_ptr<SynchedEntityData::DataItem> > *SynchedEntityData::unpack(Data
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
result->push_back(item);
|
result->push_back(item);
|
||||||
|
itemCount++;
|
||||||
|
|
||||||
currentHeader = input->readByte();
|
currentHeader = input->readByte();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -84,27 +84,56 @@ Tag *Tag::readNamedTag(DataInput *dis)
|
||||||
|
|
||||||
Tag *Tag::readNamedTag(DataInput *dis, int tagDepth)
|
Tag *Tag::readNamedTag(DataInput *dis, int tagDepth)
|
||||||
{
|
{
|
||||||
|
static __declspec(thread) int depth = 0;
|
||||||
|
static __declspec(thread) int totalTagCount = 0;
|
||||||
|
|
||||||
|
if (depth == 0)
|
||||||
|
{
|
||||||
|
totalTagCount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
depth++;
|
||||||
|
|
||||||
|
if (depth > 256)
|
||||||
|
{
|
||||||
|
depth--;
|
||||||
|
return new EndTag();
|
||||||
|
}
|
||||||
|
|
||||||
|
totalTagCount++;
|
||||||
|
const int MAX_TOTAL_TAGS = 32768;
|
||||||
|
if (totalTagCount > MAX_TOTAL_TAGS)
|
||||||
|
{
|
||||||
|
depth--;
|
||||||
|
return new EndTag();
|
||||||
|
}
|
||||||
|
|
||||||
byte type = dis->readByte();
|
byte type = dis->readByte();
|
||||||
if (type == 0) return new EndTag();
|
if (type == 0) {
|
||||||
|
depth--;
|
||||||
|
return new EndTag();
|
||||||
|
}
|
||||||
|
|
||||||
// 4J Stu - readByte can return -1, so if it's that then also mark as the end tag
|
// 4J Stu - readByte can return -1, so if it's that then also mark as the end tag
|
||||||
if(type == 255)
|
if(type == 255)
|
||||||
{
|
{
|
||||||
app.DebugPrintf("readNamedTag read a type of 255\n");
|
depth--;
|
||||||
#ifndef _CONTENT_PACKAGE
|
|
||||||
__debugbreak();
|
|
||||||
#endif
|
|
||||||
return new EndTag();
|
return new EndTag();
|
||||||
}
|
}
|
||||||
|
|
||||||
wstring name = dis->readUTF();//new String(bytes, "UTF-8");
|
wstring name = dis->readUTF();//new String(bytes, "UTF-8");
|
||||||
|
|
||||||
Tag *tag = newTag(type, name);
|
Tag *tag = newTag(type, name);
|
||||||
|
if (tag == nullptr) {
|
||||||
|
depth--;
|
||||||
|
return new EndTag();
|
||||||
|
}
|
||||||
// short length = dis.readShort();
|
// short length = dis.readShort();
|
||||||
// byte[] bytes = new byte[length];
|
// byte[] bytes = new byte[length];
|
||||||
// dis.readFully(bytes);
|
// dis.readFully(bytes);
|
||||||
|
|
||||||
tag->load(dis, tagDepth);
|
tag->load(dis, tagDepth);
|
||||||
|
depth--;
|
||||||
return tag;
|
return tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -121,7 +121,20 @@ void TextureAndGeometryPacket::read(DataInputStream *dis) //throws IOException
|
||||||
{
|
{
|
||||||
textureName = dis->readUTF();
|
textureName = dis->readUTF();
|
||||||
dwSkinID = static_cast<DWORD>(dis->readInt());
|
dwSkinID = static_cast<DWORD>(dis->readInt());
|
||||||
dwTextureBytes = static_cast<DWORD>(dis->readShort());
|
|
||||||
|
short rawTextureBytes = dis->readShort();
|
||||||
|
if (rawTextureBytes <= 0)
|
||||||
|
{
|
||||||
|
dwTextureBytes = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dwTextureBytes = (DWORD)(unsigned short)rawTextureBytes;
|
||||||
|
if (dwTextureBytes > 65536)
|
||||||
|
{
|
||||||
|
dwTextureBytes = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(dwTextureBytes>0)
|
if(dwTextureBytes>0)
|
||||||
{
|
{
|
||||||
|
|
@ -134,7 +147,19 @@ void TextureAndGeometryPacket::read(DataInputStream *dis) //throws IOException
|
||||||
}
|
}
|
||||||
uiAnimOverrideBitmask = dis->readInt();
|
uiAnimOverrideBitmask = dis->readInt();
|
||||||
|
|
||||||
dwBoxC = static_cast<DWORD>(dis->readShort());
|
short rawBoxC = dis->readShort();
|
||||||
|
if (rawBoxC <= 0)
|
||||||
|
{
|
||||||
|
dwBoxC = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dwBoxC = (DWORD)(unsigned short)rawBoxC;
|
||||||
|
if (dwBoxC > 256)
|
||||||
|
{
|
||||||
|
dwBoxC = 0; // sane limit for skin boxes
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(dwBoxC>0)
|
if(dwBoxC>0)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -37,17 +37,26 @@ void TexturePacket::handle(PacketListener *listener)
|
||||||
void TexturePacket::read(DataInputStream *dis) //throws IOException
|
void TexturePacket::read(DataInputStream *dis) //throws IOException
|
||||||
{
|
{
|
||||||
textureName = dis->readUTF();
|
textureName = dis->readUTF();
|
||||||
dwBytes = static_cast<DWORD>(dis->readShort());
|
short rawBytes = dis->readShort();
|
||||||
|
if (rawBytes <= 0)
|
||||||
|
{
|
||||||
|
dwBytes = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
dwBytes = (DWORD)(unsigned short)rawBytes;
|
||||||
|
if (dwBytes > 65536)
|
||||||
|
{
|
||||||
|
dwBytes = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->pbData= new BYTE [dwBytes];
|
||||||
|
|
||||||
if(dwBytes>0)
|
for(DWORD i=0;i<dwBytes;i++)
|
||||||
{
|
{
|
||||||
this->pbData= new BYTE [dwBytes];
|
this->pbData[i] = dis->readByte();
|
||||||
|
|
||||||
for(DWORD i=0;i<dwBytes;i++)
|
|
||||||
{
|
|
||||||
this->pbData[i] = dis->readByte();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TexturePacket::write(DataOutputStream *dos) //throws IOException
|
void TexturePacket::write(DataOutputStream *dos) //throws IOException
|
||||||
|
|
|
||||||
|
|
@ -22,9 +22,9 @@ void SetThreadName( DWORD dwThreadID, LPCSTR szThreadName )
|
||||||
#if ( defined _WINDOWS64 | defined _DURANGO )
|
#if ( defined _WINDOWS64 | defined _DURANGO )
|
||||||
__try
|
__try
|
||||||
{
|
{
|
||||||
RaiseException( 0x406D1388, 0, sizeof(info)/sizeof(DWORD), (ULONG_PTR *)&info );
|
RaiseException(0x406D1388, 0, sizeof(info)/sizeof(ULONG_PTR), (ULONG_PTR *)&info);
|
||||||
}
|
}
|
||||||
__except( GetExceptionCode()==0x406D1388 ? EXCEPTION_CONTINUE_EXECUTION : EXCEPTION_EXECUTE_HANDLER )
|
__except (EXCEPTION_EXECUTE_HANDLER)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ UpdateGameRuleProgressPacket::UpdateGameRuleProgressPacket(ConsoleGameRules::EGa
|
||||||
m_auxValue = auxValue;
|
m_auxValue = auxValue;
|
||||||
m_dataTag = dataTag;
|
m_dataTag = dataTag;
|
||||||
|
|
||||||
if(dataLength > 0)
|
if (dataLength > 0 && dataLength <= 65536)
|
||||||
{
|
{
|
||||||
m_data = byteArray(dataLength);
|
m_data = byteArray(dataLength);
|
||||||
memcpy(m_data.data,data,dataLength);
|
memcpy(m_data.data,data,dataLength);
|
||||||
|
|
|
||||||
|
|
@ -237,9 +237,19 @@ HRESULT Compression::DecompressLZXRLE(void *pDestination, unsigned int *pDestSiz
|
||||||
unsigned char *dynamicRleBuf = nullptr;
|
unsigned char *dynamicRleBuf = nullptr;
|
||||||
HRESULT decompressResult;
|
HRESULT decompressResult;
|
||||||
|
|
||||||
if(*pDestSize > rleSize)
|
unsigned int safeRleSize = max(rleSize, *pDestSize);
|
||||||
|
|
||||||
|
const unsigned int MAX_RLE_ALLOC = 16 * 1024 * 1024; // 16 MB
|
||||||
|
if (safeRleSize > MAX_RLE_ALLOC)
|
||||||
|
{
|
||||||
|
LeaveCriticalSection(&rleDecompressLock);
|
||||||
|
*pDestSize = 0;
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (safeRleSize > staticRleSize)
|
||||||
{
|
{
|
||||||
rleSize = *pDestSize;
|
rleSize = safeRleSize;
|
||||||
dynamicRleBuf = new unsigned char[rleSize];
|
dynamicRleBuf = new unsigned char[rleSize];
|
||||||
decompressResult = Decompress(dynamicRleBuf, &rleSize, pSource, SrcSize);
|
decompressResult = Decompress(dynamicRleBuf, &rleSize, pSource, SrcSize);
|
||||||
pucIn = (unsigned char *)dynamicRleBuf;
|
pucIn = (unsigned char *)dynamicRleBuf;
|
||||||
|
|
@ -263,7 +273,7 @@ HRESULT Compression::DecompressLZXRLE(void *pDestination, unsigned int *pDestSiz
|
||||||
//unsigned char *pucIn = (unsigned char *)rleDecompressBuf;
|
//unsigned char *pucIn = (unsigned char *)rleDecompressBuf;
|
||||||
const unsigned char *pucEnd = pucIn + rleSize;
|
const unsigned char *pucEnd = pucIn + rleSize;
|
||||||
unsigned char *pucOut = static_cast<unsigned char*>(pDestination);
|
unsigned char *pucOut = static_cast<unsigned char*>(pDestination);
|
||||||
const unsigned char *pucOutEnd = pucOut + *pDestSize;
|
unsigned char *pucOutEnd = pucOut + *pDestSize;
|
||||||
|
|
||||||
while( pucIn != pucEnd )
|
while( pucIn != pucEnd )
|
||||||
{
|
{
|
||||||
|
|
@ -275,7 +285,11 @@ HRESULT Compression::DecompressLZXRLE(void *pDestination, unsigned int *pDestSiz
|
||||||
if( count < 3 )
|
if( count < 3 )
|
||||||
{
|
{
|
||||||
count++;
|
count++;
|
||||||
if( pucOut + count > pucOutEnd ) break;
|
if (pucOut + count > pucOutEnd)
|
||||||
|
{
|
||||||
|
pucOut = pucOutEnd;
|
||||||
|
break;
|
||||||
|
}
|
||||||
for( unsigned int i = 0; i < count; i++ )
|
for( unsigned int i = 0; i < count; i++ )
|
||||||
{
|
{
|
||||||
*pucOut++ = 255;
|
*pucOut++ = 255;
|
||||||
|
|
@ -286,7 +300,11 @@ HRESULT Compression::DecompressLZXRLE(void *pDestination, unsigned int *pDestSiz
|
||||||
count++;
|
count++;
|
||||||
if( pucIn >= pucEnd ) break;
|
if( pucIn >= pucEnd ) break;
|
||||||
const unsigned char data = *pucIn++;
|
const unsigned char data = *pucIn++;
|
||||||
if( pucOut + count > pucOutEnd ) break;
|
if (pucOut + count > pucOutEnd)
|
||||||
|
{
|
||||||
|
pucOut = pucOutEnd;
|
||||||
|
break;
|
||||||
|
}
|
||||||
for( unsigned int i = 0; i < count; i++ )
|
for( unsigned int i = 0; i < count; i++ )
|
||||||
{
|
{
|
||||||
*pucOut++ = data;
|
*pucOut++ = data;
|
||||||
|
|
@ -317,7 +335,7 @@ HRESULT Compression::DecompressRLE(void *pDestination, unsigned int *pDestSize,
|
||||||
unsigned char *pucIn = static_cast<unsigned char *>(pSource);
|
unsigned char *pucIn = static_cast<unsigned char *>(pSource);
|
||||||
const unsigned char *pucEnd = pucIn + SrcSize;
|
const unsigned char *pucEnd = pucIn + SrcSize;
|
||||||
unsigned char *pucOut = static_cast<unsigned char*>(pDestination);
|
unsigned char *pucOut = static_cast<unsigned char*>(pDestination);
|
||||||
const unsigned char *pucOutEnd = pucOut + *pDestSize;
|
unsigned char *pucOutEnd = pucOut + *pDestSize;
|
||||||
|
|
||||||
while( pucIn != pucEnd )
|
while( pucIn != pucEnd )
|
||||||
{
|
{
|
||||||
|
|
@ -329,7 +347,11 @@ HRESULT Compression::DecompressRLE(void *pDestination, unsigned int *pDestSize,
|
||||||
if( count < 3 )
|
if( count < 3 )
|
||||||
{
|
{
|
||||||
count++;
|
count++;
|
||||||
if( pucOut + count > pucOutEnd ) break;
|
if (pucOut + count > pucOutEnd)
|
||||||
|
{
|
||||||
|
pucOut = pucOutEnd;
|
||||||
|
break;
|
||||||
|
}
|
||||||
for( unsigned int i = 0; i < count; i++ )
|
for( unsigned int i = 0; i < count; i++ )
|
||||||
{
|
{
|
||||||
*pucOut++ = 255;
|
*pucOut++ = 255;
|
||||||
|
|
@ -340,7 +362,11 @@ HRESULT Compression::DecompressRLE(void *pDestination, unsigned int *pDestSize,
|
||||||
count++;
|
count++;
|
||||||
if( pucIn >= pucEnd ) break;
|
if( pucIn >= pucEnd ) break;
|
||||||
const unsigned char data = *pucIn++;
|
const unsigned char data = *pucIn++;
|
||||||
if( pucOut + count > pucOutEnd ) break;
|
if (pucOut + count > pucOutEnd)
|
||||||
|
{
|
||||||
|
pucOut = pucOutEnd;
|
||||||
|
break;
|
||||||
|
}
|
||||||
for( unsigned int i = 0; i < count; i++ )
|
for( unsigned int i = 0; i < count; i++ )
|
||||||
{
|
{
|
||||||
*pucOut++ = data;
|
*pucOut++ = data;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue