mirror of
https://github.com/LCEMP/LCEMP.git
synced 2026-05-28 06:42:54 +00:00
a lot
This commit is contained in:
parent
39ffeedde1
commit
341963b9c0
|
|
@ -49,12 +49,11 @@ void BufferedImage::ByteFlip4(unsigned int &data)
|
|||
// 24-bits used (ie no alpha channel) whereas method 0 is a full 32-bit image with a valid alpha channel.
|
||||
BufferedImage::BufferedImage(const wstring& File, bool filenameHasExtension /*=false*/, bool bTitleUpdateTexture /*=false*/, const wstring &drive /*=L""*/)
|
||||
{
|
||||
HRESULT hr;
|
||||
wstring wDrive;
|
||||
wstring filePath;
|
||||
filePath = File;
|
||||
|
||||
wDrive = drive;
|
||||
HRESULT hr = ERROR_SUCCESS;
|
||||
wstring wDrive = drive;
|
||||
wstring filePath = File;
|
||||
width = 0;
|
||||
height = 0;
|
||||
if(wDrive.empty())
|
||||
{
|
||||
#ifdef _XBOX
|
||||
|
|
@ -170,9 +169,53 @@ BufferedImage::BufferedImage(const wstring& File, bool filenameHasExtension /*=f
|
|||
ZeroMemory(&ImageInfo,sizeof(D3DXIMAGE_INFO));
|
||||
hr=RenderManager.LoadTextureData(pchTextureName,&ImageInfo,&data[l]);
|
||||
|
||||
#if defined(_WINDOWS64)
|
||||
if (hr != ERROR_SUCCESS && l == 0 && drive.empty())
|
||||
{
|
||||
static const wchar_t *fallbackDrives[] =
|
||||
{
|
||||
L"Minecraft.Client/Common/",
|
||||
L"Common/",
|
||||
L"../Minecraft.Client/Common/",
|
||||
L"../Common/",
|
||||
L"..\\Minecraft.Client\\Common\\",
|
||||
L"..\\Common\\"
|
||||
};
|
||||
const unsigned int fallbackDriveCount = sizeof(fallbackDrives) / sizeof(fallbackDrives[0]);
|
||||
|
||||
for (unsigned int f = 0; f < fallbackDriveCount; ++f)
|
||||
{
|
||||
const wstring fallbackDrive = fallbackDrives[f];
|
||||
if (fallbackDrive == wDrive)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
wstring fallbackName;
|
||||
if (filenameHasExtension)
|
||||
{
|
||||
fallbackName = fallbackDrive + L"res" + filePath.substr(0, filePath.length());
|
||||
}
|
||||
else
|
||||
{
|
||||
fallbackName = fallbackDrive + L"res" + filePath.substr(0, filePath.length() - 4) + mipMapPath + L".png";
|
||||
}
|
||||
|
||||
const char *fallbackTextureName = wstringtofilename(fallbackName);
|
||||
hr = RenderManager.LoadTextureData(fallbackTextureName, &ImageInfo, &data[l]);
|
||||
if (hr == ERROR_SUCCESS)
|
||||
{
|
||||
app.DebugPrintf("BufferedImage: fallback load succeeded for '%s'\n", fallbackTextureName);
|
||||
wDrive = fallbackDrive;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if(hr!=ERROR_SUCCESS)
|
||||
{
|
||||
app.DebugPrintf("BufferedImage: failed to load texture '%s' (hr=0x%08X)\n", pchTextureName, (unsigned int)hr);
|
||||
// 4J - If we haven't loaded the non-mipmap version then exit the game
|
||||
if( l == 0 )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -47,6 +47,9 @@
|
|||
#else
|
||||
#include "Common\UI\UI.h"
|
||||
#endif
|
||||
#ifdef _WINDOWS64
|
||||
#include "Common\Network\PlatformNetworkManagerStub.h"
|
||||
#endif
|
||||
#ifdef __PS3__
|
||||
#include "PS3/Network/SonyVoiceChat.h"
|
||||
#endif
|
||||
|
|
@ -57,6 +60,26 @@
|
|||
#include "..\Minecraft.World\GenericStats.h"
|
||||
#endif
|
||||
|
||||
namespace
|
||||
{
|
||||
const wstring LCE_TRANSFER_PACKET = L"LCE|Xfer";
|
||||
|
||||
string NarrowAscii(const wstring &value)
|
||||
{
|
||||
string out;
|
||||
out.reserve(value.length());
|
||||
for (size_t i = 0; i < value.length(); ++i)
|
||||
{
|
||||
const wchar_t ch = value[i];
|
||||
if (ch >= 32 && ch <= 126)
|
||||
{
|
||||
out.push_back((char)ch);
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
}
|
||||
|
||||
ClientConnection::ClientConnection(Minecraft *minecraft, const wstring& ip, int port)
|
||||
{
|
||||
// 4J Stu - No longer used as we use the socket version below.
|
||||
|
|
@ -140,6 +163,19 @@ ClientConnection::~ClientConnection()
|
|||
|
||||
void ClientConnection::tick()
|
||||
{
|
||||
if (connection == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef _WINDOWS64
|
||||
if (CPlatformNetworkManagerStub::IsServerTransferInProgress())
|
||||
{
|
||||
connection->flush();
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!done) connection->tick();
|
||||
connection->flush();
|
||||
}
|
||||
|
|
@ -704,6 +740,17 @@ void ClientConnection::handleAddPainting(shared_ptr<AddPaintingPacket> packet)
|
|||
|
||||
void ClientConnection::handleSetEntityMotion(shared_ptr<SetEntityMotionPacket> packet)
|
||||
{
|
||||
#ifdef _WINDOWS64
|
||||
if (CPlatformNetworkManagerStub::IsServerTransferInProgress())
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if (!started || level == NULL || minecraft == NULL || minecraft->level == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
shared_ptr<Entity> e = getEntity(packet->id);
|
||||
if (e == NULL) return;
|
||||
e->lerpMotion(packet->xa / 8000.0, packet->ya / 8000.0, packet->za / 8000.0);
|
||||
|
|
@ -1136,6 +1183,16 @@ void ClientConnection::handleDisconnect(shared_ptr<DisconnectPacket> packet)
|
|||
{
|
||||
connection->close(DisconnectPacket::eDisconnect_Kicked);
|
||||
done = true;
|
||||
|
||||
#ifdef _WINDOWS64
|
||||
if (CPlatformNetworkManagerStub::IsServerTransferInProgress())
|
||||
{
|
||||
level = NULL;
|
||||
started = false;
|
||||
app.DebugPrintf("Win64 LAN: Ignoring handleDisconnect during in-progress server transfer\n");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
Minecraft *pMinecraft = Minecraft::GetInstance();
|
||||
pMinecraft->connectionDisconnected( m_userIndex , packet->reason );
|
||||
|
|
@ -1152,6 +1209,16 @@ void ClientConnection::onDisconnect(DisconnectPacket::eDisconnectReason reason,
|
|||
if (done) return;
|
||||
done = true;
|
||||
|
||||
#ifdef _WINDOWS64
|
||||
if (CPlatformNetworkManagerStub::IsServerTransferInProgress())
|
||||
{
|
||||
level = NULL;
|
||||
started = false;
|
||||
app.DebugPrintf("Win64 LAN: Ignoring onDisconnect during in-progress server transfer (reason=%d)\n", (int)reason);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
Minecraft *pMinecraft = Minecraft::GetInstance();
|
||||
pMinecraft->connectionDisconnected( m_userIndex , reason );
|
||||
|
||||
|
|
@ -1281,6 +1348,20 @@ void ClientConnection::handleChat(shared_ptr<ChatPacket> packet)
|
|||
|
||||
switch(packet->m_messageType)
|
||||
{
|
||||
case ChatPacket::e_ChatCustom:
|
||||
if(packet->m_stringArgs.size() >= 2)
|
||||
{
|
||||
message = L"<" + playerDisplayName + L"> " + packet->m_stringArgs[1];
|
||||
}
|
||||
else if(packet->m_stringArgs.size() >= 1)
|
||||
{
|
||||
message = packet->m_stringArgs[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
message = L"";
|
||||
}
|
||||
break;
|
||||
case ChatPacket::e_ChatBedOccupied:
|
||||
message = app.GetString(IDS_TILE_BED_OCCUPIED);
|
||||
break;
|
||||
|
|
@ -2186,6 +2267,21 @@ void ClientConnection::handleEntityEvent(shared_ptr<EntityEventPacket> packet)
|
|||
|
||||
shared_ptr<Entity> ClientConnection::getEntity(int entityId)
|
||||
{
|
||||
if (!started || level == NULL || minecraft == NULL || minecraft->level == NULL)
|
||||
{
|
||||
return shared_ptr<Entity>();
|
||||
}
|
||||
|
||||
if (m_userIndex < 0 || m_userIndex >= XUSER_MAX_COUNT)
|
||||
{
|
||||
return shared_ptr<Entity>();
|
||||
}
|
||||
|
||||
if (minecraft->localplayers[m_userIndex] == NULL)
|
||||
{
|
||||
return shared_ptr<Entity>();
|
||||
}
|
||||
|
||||
//if (entityId == minecraft->player->entityId)
|
||||
if(entityId == minecraft->localplayers[m_userIndex]->entityId)
|
||||
{
|
||||
|
|
@ -2841,7 +2937,15 @@ void ClientConnection::handleTileDestruction(shared_ptr<TileDestructionPacket> p
|
|||
|
||||
bool ClientConnection::canHandleAsyncPackets()
|
||||
{
|
||||
return minecraft != NULL && minecraft->level != NULL && minecraft->localplayers[m_userIndex] != NULL && level != NULL;
|
||||
if (minecraft == NULL || level == NULL || minecraft->level == NULL || !started)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (m_userIndex < 0 || m_userIndex >= XUSER_MAX_COUNT)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return minecraft->localplayers[m_userIndex] != NULL;
|
||||
}
|
||||
|
||||
void ClientConnection::handleGameEvent(shared_ptr<GameEventPacket> gameEventPacket)
|
||||
|
|
@ -3148,6 +3252,41 @@ void ClientConnection::handleSoundEvent(shared_ptr<LevelSoundPacket> packet)
|
|||
|
||||
void ClientConnection::handleCustomPayload(shared_ptr<CustomPayloadPacket> customPayloadPacket)
|
||||
{
|
||||
if (LCE_TRANSFER_PACKET.compare(customPayloadPacket->identifier) == 0)
|
||||
{
|
||||
#ifdef _WINDOWS64
|
||||
ByteArrayInputStream bais(customPayloadPacket->data);
|
||||
DataInputStream input(&bais);
|
||||
const int payloadVersion = (int)input.readUnsignedByte();
|
||||
const int queueIndex = (int)input.readUnsignedByte();
|
||||
const int hostPort = input.readInt();
|
||||
const wstring hostIpW = input.readUTF();
|
||||
const wstring queueLabel = input.readUTF();
|
||||
const string hostIp = NarrowAscii(hostIpW);
|
||||
|
||||
app.DebugPrintf("Win64 LAN: Received transfer payload v%d queue=%d target=%s:%d label=%ls\n",
|
||||
payloadVersion, queueIndex, hostIp.c_str(), hostPort, queueLabel.c_str());
|
||||
|
||||
if (!hostIp.empty() && hostPort > 0)
|
||||
{
|
||||
CPlatformNetworkManagerStub::RequestServerTransfer(hostIp.c_str(), hostPort);
|
||||
wstring message = L"Match found";
|
||||
if (!queueLabel.empty())
|
||||
{
|
||||
message += L" for ";
|
||||
message += queueLabel;
|
||||
}
|
||||
message += L". Transferring...";
|
||||
minecraft->gui->addMessage(message, m_userIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
app.DebugPrintf("Win64 LAN: Ignoring invalid transfer payload target\n");
|
||||
}
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
if (CustomPayloadPacket::TRADER_LIST_PACKET.compare(customPayloadPacket->identifier) == 0)
|
||||
{
|
||||
ByteArrayInputStream bais(customPayloadPacket->data);
|
||||
|
|
|
|||
|
|
@ -456,9 +456,6 @@ void SoundEngine::updateMiles()
|
|||
|
||||
if ( SoundInfo.Status != MILESEVENT_SOUND_STATUS_COMPLETE )
|
||||
{
|
||||
if (SoundInfo.Sample == NULL)
|
||||
continue;
|
||||
|
||||
// apply the master volume
|
||||
// watch for the 'special' volume levels
|
||||
bool isThunder = false;
|
||||
|
|
|
|||
|
|
@ -69,6 +69,62 @@
|
|||
|
||||
#include "..\Common\Leaderboards\LeaderboardManager.h"
|
||||
|
||||
#ifdef _WINDOWS64
|
||||
extern void Windows64_DedicatedGuiPushLog(const char *text);
|
||||
|
||||
static void WriteStandaloneDebugLog(const char *text)
|
||||
{
|
||||
if (text == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
wchar_t exePath[MAX_PATH];
|
||||
if (!GetModuleFileNameW(NULL, exePath, MAX_PATH))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
wstring logPath(exePath);
|
||||
size_t lastSlash = logPath.find_last_of(L"\\/");
|
||||
if (lastSlash != wstring::npos)
|
||||
{
|
||||
logPath = logPath.substr(0, lastSlash + 1) + L"StandaloneDebug.log";
|
||||
}
|
||||
else
|
||||
{
|
||||
logPath = L"StandaloneDebug.log";
|
||||
}
|
||||
|
||||
HANDLE file = CreateFileW(logPath.c_str(), FILE_APPEND_DATA, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (file == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SYSTEMTIME st;
|
||||
GetLocalTime(&st);
|
||||
|
||||
char prefix[64];
|
||||
_snprintf_s(prefix, sizeof(prefix), _TRUNCATE, "[%02d:%02d:%02d.%03d] ",
|
||||
st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
|
||||
|
||||
DWORD bytesWritten = 0;
|
||||
WriteFile(file, prefix, (DWORD)strlen(prefix), &bytesWritten, NULL);
|
||||
WriteFile(file, text, (DWORD)strlen(text), &bytesWritten, NULL);
|
||||
|
||||
size_t len = strlen(text);
|
||||
if (len == 0 || (text[len - 1] != '\n' && text[len - 1] != '\r'))
|
||||
{
|
||||
const char *newline = "\r\n";
|
||||
WriteFile(file, newline, (DWORD)strlen(newline), &bytesWritten, NULL);
|
||||
}
|
||||
|
||||
CloseHandle(file);
|
||||
Windows64_DedicatedGuiPushLog(text);
|
||||
}
|
||||
#endif
|
||||
|
||||
//CMinecraftApp app;
|
||||
unsigned int CMinecraftApp::m_uiLastSignInData = 0;
|
||||
|
||||
|
|
@ -233,21 +289,23 @@ CMinecraftApp::CMinecraftApp()
|
|||
|
||||
void CMinecraftApp::DebugPrintf(const char *szFormat, ...)
|
||||
{
|
||||
|
||||
#ifndef _FINAL_BUILD
|
||||
char buf[1024];
|
||||
va_list ap;
|
||||
va_start(ap, szFormat);
|
||||
vsnprintf(buf, sizeof(buf), szFormat, ap);
|
||||
va_end(ap);
|
||||
|
||||
#ifndef _FINAL_BUILD
|
||||
OutputDebugStringA(buf);
|
||||
#endif
|
||||
|
||||
#ifdef _WINDOWS64
|
||||
WriteStandaloneDebugLog(buf);
|
||||
#endif
|
||||
}
|
||||
|
||||
void CMinecraftApp::DebugPrintf(int user, const char *szFormat, ...)
|
||||
{
|
||||
#ifndef _FINAL_BUILD
|
||||
if(user == USER_NONE)
|
||||
return;
|
||||
char buf[1024];
|
||||
|
|
@ -255,6 +313,7 @@ void CMinecraftApp::DebugPrintf(int user, const char *szFormat, ...)
|
|||
va_start(ap, szFormat);
|
||||
vsnprintf(buf, sizeof(buf), szFormat, ap);
|
||||
va_end(ap);
|
||||
#ifndef _FINAL_BUILD
|
||||
#ifdef __PS3__
|
||||
unsigned int writelen;
|
||||
sys_tty_write(SYS_TTYP_USER1 + ( user - 1 ), buf, strlen(buf), &writelen );
|
||||
|
|
@ -297,12 +356,26 @@ void CMinecraftApp::DebugPrintf(int user, const char *szFormat, ...)
|
|||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef _WINDOWS64
|
||||
WriteStandaloneDebugLog(buf);
|
||||
#endif
|
||||
}
|
||||
|
||||
LPCWSTR CMinecraftApp::GetString(int iID)
|
||||
{
|
||||
//return L"Değişiklikler ve Yenilikler";
|
||||
//return L"ÕÕÕÕÖÖÖÖ";
|
||||
if (app.m_stringTable == NULL)
|
||||
{
|
||||
static int s_missingStringTableLogCount = 0;
|
||||
if (s_missingStringTableLogCount < 16)
|
||||
{
|
||||
app.DebugPrintf("CMinecraftApp::GetString - null m_stringTable for id %d\n", iID);
|
||||
s_missingStringTableLogCount++;
|
||||
}
|
||||
return L"";
|
||||
}
|
||||
return app.m_stringTable->getString(iID);
|
||||
}
|
||||
|
||||
|
|
@ -4085,23 +4158,65 @@ int CMinecraftApp::BannedLevelDialogReturned(void *pParam,int iPad,const C4JStor
|
|||
|
||||
void CMinecraftApp::loadMediaArchive()
|
||||
{
|
||||
wstring mediapath = L"";
|
||||
wstring mediaFileName = L"";
|
||||
|
||||
#ifdef __PS3__
|
||||
mediapath = L"Common\\Media\\MediaPS3.arc";
|
||||
mediaFileName = L"MediaPS3.arc";
|
||||
#elif _WINDOWS64
|
||||
mediapath = L"Common\\Media\\MediaWindows64.arc";
|
||||
mediaFileName = L"MediaWindows64.arc";
|
||||
#elif __ORBIS__
|
||||
mediapath = L"Common\\Media\\MediaOrbis.arc";
|
||||
mediaFileName = L"MediaOrbis.arc";
|
||||
#elif _DURANGO
|
||||
mediapath = L"Common\\Media\\MediaDurango.arc";
|
||||
mediaFileName = L"MediaDurango.arc";
|
||||
#elif __PSVITA__
|
||||
mediapath = L"Common\\Media\\MediaPSVita.arc";
|
||||
mediaFileName = L"MediaPSVita.arc";
|
||||
#endif
|
||||
|
||||
if (!mediapath.empty())
|
||||
if (!mediaFileName.empty())
|
||||
{
|
||||
m_mediaArchive = new ArchiveFile( File(mediapath) );
|
||||
if (m_mediaArchive != NULL)
|
||||
{
|
||||
delete m_mediaArchive;
|
||||
m_mediaArchive = NULL;
|
||||
}
|
||||
|
||||
vector<wstring> candidates;
|
||||
candidates.push_back(L"Common\\Media\\" + mediaFileName);
|
||||
candidates.push_back(L"Minecraft.Client\\Common\\Media\\" + mediaFileName);
|
||||
|
||||
#if defined(_WINDOWS64) || defined(_WIN32)
|
||||
wchar_t exePath[MAX_PATH];
|
||||
if (GetModuleFileNameW(NULL, exePath, MAX_PATH))
|
||||
{
|
||||
wstring exeDir(exePath);
|
||||
size_t lastSlash = exeDir.find_last_of(L"\\/");
|
||||
if (lastSlash != wstring::npos)
|
||||
{
|
||||
exeDir = exeDir.substr(0, lastSlash);
|
||||
wstring root = exeDir;
|
||||
for (int i = 0; i < 8; ++i)
|
||||
{
|
||||
candidates.push_back(root + L"\\Common\\Media\\" + mediaFileName);
|
||||
candidates.push_back(root + L"\\Minecraft.Client\\Common\\Media\\" + mediaFileName);
|
||||
root += L"\\..";
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
for (AUTO_VAR(it, candidates.begin()); it != candidates.end(); ++it)
|
||||
{
|
||||
File archiveCandidate(*it);
|
||||
if (archiveCandidate.exists())
|
||||
{
|
||||
app.DebugPrintf("CMinecraftApp::loadMediaArchive - using '%ls'\n", it->c_str());
|
||||
m_mediaArchive = new ArchiveFile(archiveCandidate);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
app.DebugPrintf("CMinecraftApp::loadMediaArchive - failed to locate '%ls'\n", mediaFileName.c_str());
|
||||
m_mediaArchive = NULL;
|
||||
}
|
||||
#if 0
|
||||
string path = "Common\\media.arc";
|
||||
|
|
@ -4153,6 +4268,18 @@ void CMinecraftApp::loadStringTable()
|
|||
// we need to unload the current string table, this is a reload
|
||||
delete m_stringTable;
|
||||
}
|
||||
m_stringTable = NULL;
|
||||
|
||||
if (m_mediaArchive == NULL)
|
||||
{
|
||||
loadMediaArchive();
|
||||
if (m_mediaArchive == NULL)
|
||||
{
|
||||
DebugPrintf("CMinecraftApp::loadStringTable - media archive not loaded\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
wstring localisationFile = L"languages.loc";
|
||||
if (m_mediaArchive->hasFile(localisationFile))
|
||||
{
|
||||
|
|
@ -4162,9 +4289,7 @@ void CMinecraftApp::loadStringTable()
|
|||
}
|
||||
else
|
||||
{
|
||||
m_stringTable = NULL;
|
||||
assert(false);
|
||||
// AHHHHHHHHH.
|
||||
DebugPrintf("CMinecraftApp::loadStringTable - missing file '%ls'\n", localisationFile.c_str());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
@ -8864,7 +8989,17 @@ int CMinecraftApp::getArchiveFileSize(const wstring &filename)
|
|||
{
|
||||
return tPack->getArchiveFile()->getFileSize(filename);
|
||||
}
|
||||
else return m_mediaArchive->getFileSize(filename);
|
||||
|
||||
if (m_mediaArchive == NULL)
|
||||
{
|
||||
loadMediaArchive();
|
||||
}
|
||||
if (m_mediaArchive != NULL)
|
||||
{
|
||||
return m_mediaArchive->getFileSize(filename);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool CMinecraftApp::hasArchiveFile(const wstring &filename)
|
||||
|
|
@ -8873,7 +9008,12 @@ bool CMinecraftApp::hasArchiveFile(const wstring &filename)
|
|||
Minecraft *pMinecraft = Minecraft::GetInstance();
|
||||
if(pMinecraft && pMinecraft->skins) tPack = pMinecraft->skins->getSelected();
|
||||
if(tPack && tPack->hasData() && tPack->getArchiveFile() && tPack->getArchiveFile()->hasFile(filename)) return true;
|
||||
else return m_mediaArchive->hasFile(filename);
|
||||
|
||||
if (m_mediaArchive == NULL)
|
||||
{
|
||||
loadMediaArchive();
|
||||
}
|
||||
return m_mediaArchive != NULL && m_mediaArchive->hasFile(filename);
|
||||
}
|
||||
|
||||
byteArray CMinecraftApp::getArchiveFile(const wstring &filename)
|
||||
|
|
@ -8885,7 +9025,17 @@ byteArray CMinecraftApp::getArchiveFile(const wstring &filename)
|
|||
{
|
||||
return tPack->getArchiveFile()->getFile(filename);
|
||||
}
|
||||
else return m_mediaArchive->getFile(filename);
|
||||
|
||||
if (m_mediaArchive == NULL)
|
||||
{
|
||||
loadMediaArchive();
|
||||
}
|
||||
if (m_mediaArchive != NULL)
|
||||
{
|
||||
return m_mediaArchive->getFile(filename);
|
||||
}
|
||||
|
||||
return byteArray();
|
||||
}
|
||||
|
||||
// DLC
|
||||
|
|
@ -9536,4 +9686,4 @@ bool CMinecraftApp::HasReachedMainMenu()
|
|||
{
|
||||
return m_hasReachedMainMenu;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -40,6 +40,10 @@
|
|||
#include "..\Minecraft.World\DurangoStats.h"
|
||||
#endif
|
||||
|
||||
#ifdef _WINDOWS64
|
||||
extern bool g_Win64DedicatedServerMode;
|
||||
#endif
|
||||
|
||||
// Global instance
|
||||
CGameNetworkManager g_NetworkManager;
|
||||
CPlatformNetworkManager *CGameNetworkManager::s_pPlatformNetworkManager;
|
||||
|
|
@ -281,186 +285,199 @@ bool CGameNetworkManager::StartNetworkGame(Minecraft *minecraft, LPVOID lpParame
|
|||
// PRIMARY PLAYER
|
||||
|
||||
vector<ClientConnection *> createdConnections;
|
||||
ClientConnection *connection;
|
||||
ClientConnection *connection = NULL;
|
||||
#ifdef _WINDOWS64
|
||||
const bool dedicatedHeadlessHost = (g_NetworkManager.IsHost() && g_Win64DedicatedServerMode);
|
||||
#else
|
||||
const bool dedicatedHeadlessHost = false;
|
||||
#endif
|
||||
|
||||
if( g_NetworkManager.IsHost() )
|
||||
if (!dedicatedHeadlessHost)
|
||||
{
|
||||
connection = new ClientConnection(minecraft, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
INetworkPlayer *pNetworkPlayer = g_NetworkManager.GetLocalPlayerByUserIndex(ProfileManager.GetLockedProfile());
|
||||
if(pNetworkPlayer == NULL)
|
||||
if( g_NetworkManager.IsHost() )
|
||||
{
|
||||
MinecraftServer::HaltServer();
|
||||
app.DebugPrintf("%d\n",ProfileManager.GetLockedProfile());
|
||||
// If the player is NULL here then something went wrong in the session setup, and continuing will end up in a crash
|
||||
return false;
|
||||
}
|
||||
|
||||
Socket *socket = pNetworkPlayer->GetSocket();
|
||||
|
||||
// Fix for #13259 - CRASH: Gameplay: loading process is halted when player loads saved data
|
||||
if(socket == NULL)
|
||||
{
|
||||
assert(false);
|
||||
MinecraftServer::HaltServer();
|
||||
// If the socket is NULL here then something went wrong in the session setup, and continuing will end up in a crash
|
||||
return false;
|
||||
}
|
||||
|
||||
connection = new ClientConnection(minecraft, socket);
|
||||
}
|
||||
|
||||
if( !connection->createdOk )
|
||||
{
|
||||
assert(false);
|
||||
delete connection;
|
||||
connection = NULL;
|
||||
MinecraftServer::HaltServer();
|
||||
return false;
|
||||
}
|
||||
|
||||
connection->send( shared_ptr<PreLoginPacket>( new PreLoginPacket(minecraft->user->name) ) );
|
||||
|
||||
// Tick connection until we're ready to go. The stages involved in this are:
|
||||
// (1) Creating the ClientConnection sends a prelogin packet to the server
|
||||
// (2) the server sends a prelogin back, which is handled by the clientConnection, and returns a login packet
|
||||
// (3) the server sends a login back, which is handled by the client connection to start the game
|
||||
if( !g_NetworkManager.IsHost() )
|
||||
{
|
||||
Minecraft::GetInstance()->progressRenderer->progressStart(IDS_PROGRESS_CONNECTING);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 4J Stu - Host needs to generate a unique multiplayer id for sentient telemetry reporting
|
||||
INT multiplayerInstanceId = TelemetryManager->GenerateMultiplayerInstanceId();
|
||||
TelemetryManager->SetMultiplayerInstanceId(multiplayerInstanceId);
|
||||
}
|
||||
TexturePack *tPack = Minecraft::GetInstance()->skins->getSelected();
|
||||
do
|
||||
{
|
||||
app.DebugPrintf("ticking connection A\n");
|
||||
connection->tick();
|
||||
|
||||
// 4J Stu - We were ticking this way too fast which could cause the connection to time out
|
||||
// The connections should tick at 20 per second
|
||||
Sleep(50);
|
||||
} while ( (IsInSession() && !connection->isStarted() && !connection->isClosed() && !g_NetworkManager.IsLeavingGame()) || tPack->isLoadingData() || (Minecraft::GetInstance()->skins->needsUIUpdate() || ui.IsReloadingSkin()) );
|
||||
ui.CleanUpSkinReload();
|
||||
|
||||
// 4J Stu - Fix for #11279 - CRASH: TCR 001: BAS Game Stability: Signing out of game will cause title to crash
|
||||
// We need to break out of the above loop if m_bLeavingGame is set, and close the connection
|
||||
if( g_NetworkManager.IsLeavingGame() || !IsInSession() )
|
||||
{
|
||||
connection->close();
|
||||
}
|
||||
|
||||
if( connection->isStarted() && !connection->isClosed() )
|
||||
{
|
||||
createdConnections.push_back( connection );
|
||||
|
||||
int primaryPad = ProfileManager.GetPrimaryPad();
|
||||
app.SetRichPresenceContext(primaryPad,CONTEXT_GAME_STATE_BLANK);
|
||||
if (GetPlayerCount() > 1) // Are we offline or online, and how many players are there
|
||||
{
|
||||
if (IsLocalGame()) ProfileManager.SetCurrentGameActivity(primaryPad,CONTEXT_PRESENCE_MULTIPLAYEROFFLINE,false);
|
||||
else ProfileManager.SetCurrentGameActivity(primaryPad,CONTEXT_PRESENCE_MULTIPLAYER,false);
|
||||
connection = new ClientConnection(minecraft, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(IsLocalGame()) ProfileManager.SetCurrentGameActivity(primaryPad,CONTEXT_PRESENCE_MULTIPLAYER_1POFFLINE,false);
|
||||
else ProfileManager.SetCurrentGameActivity(primaryPad,CONTEXT_PRESENCE_MULTIPLAYER_1P,false);
|
||||
}
|
||||
|
||||
|
||||
// ALL OTHER LOCAL PLAYERS
|
||||
for(int idx = 0; idx < XUSER_MAX_COUNT; ++idx)
|
||||
{
|
||||
// Already have setup the primary pad
|
||||
if(idx == ProfileManager.GetPrimaryPad() ) continue;
|
||||
|
||||
if( GetLocalPlayerByUserIndex(idx) != NULL && !ProfileManager.IsSignedIn(idx) )
|
||||
INetworkPlayer *pNetworkPlayer = g_NetworkManager.GetLocalPlayerByUserIndex(ProfileManager.GetLockedProfile());
|
||||
if(pNetworkPlayer == NULL)
|
||||
{
|
||||
INetworkPlayer *pNetworkPlayer = g_NetworkManager.GetLocalPlayerByUserIndex(idx);
|
||||
Socket *socket = pNetworkPlayer->GetSocket();
|
||||
app.DebugPrintf("Closing socket due to player %d not being signed in any more\n");
|
||||
if( !socket->close(false) ) socket->close(true);
|
||||
|
||||
continue;
|
||||
MinecraftServer::HaltServer();
|
||||
app.DebugPrintf("%d\n",ProfileManager.GetLockedProfile());
|
||||
// If the player is NULL here then something went wrong in the session setup, and continuing will end up in a crash
|
||||
return false;
|
||||
}
|
||||
|
||||
// By default when we host we only have the local player, but currently allow multiple local players to join
|
||||
// when joining any other way, so just because they are signed in doesn't mean they are in the session
|
||||
// 4J Stu - If they are in the session, then we should add them to the game. Otherwise we won't be able to add them later
|
||||
INetworkPlayer *pNetworkPlayer = g_NetworkManager.GetLocalPlayerByUserIndex(idx);
|
||||
if( pNetworkPlayer == NULL )
|
||||
continue;
|
||||
|
||||
ClientConnection *connection;
|
||||
|
||||
Socket *socket = pNetworkPlayer->GetSocket();
|
||||
connection = new ClientConnection(minecraft, socket, idx);
|
||||
|
||||
minecraft->addPendingLocalConnection(idx, connection);
|
||||
//minecraft->createExtraLocalPlayer(idx, (convStringToWstring( ProfileManager.GetGamertag(idx) )).c_str(), idx, connection);
|
||||
// Fix for #13259 - CRASH: Gameplay: loading process is halted when player loads saved data
|
||||
if(socket == NULL)
|
||||
{
|
||||
assert(false);
|
||||
MinecraftServer::HaltServer();
|
||||
// If the socket is NULL here then something went wrong in the session setup, and continuing will end up in a crash
|
||||
return false;
|
||||
}
|
||||
|
||||
// Open the socket on the server end to accept incoming data
|
||||
Socket::addIncomingSocket(socket);
|
||||
connection = new ClientConnection(minecraft, socket);
|
||||
}
|
||||
|
||||
connection->send( shared_ptr<PreLoginPacket>( new PreLoginPacket(convStringToWstring( ProfileManager.GetGamertag(idx) )) ) );
|
||||
if( !connection->createdOk )
|
||||
{
|
||||
assert(false);
|
||||
delete connection;
|
||||
connection = NULL;
|
||||
MinecraftServer::HaltServer();
|
||||
return false;
|
||||
}
|
||||
|
||||
connection->send( shared_ptr<PreLoginPacket>( new PreLoginPacket(minecraft->user->name) ) );
|
||||
|
||||
// Tick connection until we're ready to go. The stages involved in this are:
|
||||
// (1) Creating the ClientConnection sends a prelogin packet to the server
|
||||
// (2) the server sends a prelogin back, which is handled by the clientConnection, and returns a login packet
|
||||
// (3) the server sends a login back, which is handled by the client connection to start the game
|
||||
if( !g_NetworkManager.IsHost() )
|
||||
{
|
||||
Minecraft::GetInstance()->progressRenderer->progressStart(IDS_PROGRESS_CONNECTING);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 4J Stu - Host needs to generate a unique multiplayer id for sentient telemetry reporting
|
||||
INT multiplayerInstanceId = TelemetryManager->GenerateMultiplayerInstanceId();
|
||||
TelemetryManager->SetMultiplayerInstanceId(multiplayerInstanceId);
|
||||
}
|
||||
TexturePack *tPack = Minecraft::GetInstance()->skins->getSelected();
|
||||
do
|
||||
{
|
||||
app.DebugPrintf("ticking connection A\n");
|
||||
connection->tick();
|
||||
|
||||
// 4J Stu - We were ticking this way too fast which could cause the connection to time out
|
||||
// The connections should tick at 20 per second
|
||||
Sleep(50);
|
||||
} while ( (IsInSession() && !connection->isStarted() && !connection->isClosed() && !g_NetworkManager.IsLeavingGame()) || tPack->isLoadingData() || (Minecraft::GetInstance()->skins->needsUIUpdate() || ui.IsReloadingSkin()) );
|
||||
ui.CleanUpSkinReload();
|
||||
|
||||
// 4J Stu - Fix for #11279 - CRASH: TCR 001: BAS Game Stability: Signing out of game will cause title to crash
|
||||
// We need to break out of the above loop if m_bLeavingGame is set, and close the connection
|
||||
if( g_NetworkManager.IsLeavingGame() || !IsInSession() )
|
||||
{
|
||||
connection->close();
|
||||
}
|
||||
|
||||
if( connection->isStarted() && !connection->isClosed() )
|
||||
{
|
||||
createdConnections.push_back( connection );
|
||||
|
||||
// Tick connection until we're ready to go. The stages involved in this are:
|
||||
// (1) Creating the ClientConnection sends a prelogin packet to the server
|
||||
// (2) the server sends a prelogin back, which is handled by the clientConnection, and returns a login packet
|
||||
// (3) the server sends a login back, which is handled by the client connection to start the game
|
||||
do
|
||||
int primaryPad = ProfileManager.GetPrimaryPad();
|
||||
app.SetRichPresenceContext(primaryPad,CONTEXT_GAME_STATE_BLANK);
|
||||
if (GetPlayerCount() > 1) // Are we offline or online, and how many players are there
|
||||
{
|
||||
// We need to keep ticking the connections for players that already logged in
|
||||
for(AUTO_VAR(it, createdConnections.begin()); it < createdConnections.end(); ++it)
|
||||
{
|
||||
(*it)->tick();
|
||||
}
|
||||
|
||||
// 4J Stu - We were ticking this way too fast which could cause the connection to time out
|
||||
// The connections should tick at 20 per second
|
||||
Sleep(50);
|
||||
app.DebugPrintf("<***> %d %d %d %d %d\n",IsInSession(), !connection->isStarted(),!connection->isClosed(),ProfileManager.IsSignedIn(idx),!g_NetworkManager.IsLeavingGame());
|
||||
#if defined _XBOX || __PS3__
|
||||
} while (IsInSession() && !connection->isStarted() && !connection->isClosed() && ProfileManager.IsSignedIn(idx) && !g_NetworkManager.IsLeavingGame() );
|
||||
#else
|
||||
// TODO - This SHOULD be something just like the code above but temporarily changing here so that we don't have to depend on the profilemanager behaviour
|
||||
} while (IsInSession() && !connection->isStarted() && !connection->isClosed() && !g_NetworkManager.IsLeavingGame() );
|
||||
#endif
|
||||
|
||||
// 4J Stu - Fix for #11279 - CRASH: TCR 001: BAS Game Stability: Signing out of game will cause title to crash
|
||||
// We need to break out of the above loop if m_bLeavingGame is set, and stop creating new connections
|
||||
// The connections in the createdConnections vector get closed at the end of the thread
|
||||
if( g_NetworkManager.IsLeavingGame() || !IsInSession() ) break;
|
||||
|
||||
if( ProfileManager.IsSignedIn(idx) && !connection->isClosed() )
|
||||
{
|
||||
app.SetRichPresenceContext(idx,CONTEXT_GAME_STATE_BLANK);
|
||||
if (IsLocalGame()) ProfileManager.SetCurrentGameActivity(idx,CONTEXT_PRESENCE_MULTIPLAYEROFFLINE,false);
|
||||
else ProfileManager.SetCurrentGameActivity(idx,CONTEXT_PRESENCE_MULTIPLAYER,false);
|
||||
if (IsLocalGame()) ProfileManager.SetCurrentGameActivity(primaryPad,CONTEXT_PRESENCE_MULTIPLAYEROFFLINE,false);
|
||||
else ProfileManager.SetCurrentGameActivity(primaryPad,CONTEXT_PRESENCE_MULTIPLAYER,false);
|
||||
}
|
||||
else
|
||||
{
|
||||
connection->close();
|
||||
AUTO_VAR(it, find( createdConnections.begin(), createdConnections.end(), connection ));
|
||||
if(it != createdConnections.end() ) createdConnections.erase( it );
|
||||
if(IsLocalGame()) ProfileManager.SetCurrentGameActivity(primaryPad,CONTEXT_PRESENCE_MULTIPLAYER_1POFFLINE,false);
|
||||
else ProfileManager.SetCurrentGameActivity(primaryPad,CONTEXT_PRESENCE_MULTIPLAYER_1P,false);
|
||||
}
|
||||
}
|
||||
|
||||
app.SetGameMode( eMode_Multiplayer );
|
||||
}
|
||||
else if ( connection->isClosed() || !IsInSession())
|
||||
{
|
||||
|
||||
// ALL OTHER LOCAL PLAYERS
|
||||
for(int idx = 0; idx < XUSER_MAX_COUNT; ++idx)
|
||||
{
|
||||
// Already have setup the primary pad
|
||||
if(idx == ProfileManager.GetPrimaryPad() ) continue;
|
||||
|
||||
if( GetLocalPlayerByUserIndex(idx) != NULL && !ProfileManager.IsSignedIn(idx) )
|
||||
{
|
||||
INetworkPlayer *pNetworkPlayer = g_NetworkManager.GetLocalPlayerByUserIndex(idx);
|
||||
Socket *socket = pNetworkPlayer->GetSocket();
|
||||
app.DebugPrintf("Closing socket due to player %d not being signed in any more\n");
|
||||
if( !socket->close(false) ) socket->close(true);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// By default when we host we only have the local player, but currently allow multiple local players to join
|
||||
// when joining any other way, so just because they are signed in doesn't mean they are in the session
|
||||
// 4J Stu - If they are in the session, then we should add them to the game. Otherwise we won't be able to add them later
|
||||
INetworkPlayer *pNetworkPlayer = g_NetworkManager.GetLocalPlayerByUserIndex(idx);
|
||||
if( pNetworkPlayer == NULL )
|
||||
continue;
|
||||
|
||||
ClientConnection *connection;
|
||||
|
||||
Socket *socket = pNetworkPlayer->GetSocket();
|
||||
connection = new ClientConnection(minecraft, socket, idx);
|
||||
|
||||
minecraft->addPendingLocalConnection(idx, connection);
|
||||
//minecraft->createExtraLocalPlayer(idx, (convStringToWstring( ProfileManager.GetGamertag(idx) )).c_str(), idx, connection);
|
||||
|
||||
// Open the socket on the server end to accept incoming data
|
||||
Socket::addIncomingSocket(socket);
|
||||
|
||||
connection->send( shared_ptr<PreLoginPacket>( new PreLoginPacket(convStringToWstring( ProfileManager.GetGamertag(idx) )) ) );
|
||||
|
||||
createdConnections.push_back( connection );
|
||||
|
||||
// Tick connection until we're ready to go. The stages involved in this are:
|
||||
// (1) Creating the ClientConnection sends a prelogin packet to the server
|
||||
// (2) the server sends a prelogin back, which is handled by the clientConnection, and returns a login packet
|
||||
// (3) the server sends a login back, which is handled by the client connection to start the game
|
||||
do
|
||||
{
|
||||
// We need to keep ticking the connections for players that already logged in
|
||||
for(AUTO_VAR(it, createdConnections.begin()); it < createdConnections.end(); ++it)
|
||||
{
|
||||
(*it)->tick();
|
||||
}
|
||||
|
||||
// 4J Stu - We were ticking this way too fast which could cause the connection to time out
|
||||
// The connections should tick at 20 per second
|
||||
Sleep(50);
|
||||
app.DebugPrintf("<***> %d %d %d %d %d\n",IsInSession(), !connection->isStarted(),!connection->isClosed(),ProfileManager.IsSignedIn(idx),!g_NetworkManager.IsLeavingGame());
|
||||
#if defined _XBOX || __PS3__
|
||||
} while (IsInSession() && !connection->isStarted() && !connection->isClosed() && ProfileManager.IsSignedIn(idx) && !g_NetworkManager.IsLeavingGame() );
|
||||
#else
|
||||
// TODO - This SHOULD be something just like the code above but temporarily changing here so that we don't have to depend on the profilemanager behaviour
|
||||
} while (IsInSession() && !connection->isStarted() && !connection->isClosed() && !g_NetworkManager.IsLeavingGame() );
|
||||
#endif
|
||||
|
||||
// 4J Stu - Fix for #11279 - CRASH: TCR 001: BAS Game Stability: Signing out of game will cause title to crash
|
||||
// We need to break out of the above loop if m_bLeavingGame is set, and stop creating new connections
|
||||
// The connections in the createdConnections vector get closed at the end of the thread
|
||||
if( g_NetworkManager.IsLeavingGame() || !IsInSession() ) break;
|
||||
|
||||
if( ProfileManager.IsSignedIn(idx) && !connection->isClosed() )
|
||||
{
|
||||
app.SetRichPresenceContext(idx,CONTEXT_GAME_STATE_BLANK);
|
||||
if (IsLocalGame()) ProfileManager.SetCurrentGameActivity(idx,CONTEXT_PRESENCE_MULTIPLAYEROFFLINE,false);
|
||||
else ProfileManager.SetCurrentGameActivity(idx,CONTEXT_PRESENCE_MULTIPLAYER,false);
|
||||
}
|
||||
else
|
||||
{
|
||||
connection->close();
|
||||
AUTO_VAR(it, find( createdConnections.begin(), createdConnections.end(), connection ));
|
||||
if(it != createdConnections.end() ) createdConnections.erase( it );
|
||||
}
|
||||
}
|
||||
|
||||
app.SetGameMode( eMode_Multiplayer );
|
||||
}
|
||||
else if ( connection->isClosed() || !IsInSession())
|
||||
{
|
||||
// assert(false);
|
||||
MinecraftServer::HaltServer();
|
||||
return false;
|
||||
MinecraftServer::HaltServer();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
app.DebugPrintf("Win64 dedicated: skipping primary local player connection\n");
|
||||
app.SetGameMode( eMode_Multiplayer );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,15 @@
|
|||
#include "..\..\Windows64\Network\WinsockNetLayer.h"
|
||||
#include "..\..\Minecraft.h"
|
||||
#include "..\..\User.h"
|
||||
extern bool g_Win64DedicatedServerMode;
|
||||
|
||||
namespace
|
||||
{
|
||||
static unsigned long long GetNowMs64()
|
||||
{
|
||||
return (unsigned long long)GetTickCount64();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
CPlatformNetworkManagerStub *g_pPlatformNetworkManager;
|
||||
|
|
@ -14,6 +23,12 @@ CPlatformNetworkManagerStub *g_pPlatformNetworkManager;
|
|||
|
||||
void CPlatformNetworkManagerStub::NotifyPlayerJoined(IQNetPlayer *pQNetPlayer )
|
||||
{
|
||||
if (pQNetPlayer == NULL)
|
||||
{
|
||||
app.DebugPrintf("NotifyPlayerJoined called with NULL player\n");
|
||||
return;
|
||||
}
|
||||
|
||||
const char * pszDescription;
|
||||
|
||||
// 4J Stu - We create a fake socket for every where that we need an INBOUND queue of game data. Outbound
|
||||
|
|
@ -94,7 +109,7 @@ void CPlatformNetworkManagerStub::NotifyPlayerJoined(IQNetPlayer *pQNetPlayer )
|
|||
if( m_pIQNet->IsHost() )
|
||||
{
|
||||
// 4J-PB - only the host should do this
|
||||
// g_NetworkManager.UpdateAndSetGameSessionData();
|
||||
g_NetworkManager.UpdateAndSetGameSessionData();
|
||||
SystemFlagAddPlayer( networkPlayer );
|
||||
}
|
||||
|
||||
|
|
@ -121,6 +136,12 @@ void CPlatformNetworkManagerStub::NotifyPlayerJoined(IQNetPlayer *pQNetPlayer )
|
|||
|
||||
void CPlatformNetworkManagerStub::NotifyPlayerLeaving(IQNetPlayer *pQNetPlayer)
|
||||
{
|
||||
if (pQNetPlayer == NULL)
|
||||
{
|
||||
app.DebugPrintf("NotifyPlayerLeaving called with NULL player\n");
|
||||
return;
|
||||
}
|
||||
|
||||
app.DebugPrintf("Player 0x%p \"%ls\" leaving.\n", pQNetPlayer, pQNetPlayer->GetGamertag());
|
||||
|
||||
INetworkPlayer *networkPlayer = getNetworkPlayer(pQNetPlayer);
|
||||
|
|
@ -148,6 +169,12 @@ void CPlatformNetworkManagerStub::NotifyPlayerLeaving(IQNetPlayer *pQNetPlayer)
|
|||
}
|
||||
|
||||
removeNetworkPlayer(pQNetPlayer);
|
||||
|
||||
if (m_pIQNet->IsHost())
|
||||
{
|
||||
// Exclude the leaving player from advertised count immediately.
|
||||
g_NetworkManager.UpdateAndSetGameSessionData(networkPlayer);
|
||||
}
|
||||
}
|
||||
|
||||
bool CPlatformNetworkManagerStub::Initialise(CGameNetworkManager *pGameNetworkManager, int flagIndexSize)
|
||||
|
|
@ -164,6 +191,13 @@ bool CPlatformNetworkManagerStub::Initialise(CGameNetworkManager *pGameNetworkMa
|
|||
m_bLeavingGame = false;
|
||||
m_bLeaveGameOnTick = false;
|
||||
m_bHostChanged = false;
|
||||
#ifdef _WINDOWS64
|
||||
m_bTransferPending = false;
|
||||
m_bTransferLeaving = false;
|
||||
m_transferHostIp[0] = 0;
|
||||
m_transferHostPort = 0;
|
||||
m_transferSuppressErrorsUntilMs = 0;
|
||||
#endif
|
||||
|
||||
m_bSearchResultsReady = false;
|
||||
m_bSearchPending = false;
|
||||
|
|
@ -213,6 +247,46 @@ void CPlatformNetworkManagerStub::DoWork()
|
|||
{
|
||||
#ifdef _WINDOWS64
|
||||
extern QNET_STATE _iQNetStubState;
|
||||
if (m_bTransferPending)
|
||||
{
|
||||
if (g_NetworkManager.IsInSession())
|
||||
{
|
||||
if (!m_bTransferLeaving)
|
||||
{
|
||||
m_bTransferLeaving = true;
|
||||
app.DebugPrintf("Win64 LAN: Transfer requested to %s:%d, leaving current session\n",
|
||||
m_transferHostIp, m_transferHostPort);
|
||||
g_NetworkManager.LeaveGame(false);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
FriendSessionInfo targetSession;
|
||||
memset(&targetSession, 0, sizeof(targetSession));
|
||||
strncpy_s(targetSession.data.hostIP, sizeof(targetSession.data.hostIP), m_transferHostIp, _TRUNCATE);
|
||||
targetSession.data.hostPort = m_transferHostPort;
|
||||
wcsncpy_s(targetSession.data.hostName, XUSER_NAME_SIZE, L"Server Transfer", _TRUNCATE);
|
||||
targetSession.data.netVersion = MINECRAFT_NET_VERSION;
|
||||
targetSession.data.isJoinable = true;
|
||||
targetSession.data.isReadyToJoin = true;
|
||||
|
||||
int primaryPad = ProfileManager.GetPrimaryPad();
|
||||
if (primaryPad < 0)
|
||||
{
|
||||
primaryPad = 0;
|
||||
}
|
||||
const int localUsersMask = GetLocalPlayerMask(primaryPad);
|
||||
const int joinResult = JoinGame(&targetSession, localUsersMask, ProfileManager.GetLockedProfile());
|
||||
app.DebugPrintf("Win64 LAN: Transfer join result=%d for %s:%d\n",
|
||||
joinResult, m_transferHostIp, m_transferHostPort);
|
||||
|
||||
m_bTransferPending = false;
|
||||
m_bTransferLeaving = false;
|
||||
m_transferHostIp[0] = 0;
|
||||
m_transferHostPort = 0;
|
||||
m_transferSuppressErrorsUntilMs = GetNowMs64() + 10000ULL;
|
||||
}
|
||||
|
||||
if (_iQNetStubState == QNET_STATE_SESSION_STARTING && app.GetGameStarted())
|
||||
{
|
||||
_iQNetStubState = QNET_STATE_GAME_PLAY;
|
||||
|
|
@ -236,8 +310,21 @@ void CPlatformNetworkManagerStub::DoWork()
|
|||
qnetPlayer->m_gamertag[0] = 0;
|
||||
qnetPlayer->SetCustomDataValue(0);
|
||||
WinsockNetLayer::PushFreeSmallId(disconnectedSmallId);
|
||||
if (IQNet::s_playerCount > 1)
|
||||
IQNet::s_playerCount--;
|
||||
|
||||
// Recompute active slot span instead of blindly decrementing.
|
||||
// A lower smallId can disconnect while higher smallIds are still active.
|
||||
DWORD highestActive = 1;
|
||||
for (DWORD idx = 1; idx < MINECRAFT_NET_MAX_PLAYERS; ++idx)
|
||||
{
|
||||
if (IQNet::m_player[idx].GetCustomDataValue() != 0)
|
||||
{
|
||||
highestActive = idx + 1;
|
||||
}
|
||||
}
|
||||
IQNet::s_playerCount = highestActive;
|
||||
app.DebugPrintf("Win64 LAN: Recomputed active player slot span to %u after disconnect smallId=%u\n",
|
||||
(unsigned int)IQNet::s_playerCount,
|
||||
(unsigned int)disconnectedSmallId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -321,6 +408,14 @@ bool CPlatformNetworkManagerStub::LeaveGame(bool bMigrateHost)
|
|||
m_machineQNetPrimaryPlayers.clear();
|
||||
SystemFlagReset();
|
||||
|
||||
#ifdef _WINDOWS64
|
||||
// Clear all back-pointers from IQNet slots to deleted network players.
|
||||
for (int idx = 0; idx < MINECRAFT_NET_MAX_PLAYERS; ++idx)
|
||||
{
|
||||
IQNet::m_player[idx].SetCustomDataValue(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _WINDOWS64
|
||||
WinsockNetLayer::Shutdown();
|
||||
WinsockNetLayer::Initialize();
|
||||
|
|
@ -356,13 +451,26 @@ void CPlatformNetworkManagerStub::HostGame(int localUsersMask, bool bOnlineGame,
|
|||
_HostGame( localUsersMask, publicSlots, privateSlots );
|
||||
|
||||
#ifdef _WINDOWS64
|
||||
int port = WIN64_NET_DEFAULT_PORT;
|
||||
unsigned char advertiseMaxPlayers = publicSlots;
|
||||
if (advertiseMaxPlayers == 0 || advertiseMaxPlayers > MINECRAFT_NET_MAX_PLAYERS)
|
||||
{
|
||||
advertiseMaxPlayers = MINECRAFT_NET_MAX_PLAYERS;
|
||||
}
|
||||
|
||||
g_Win64MultiplayerMaxPlayers = (int)advertiseMaxPlayers;
|
||||
|
||||
int port = g_Win64MultiplayerPort;
|
||||
if (port <= 0)
|
||||
{
|
||||
port = WIN64_NET_DEFAULT_PORT;
|
||||
}
|
||||
if (!WinsockNetLayer::IsActive())
|
||||
WinsockNetLayer::HostGame(port);
|
||||
|
||||
const wchar_t *hostName = IQNet::m_player[0].m_gamertag;
|
||||
unsigned int settings = app.GetGameHostOption(eGameHostOption_All);
|
||||
WinsockNetLayer::StartAdvertising(port, hostName, settings, 0, 0, MINECRAFT_NET_VERSION);
|
||||
WinsockNetLayer::StartAdvertising(port, hostName, settings, 0, 0, MINECRAFT_NET_VERSION, advertiseMaxPlayers);
|
||||
UpdateAndSetGameSessionData();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -401,6 +509,9 @@ int CPlatformNetworkManagerStub::JoinGame(FriendSessionInfo *searchResult, int l
|
|||
if (!WinsockNetLayer::JoinGame(hostIP, hostPort))
|
||||
{
|
||||
app.DebugPrintf("Win64 LAN: Failed to connect to %s:%d\n", hostIP, hostPort);
|
||||
// Reset transient join state so a failed attempt does not poison subsequent joins.
|
||||
m_pIQNet->EndGame();
|
||||
WinsockNetLayer::StartDiscovery();
|
||||
return CGameNetworkManager::JOINGAME_FAIL_GENERAL;
|
||||
}
|
||||
|
||||
|
|
@ -481,44 +592,40 @@ bool CPlatformNetworkManagerStub::_RunNetworkGame()
|
|||
|
||||
void CPlatformNetworkManagerStub::UpdateAndSetGameSessionData(INetworkPlayer *pNetworkPlayerLeaving /*= NULL*/)
|
||||
{
|
||||
// DWORD playerCount = m_pIQNet->GetPlayerCount();
|
||||
//
|
||||
// if( this->m_bLeavingGame )
|
||||
// return;
|
||||
//
|
||||
// if( GetHostPlayer() == NULL )
|
||||
// return;
|
||||
//
|
||||
// for(unsigned int i = 0; i < MINECRAFT_NET_MAX_PLAYERS; ++i)
|
||||
// {
|
||||
// if( i < playerCount )
|
||||
// {
|
||||
// INetworkPlayer *pNetworkPlayer = GetPlayerByIndex(i);
|
||||
//
|
||||
// // We can call this from NotifyPlayerLeaving but at that point the player is still considered in the session
|
||||
// if( pNetworkPlayer != pNetworkPlayerLeaving )
|
||||
// {
|
||||
// m_hostGameSessionData.players[i] = ((NetworkPlayerXbox *)pNetworkPlayer)->GetUID();
|
||||
//
|
||||
// char *temp;
|
||||
// temp = (char *)wstringtofilename( pNetworkPlayer->GetOnlineName() );
|
||||
// memcpy(m_hostGameSessionData.szPlayers[i],temp,XUSER_NAME_SIZE);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// m_hostGameSessionData.players[i] = NULL;
|
||||
// memset(m_hostGameSessionData.szPlayers[i],0,XUSER_NAME_SIZE);
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// m_hostGameSessionData.players[i] = NULL;
|
||||
// memset(m_hostGameSessionData.szPlayers[i],0,XUSER_NAME_SIZE);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// m_hostGameSessionData.hostPlayerUID = ((NetworkPlayerXbox *)GetHostPlayer())->GetQNetPlayer()->GetXuid();
|
||||
// m_hostGameSessionData.m_uiGameHostSettings = app.GetGameHostOption(eGameHostOption_All);
|
||||
#ifdef _WINDOWS64
|
||||
if (this->m_bLeavingGame || !m_pIQNet->IsHost() || !WinsockNetLayer::IsHosting())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
BYTE advertisedCount = (BYTE)m_pIQNet->GetPlayerCount();
|
||||
if (g_Win64DedicatedServerMode && advertisedCount > 0)
|
||||
{
|
||||
// Dedicated host keeps slot 0 active internally for network scheduling,
|
||||
// but should not be shown as an in-game player in server browser counts.
|
||||
--advertisedCount;
|
||||
}
|
||||
if (pNetworkPlayerLeaving != NULL && advertisedCount > 0)
|
||||
{
|
||||
--advertisedCount;
|
||||
}
|
||||
if (advertisedCount == 0 && !g_Win64DedicatedServerMode)
|
||||
{
|
||||
advertisedCount = 1;
|
||||
}
|
||||
|
||||
extern QNET_STATE _iQNetStubState;
|
||||
const BYTE maxPlayers = WinsockNetLayer::GetMaxPlayers();
|
||||
const bool joinable = (_iQNetStubState == QNET_STATE_GAME_PLAY) && (advertisedCount < maxPlayers);
|
||||
const unsigned int advertisedSettings = app.GetGameHostOption(eGameHostOption_All);
|
||||
|
||||
WinsockNetLayer::UpdateAdvertiseGameSettings(advertisedSettings);
|
||||
WinsockNetLayer::UpdateAdvertisePlayerCount(advertisedCount);
|
||||
WinsockNetLayer::UpdateAdvertiseJoinable(joinable);
|
||||
|
||||
app.DebugPrintf("Win64 LAN: Updated advertised session data (players=%d, joinable=%d, settings=0x%08X)\n",
|
||||
(int)advertisedCount, joinable ? 1 : 0, advertisedSettings);
|
||||
#endif
|
||||
}
|
||||
|
||||
int CPlatformNetworkManagerStub::RemovePlayerOnSocketClosedThreadProc( void* lpParam )
|
||||
|
|
@ -806,12 +913,102 @@ INetworkPlayer *CPlatformNetworkManagerStub::GetPlayerByIndex(int playerIndex)
|
|||
|
||||
INetworkPlayer * CPlatformNetworkManagerStub::GetPlayerByXuid(PlayerUID xuid)
|
||||
{
|
||||
return getNetworkPlayer( m_pIQNet->GetPlayerByXuid(xuid)) ;
|
||||
IQNetPlayer *qnetPlayer = m_pIQNet->GetPlayerByXuid(xuid);
|
||||
|
||||
#ifdef _WINDOWS64
|
||||
if (qnetPlayer == NULL)
|
||||
{
|
||||
const unsigned __int64 kWin64StubXuidBase = 0xe000d45248242f2eULL;
|
||||
const unsigned __int64 uxuid = (unsigned __int64)xuid;
|
||||
if (uxuid >= kWin64StubXuidBase)
|
||||
{
|
||||
const unsigned __int64 delta = uxuid - kWin64StubXuidBase;
|
||||
if (delta < (unsigned __int64)MINECRAFT_NET_MAX_PLAYERS)
|
||||
{
|
||||
const BYTE smallId = (BYTE)delta;
|
||||
// Clients can legitimately resolve remote players by XUID before the
|
||||
// platform join callback has materialized the slot's NetworkPlayer.
|
||||
// Hosts keep the stricter check to avoid creating phantom entries.
|
||||
const bool slotActive = (!m_pIQNet->IsHost()) ||
|
||||
(smallId == 0) ||
|
||||
(IQNet::m_player[smallId].GetCustomDataValue() != 0);
|
||||
if (slotActive)
|
||||
{
|
||||
qnetPlayer = &IQNet::m_player[smallId];
|
||||
qnetPlayer->m_smallId = smallId;
|
||||
if (smallId == 0)
|
||||
{
|
||||
qnetPlayer->m_isHostPlayer = true;
|
||||
qnetPlayer->m_isRemote = !m_pIQNet->IsHost();
|
||||
}
|
||||
else
|
||||
{
|
||||
const BYTE localSmallId = WinsockNetLayer::GetLocalSmallId();
|
||||
const bool isLocalSlot = (!m_pIQNet->IsHost() && (smallId == localSmallId));
|
||||
qnetPlayer->m_isHostPlayer = false;
|
||||
qnetPlayer->m_isRemote = !isLocalSlot;
|
||||
}
|
||||
if (smallId >= IQNet::s_playerCount)
|
||||
{
|
||||
IQNet::s_playerCount = smallId + 1;
|
||||
}
|
||||
app.DebugPrintf("Win64 LAN: Materialized player slot from XUID (smallId=%u, isRemote=%d)\n",
|
||||
(unsigned int)smallId,
|
||||
qnetPlayer->m_isRemote ? 1 : 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (qnetPlayer == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
INetworkPlayer *networkPlayer = getNetworkPlayer(qnetPlayer);
|
||||
#ifdef _WINDOWS64
|
||||
if (networkPlayer == NULL)
|
||||
{
|
||||
NotifyPlayerJoined(qnetPlayer);
|
||||
networkPlayer = getNetworkPlayer(qnetPlayer);
|
||||
app.DebugPrintf("Win64 LAN: Lazily created network player from XUID (smallId=%u)\n",
|
||||
(unsigned int)qnetPlayer->GetSmallId());
|
||||
}
|
||||
#endif
|
||||
return networkPlayer;
|
||||
}
|
||||
|
||||
INetworkPlayer * CPlatformNetworkManagerStub::GetPlayerBySmallId(unsigned char smallId)
|
||||
{
|
||||
return getNetworkPlayer(m_pIQNet->GetPlayerBySmallId(smallId));
|
||||
IQNetPlayer *qnetPlayer = m_pIQNet->GetPlayerBySmallId(smallId);
|
||||
if (qnetPlayer == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
INetworkPlayer *networkPlayer = getNetworkPlayer(qnetPlayer);
|
||||
#ifdef _WINDOWS64
|
||||
if (networkPlayer == NULL && smallId != 0 && !m_pIQNet->IsHost())
|
||||
{
|
||||
const BYTE localSmallId = WinsockNetLayer::GetLocalSmallId();
|
||||
const bool isLocalSlot = (smallId == localSmallId);
|
||||
qnetPlayer->m_smallId = smallId;
|
||||
qnetPlayer->m_isHostPlayer = false;
|
||||
qnetPlayer->m_isRemote = !isLocalSlot;
|
||||
if (smallId >= IQNet::s_playerCount)
|
||||
{
|
||||
IQNet::s_playerCount = smallId + 1;
|
||||
}
|
||||
|
||||
// On Win64 clients we may receive player/entity packets for remote users before a
|
||||
// platform-layer "player joined" callback has been issued for that slot.
|
||||
NotifyPlayerJoined(qnetPlayer);
|
||||
networkPlayer = getNetworkPlayer(qnetPlayer);
|
||||
app.DebugPrintf("Win64 LAN: Lazily created network player for smallId=%u\n", (unsigned int)smallId);
|
||||
}
|
||||
#endif
|
||||
return networkPlayer;
|
||||
}
|
||||
|
||||
INetworkPlayer *CPlatformNetworkManagerStub::GetHostPlayer()
|
||||
|
|
@ -857,3 +1054,39 @@ bool CPlatformNetworkManagerStub::IsReadyToPlayOrIdle()
|
|||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef _WINDOWS64
|
||||
void CPlatformNetworkManagerStub::QueueServerTransfer(const char *hostIp, int hostPort)
|
||||
{
|
||||
if (hostIp == NULL || hostIp[0] == 0 || hostPort <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
strncpy_s(m_transferHostIp, sizeof(m_transferHostIp), hostIp, _TRUNCATE);
|
||||
m_transferHostPort = hostPort;
|
||||
m_bTransferPending = true;
|
||||
m_bTransferLeaving = false;
|
||||
m_transferSuppressErrorsUntilMs = GetNowMs64() + 10000ULL;
|
||||
|
||||
app.DebugPrintf("Win64 LAN: Queued server transfer target %s:%d\n", m_transferHostIp, m_transferHostPort);
|
||||
}
|
||||
|
||||
void CPlatformNetworkManagerStub::RequestServerTransfer(const char *hostIp, int hostPort)
|
||||
{
|
||||
if (g_pPlatformNetworkManager == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
g_pPlatformNetworkManager->QueueServerTransfer(hostIp, hostPort);
|
||||
}
|
||||
|
||||
bool CPlatformNetworkManagerStub::IsServerTransferInProgress()
|
||||
{
|
||||
return (g_pPlatformNetworkManager != NULL) &&
|
||||
(g_pPlatformNetworkManager->m_bTransferPending ||
|
||||
g_pPlatformNetworkManager->m_bTransferLeaving ||
|
||||
(GetNowMs64() < g_pPlatformNetworkManager->m_transferSuppressErrorsUntilMs));
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -48,6 +48,10 @@ public:
|
|||
virtual bool IsPrivateGame() { return m_bIsPrivateGame; }
|
||||
virtual bool IsLeavingGame() { return m_bLeavingGame; }
|
||||
virtual void ResetLeavingGame() { m_bLeavingGame = false; }
|
||||
#ifdef _WINDOWS64
|
||||
static void RequestServerTransfer(const char *hostIp, int hostPort);
|
||||
static bool IsServerTransferInProgress();
|
||||
#endif
|
||||
|
||||
virtual void RegisterPlayerChangedCallback(int iPad, void (*callback)(void *callbackParam, INetworkPlayer *pPlayer, bool leaving), void *callbackParam);
|
||||
virtual void UnRegisterPlayerChangedCallback(int iPad, void (*callback)(void *callbackParam, INetworkPlayer *pPlayer, bool leaving), void *callbackParam);
|
||||
|
|
@ -61,6 +65,9 @@ private:
|
|||
virtual bool _LeaveGame(bool bMigrateHost, bool bLeaveRoom);
|
||||
virtual void _HostGame(int dwUsersMask, unsigned char publicSlots = MINECRAFT_NET_MAX_PLAYERS, unsigned char privateSlots = 0);
|
||||
virtual bool _StartGame();
|
||||
#ifdef _WINDOWS64
|
||||
void QueueServerTransfer(const char *hostIp, int hostPort);
|
||||
#endif
|
||||
|
||||
IQNet * m_pIQNet; // pointer to QNet interface
|
||||
|
||||
|
|
@ -72,6 +79,13 @@ private:
|
|||
bool m_bLeaveGameOnTick;
|
||||
bool m_migrateHostOnLeave;
|
||||
bool m_bHostChanged;
|
||||
#ifdef _WINDOWS64
|
||||
bool m_bTransferPending;
|
||||
bool m_bTransferLeaving;
|
||||
char m_transferHostIp[64];
|
||||
int m_transferHostPort;
|
||||
unsigned long long m_transferSuppressErrorsUntilMs;
|
||||
#endif
|
||||
|
||||
bool m_bIsOfflineGame;
|
||||
bool m_bIsPrivateGame;
|
||||
|
|
@ -166,6 +180,17 @@ public:
|
|||
void NotifyPlayerLeaving( IQNetPlayer *pQNetPlayer );
|
||||
|
||||
#ifndef _XBOX
|
||||
void FakeLocalPlayerJoined() { NotifyPlayerJoined(m_pIQNet->GetLocalPlayerByUserIndex(0)); }
|
||||
void FakeLocalPlayerJoined()
|
||||
{
|
||||
IQNetPlayer *player = m_pIQNet->GetLocalPlayerByUserIndex(0);
|
||||
if (player == NULL)
|
||||
{
|
||||
// Dedicated/headless host can suppress slot 0 from "active local player"
|
||||
// queries. Fall back to the canonical host slot so platform bookkeeping
|
||||
// can still be initialized.
|
||||
player = &IQNet::m_player[0];
|
||||
}
|
||||
NotifyPlayerJoined(player);
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
|
|
|||
|
|
@ -15,9 +15,6 @@
|
|||
|
||||
#ifdef _WINDOWS64
|
||||
#include "..\..\KeyboardMouseInput.h"
|
||||
#include "UI.h"
|
||||
|
||||
SavedInventoryCursorPos g_savedInventoryCursorPos = { 0.0f, 0.0f, false };
|
||||
#endif
|
||||
|
||||
IUIScene_AbstractContainerMenu::IUIScene_AbstractContainerMenu()
|
||||
|
|
@ -473,26 +470,20 @@ void IUIScene_AbstractContainerMenu::onMouseTick()
|
|||
#ifdef _WINDOWS64
|
||||
if (!g_KBMInput.IsMouseGrabbed())
|
||||
{
|
||||
int deltaX = g_KBMInput.GetMouseDeltaX();
|
||||
int deltaY = g_KBMInput.GetMouseDeltaY();
|
||||
|
||||
extern HWND g_hWnd;
|
||||
RECT rc;
|
||||
GetClientRect(g_hWnd, &rc);
|
||||
int winW = rc.right - rc.left;
|
||||
int winH = rc.bottom - rc.top;
|
||||
|
||||
if (winW > 0 && winH > 0)
|
||||
int dx = g_KBMInput.GetMouseDeltaX();
|
||||
int dy = g_KBMInput.GetMouseDeltaY();
|
||||
if (dx != 0 || dy != 0)
|
||||
{
|
||||
float scaleX = (float)getMovieWidth() / (float)winW;
|
||||
float scaleY = (float)getMovieHeight() / (float)winH;
|
||||
float sensitivity = (float)app.GetGameSettings(iPad, eGameSetting_Sensitivity_InMenu) / 100.0f;
|
||||
float mouseScale = sensitivity * 1.0f;
|
||||
vPointerPos.x += (float)dx * mouseScale;
|
||||
vPointerPos.y += (float)dy * mouseScale;
|
||||
|
||||
if (vPointerPos.x < m_fPointerMinX) vPointerPos.x = m_fPointerMinX;
|
||||
else if (vPointerPos.x > m_fPointerMaxX) vPointerPos.x = m_fPointerMaxX;
|
||||
if (vPointerPos.y < m_fPointerMinY) vPointerPos.y = m_fPointerMinY;
|
||||
else if (vPointerPos.y > m_fPointerMaxY) vPointerPos.y = m_fPointerMaxY;
|
||||
|
||||
vPointerPos.x += (float)deltaX * scaleX;
|
||||
vPointerPos.y += (float)deltaY * scaleY;
|
||||
}
|
||||
|
||||
if (deltaX != 0 || deltaY != 0)
|
||||
{
|
||||
bStickInput = true;
|
||||
}
|
||||
}
|
||||
|
|
@ -715,11 +706,7 @@ void IUIScene_AbstractContainerMenu::onMouseTick()
|
|||
|
||||
// If there is no stick input, and we are over a slot, then snap pointer to slot centre.
|
||||
// 4J - TomK - only if this particular component allows so!
|
||||
#ifdef _WINDOWS64
|
||||
if(g_KBMInput.IsMouseGrabbed() && CanHaveFocus(eSectionUnderPointer))
|
||||
#else
|
||||
if(CanHaveFocus(eSectionUnderPointer))
|
||||
#endif
|
||||
{
|
||||
vPointerPos.x = vSnapPos.x;
|
||||
vPointerPos.y = vSnapPos.y;
|
||||
|
|
@ -727,8 +714,7 @@ void IUIScene_AbstractContainerMenu::onMouseTick()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// Clamp to pointer extents
|
||||
// Clamp to pointer extents.
|
||||
if ( vPointerPos.x < m_fPointerMinX ) vPointerPos.x = m_fPointerMinX;
|
||||
else if ( vPointerPos.x > m_fPointerMaxX ) vPointerPos.x = m_fPointerMaxX;
|
||||
if ( vPointerPos.y < m_fPointerMinY ) vPointerPos.y = m_fPointerMinY;
|
||||
|
|
@ -1250,15 +1236,8 @@ void IUIScene_AbstractContainerMenu::onMouseTick()
|
|||
|
||||
|
||||
// Offset back to image top left.
|
||||
#ifdef _WINDOWS64
|
||||
if (g_KBMInput.IsMouseGrabbed())
|
||||
{
|
||||
#endif
|
||||
vPointerPos.x -= m_fPointerImageOffsetX;
|
||||
vPointerPos.y -= m_fPointerImageOffsetY;
|
||||
#ifdef _WINDOWS64
|
||||
}
|
||||
#endif
|
||||
vPointerPos.x -= m_fPointerImageOffsetX;
|
||||
vPointerPos.y -= m_fPointerImageOffsetY;
|
||||
|
||||
// Update pointer position.
|
||||
// 4J-PB - do not allow sub pixel positions or we get broken lines in box edges
|
||||
|
|
|
|||
|
|
@ -1,15 +1,5 @@
|
|||
#pragma once
|
||||
|
||||
#ifdef _WINDOWS64
|
||||
struct SavedInventoryCursorPos
|
||||
{
|
||||
float x;
|
||||
float y;
|
||||
bool hasSavedPos;
|
||||
};
|
||||
extern SavedInventoryCursorPos g_savedInventoryCursorPos;
|
||||
#endif
|
||||
|
||||
// Uncomment to enable tap input detection to jump 1 slot. Doesn't work particularly well yet, and I feel the system does not need it.
|
||||
// Would probably be required if we decide to slow down the pointer movement.
|
||||
// 4J Stu - There was a request to be able to navigate the scenes with the dpad, so I have used much of the TAP_DETECTION
|
||||
|
|
@ -230,6 +220,4 @@ protected:
|
|||
|
||||
public:
|
||||
virtual int getPad() = 0;
|
||||
virtual int getMovieWidth() = 0;
|
||||
virtual int getMovieHeight() = 0;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -10,6 +10,9 @@
|
|||
#include "..\..\TexturePack.h"
|
||||
#include "..\..\DLCTexturePack.h"
|
||||
#include "..\..\..\Minecraft.World\StringHelpers.h"
|
||||
#ifdef _WINDOWS64
|
||||
#include "..\Network\PlatformNetworkManagerStub.h"
|
||||
#endif
|
||||
|
||||
|
||||
int IUIScene_PauseMenu::ExitGameDialogReturned(void *pParam,int iPad,C4JStorage::EMessageResult result)
|
||||
|
|
@ -393,6 +396,14 @@ int IUIScene_PauseMenu::ExitWorldThreadProc( void* lpParameter )
|
|||
// This function performs the meat of exiting from a level. It should be called from a thread other than the main thread.
|
||||
void IUIScene_PauseMenu::_ExitWorld(LPVOID lpParameter)
|
||||
{
|
||||
#ifdef _WINDOWS64
|
||||
if (CPlatformNetworkManagerStub::IsServerTransferInProgress())
|
||||
{
|
||||
app.DebugPrintf("Win64 LAN: Skipping _ExitWorld teardown during server transfer\n");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
Minecraft *pMinecraft=Minecraft::GetInstance();
|
||||
|
||||
int exitReasonStringId = pMinecraft->progressRenderer->getCurrentTitle();
|
||||
|
|
@ -688,4 +699,4 @@ int IUIScene_PauseMenu::DisableAutosaveDialogReturned(void *pParam,int iPad,C4JS
|
|||
app.SetAction(iPad,eAppAction_SaveGame);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -95,9 +95,14 @@ UIBitmapFont::UIBitmapFont( SFontData &sfontdata )
|
|||
: UIAbstractBitmapFont( sfontdata.m_strFontName )
|
||||
{
|
||||
m_numGlyphs = sfontdata.m_uiGlyphCount;
|
||||
m_cFontData = NULL;
|
||||
|
||||
BufferedImage bimg(sfontdata.m_wstrFilename);
|
||||
int *bimgData = bimg.getData();
|
||||
if (bimgData == NULL)
|
||||
{
|
||||
app.DebugPrintf("UIBitmapFont: missing texture data for '%s'\n", sfontdata.m_strFontName.c_str());
|
||||
}
|
||||
|
||||
m_cFontData = new CFontData(sfontdata, bimgData);
|
||||
|
||||
|
|
@ -106,12 +111,27 @@ UIBitmapFont::UIBitmapFont( SFontData &sfontdata )
|
|||
|
||||
UIBitmapFont::~UIBitmapFont()
|
||||
{
|
||||
m_cFontData->release();
|
||||
if (m_cFontData)
|
||||
{
|
||||
m_cFontData->release();
|
||||
delete m_cFontData;
|
||||
m_cFontData = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//Callback function type for returning vertical font metrics
|
||||
IggyFontMetrics *UIBitmapFont::GetFontMetrics(IggyFontMetrics *metrics)
|
||||
{
|
||||
if (metrics == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
if (m_cFontData == NULL || m_cFontData->getFontData() == NULL)
|
||||
{
|
||||
memset(metrics, 0, sizeof(*metrics));
|
||||
return metrics;
|
||||
}
|
||||
|
||||
//Description
|
||||
// Vertical metrics for a font
|
||||
//Members
|
||||
|
|
@ -138,6 +158,11 @@ IggyFontMetrics *UIBitmapFont::GetFontMetrics(IggyFontMetrics *metrics)
|
|||
//Callback function type for mapping 32-bit unicode code point to internal font glyph number; use IGGY_GLYPH_INVALID to mean "invalid character"
|
||||
S32 UIBitmapFont::GetCodepointGlyph(U32 codepoint)
|
||||
{
|
||||
if (m_cFontData == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 4J-JEV: Change "right single quotation marks" to apostrophies.
|
||||
if (codepoint == 0x2019) codepoint = 0x27;
|
||||
|
||||
|
|
@ -147,6 +172,16 @@ S32 UIBitmapFont::GetCodepointGlyph(U32 codepoint)
|
|||
//Callback function type for returning horizontal metrics for each glyph
|
||||
IggyGlyphMetrics * UIBitmapFont::GetGlyphMetrics(S32 glyph,IggyGlyphMetrics *metrics)
|
||||
{
|
||||
if (metrics == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
if (m_cFontData == NULL || m_cFontData->getFontData() == NULL)
|
||||
{
|
||||
memset(metrics, 0, sizeof(*metrics));
|
||||
return metrics;
|
||||
}
|
||||
|
||||
// 4J-JEV: Information about 'Glyph Metrics'.
|
||||
// http://freetype.sourceforge.net/freetype2/docs/glyphs/glyphs-3.html - Overview.
|
||||
// http://en.wikipedia.org/wiki/Kerning#Kerning_values - 'Font Units'
|
||||
|
|
@ -196,6 +231,10 @@ IggyGlyphMetrics * UIBitmapFont::GetGlyphMetrics(S32 glyph,IggyGlyphMetrics *met
|
|||
//Callback function type that should return true iff the glyph has no visible elements
|
||||
rrbool UIBitmapFont::IsGlyphEmpty (S32 glyph)
|
||||
{
|
||||
if (m_cFontData == NULL)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (m_cFontData->glyphIsWhitespace(glyph)) return true;
|
||||
return false;//app.DebugPrintf("Is glyph %d empty? %s\n",glyph,isEmpty?"TRUE":"FALSE");
|
||||
}
|
||||
|
|
@ -214,6 +253,10 @@ F32 UIBitmapFont::GetKerningForGlyphPair(S32 first_glyph,S32 second_glyph)
|
|||
//Callback function type used for reporting whether a bitmap supports a given glyph at the given scale
|
||||
rrbool UIBitmapFont::CanProvideBitmap(S32 glyph,F32 pixel_scale)
|
||||
{
|
||||
if (m_cFontData == NULL || m_cFontData->getFontData() == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
//app.DebugPrintf("Can provide bitmap for glyph %d at scale %f? %s\n",glyph,pixel_scale,canProvideBitmap?"TRUE":"FALSE");
|
||||
return true;
|
||||
}
|
||||
|
|
@ -226,6 +269,16 @@ rrbool UIBitmapFont::CanProvideBitmap(S32 glyph,F32 pixel_scale)
|
|||
// bitmap The structure to store the bitmap into
|
||||
rrbool UIBitmapFont::GetGlyphBitmap(S32 glyph,F32 pixel_scale,IggyBitmapCharacter *bitmap)
|
||||
{
|
||||
if (bitmap == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (m_cFontData == NULL || m_cFontData->getFontData() == NULL)
|
||||
{
|
||||
memset(bitmap, 0, sizeof(*bitmap));
|
||||
return false;
|
||||
}
|
||||
|
||||
//Description
|
||||
// Data structure used to return to Iggy the bitmap to use for a glyph
|
||||
//Members
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@
|
|||
#include "..\..\..\Minecraft.World\net.minecraft.world.entity.boss.enderdragon.h"
|
||||
#ifdef _WINDOWS64
|
||||
#include "..\..\KeyboardMouseInput.h"
|
||||
#include "UIControl_Slider.h"
|
||||
#endif
|
||||
#include "..\..\EnderDragonRenderer.h"
|
||||
#include "..\..\MultiPlayerLocalPlayer.h"
|
||||
|
|
@ -690,100 +689,6 @@ void UIController::tickInput()
|
|||
else
|
||||
#endif
|
||||
{
|
||||
#ifdef _WINDOWS64
|
||||
if (!g_KBMInput.IsMouseGrabbed())
|
||||
{
|
||||
UIScene *pScene = NULL;
|
||||
for (int grp = 0; grp < eUIGroup_COUNT && !pScene; ++grp)
|
||||
{
|
||||
pScene = m_groups[grp]->GetTopScene(eUILayer_Debug);
|
||||
if (!pScene) pScene = m_groups[grp]->GetTopScene(eUILayer_Tooltips);
|
||||
if (!pScene) pScene = m_groups[grp]->GetTopScene(eUILayer_Error);
|
||||
if (!pScene) pScene = m_groups[grp]->GetTopScene(eUILayer_Alert);
|
||||
if (!pScene) pScene = m_groups[grp]->GetTopScene(eUILayer_Popup);
|
||||
if (!pScene) pScene = m_groups[grp]->GetTopScene(eUILayer_Fullscreen);
|
||||
if (!pScene) pScene = m_groups[grp]->GetTopScene(eUILayer_Scene);
|
||||
}
|
||||
if (pScene && pScene->getMovie())
|
||||
{
|
||||
Iggy *movie = pScene->getMovie();
|
||||
F32 mouseX = (F32)g_KBMInput.GetMouseX();
|
||||
F32 mouseY = (F32)g_KBMInput.GetMouseY();
|
||||
|
||||
extern HWND g_hWnd;
|
||||
if (g_hWnd)
|
||||
{
|
||||
RECT rc;
|
||||
GetClientRect(g_hWnd, &rc);
|
||||
int winW = rc.right - rc.left;
|
||||
int winH = rc.bottom - rc.top;
|
||||
if (winW > 0 && winH > 0)
|
||||
{
|
||||
mouseX = mouseX * (m_fScreenWidth / (F32)winW);
|
||||
mouseY = mouseY * (m_fScreenHeight / (F32)winH);
|
||||
}
|
||||
}
|
||||
|
||||
IggyFocusHandle currentFocus = IGGY_FOCUS_NULL;
|
||||
IggyFocusableObject focusables[64];
|
||||
S32 numFocusables = 0;
|
||||
IggyPlayerGetFocusableObjects(movie, ¤tFocus, focusables, 64, &numFocusables);
|
||||
|
||||
IggyFocusHandle hitObject = IGGY_FOCUS_NULL;
|
||||
for (S32 i = 0; i < numFocusables; ++i)
|
||||
{
|
||||
if (mouseX >= focusables[i].x0 && mouseX <= focusables[i].x1 &&
|
||||
mouseY >= focusables[i].y0 && mouseY <= focusables[i].y1)
|
||||
{
|
||||
hitObject = focusables[i].object;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (hitObject != IGGY_FOCUS_NULL && hitObject != currentFocus)
|
||||
{
|
||||
IggyPlayerSetFocusRS(movie, hitObject, 0);
|
||||
}
|
||||
|
||||
if (g_KBMInput.IsMouseButtonDown(0) || g_KBMInput.IsMouseButtonPressed(0))
|
||||
{
|
||||
vector<UIControl *> *controls = pScene->GetControls();
|
||||
if (controls)
|
||||
{
|
||||
for (size_t i = 0; i < controls->size(); i++)
|
||||
{
|
||||
UIControl *ctrl = (*controls)[i];
|
||||
if (ctrl && ctrl->getControlType() == UIControl::eSlider && ctrl->getVisible())
|
||||
{
|
||||
S32 cx = ctrl->getXPos();
|
||||
S32 cy = ctrl->getYPos();
|
||||
S32 cw = ctrl->getWidth();
|
||||
S32 ch = ctrl->getHeight();
|
||||
|
||||
if (mouseX >= cx && mouseX <= cx + cw &&
|
||||
mouseY >= cy && mouseY <= cy + ch)
|
||||
{
|
||||
UIControl_Slider *pSlider = (UIControl_Slider *)ctrl;
|
||||
float fNewSliderPos = (mouseX - (float)cx) / (float)pSlider->GetRealWidth();
|
||||
if (fNewSliderPos < 0.0f) fNewSliderPos = 0.0f;
|
||||
if (fNewSliderPos > 1.0f) fNewSliderPos = 1.0f;
|
||||
pSlider->SetSliderTouchPos(fNewSliderPos);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int wheel = g_KBMInput.GetMouseWheel();
|
||||
if (wheel > 0)
|
||||
handleKeyPress(0, ACTION_MENU_UP);
|
||||
else if (wheel < 0)
|
||||
handleKeyPress(0, ACTION_MENU_DOWN);
|
||||
}
|
||||
#endif
|
||||
handleInput();
|
||||
++m_accumulatedTicks;
|
||||
}
|
||||
|
|
@ -3145,4 +3050,4 @@ void UIController::SendTouchInput(unsigned int iPad, unsigned int key, bool bPre
|
|||
}
|
||||
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
@ -148,24 +148,41 @@ CFontData::CFontData()
|
|||
m_sFontData = NULL;
|
||||
m_kerningTable = NULL;
|
||||
m_pbRawImage = NULL;
|
||||
m_pfAdvanceTable = NULL;
|
||||
}
|
||||
|
||||
CFontData::CFontData(SFontData &sFontData, int *pbRawImage)
|
||||
: m_unicodeMap( sFontData.m_uiGlyphCount + 2 )
|
||||
{
|
||||
this->m_sFontData = &sFontData;
|
||||
m_kerningTable = NULL;
|
||||
m_pbRawImage = NULL;
|
||||
m_pfAdvanceTable = NULL;
|
||||
|
||||
// INITIALISE ALPHA CHANNEL //
|
||||
|
||||
// Glyph Archive (1Byte per pixel).
|
||||
unsigned int archiveSize = sFontData.m_uiGlyphMapX * sFontData.m_uiGlyphMapY;
|
||||
if (archiveSize == 0)
|
||||
{
|
||||
app.DebugPrintf("CFontData: invalid archive size for '%s'\n", sFontData.m_strFontName.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
this->m_pbRawImage = new unsigned char[archiveSize];
|
||||
|
||||
// 4J-JEV: Take the alpha channel from each pixel.
|
||||
for (unsigned int i = 0; i < archiveSize; i++)
|
||||
if (pbRawImage == NULL)
|
||||
{
|
||||
this->m_pbRawImage[i] = (pbRawImage[i] & 0xFF000000) >> 24;
|
||||
app.DebugPrintf("CFontData: raw font image missing for '%s', using blank fallback\n", sFontData.m_strFontName.c_str());
|
||||
memset(this->m_pbRawImage, 0, archiveSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 4J-JEV: Take the alpha channel from each pixel.
|
||||
for (unsigned int i = 0; i < archiveSize; i++)
|
||||
{
|
||||
this->m_pbRawImage[i] = (pbRawImage[i] & 0xFF000000) >> 24;
|
||||
}
|
||||
}
|
||||
|
||||
// CREATE UNICODE MAP //
|
||||
|
|
@ -267,10 +284,17 @@ void CFontData::release()
|
|||
delete [] m_kerningTable;
|
||||
delete [] m_pfAdvanceTable;
|
||||
delete [] m_pbRawImage;
|
||||
m_kerningTable = NULL;
|
||||
m_pfAdvanceTable = NULL;
|
||||
m_pbRawImage = NULL;
|
||||
}
|
||||
|
||||
const string CFontData::getFontName()
|
||||
{
|
||||
if (m_sFontData == NULL)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
return m_sFontData->m_strFontName;
|
||||
}
|
||||
|
||||
|
|
@ -289,11 +313,19 @@ unsigned short CFontData::getGlyphId(unsigned int unicodepoint)
|
|||
|
||||
unsigned int CFontData::getUnicode(unsigned short glyphId)
|
||||
{
|
||||
if (m_sFontData == NULL || glyphId >= m_sFontData->m_uiGlyphCount)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return m_sFontData->Codepoints[glyphId];
|
||||
}
|
||||
|
||||
unsigned char *CFontData::topLeftPixel(int row, int col)
|
||||
{
|
||||
if (m_pbRawImage == NULL || m_sFontData == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
unsigned char *out = m_pbRawImage;
|
||||
moveCursor(out, col * m_sFontData->m_uiGlyphWidth, row* m_sFontData->m_uiGlyphHeight);
|
||||
return out;
|
||||
|
|
@ -301,22 +333,40 @@ unsigned char *CFontData::topLeftPixel(int row, int col)
|
|||
|
||||
void CFontData::getPos(unsigned short glyphId, int &rowOut, int &colOut)
|
||||
{
|
||||
if (m_sFontData == NULL || m_sFontData->m_uiGlyphMapCols == 0)
|
||||
{
|
||||
rowOut = 0;
|
||||
colOut = 0;
|
||||
return;
|
||||
}
|
||||
rowOut = glyphId / m_sFontData->m_uiGlyphMapCols;
|
||||
colOut = glyphId % m_sFontData->m_uiGlyphMapCols;
|
||||
}
|
||||
|
||||
float CFontData::getAdvance(unsigned short glyphId)
|
||||
{
|
||||
if (m_pfAdvanceTable == NULL || m_sFontData == NULL || glyphId >= m_sFontData->m_uiGlyphCount)
|
||||
{
|
||||
return 0.0f;
|
||||
}
|
||||
return m_pfAdvanceTable[glyphId];
|
||||
}
|
||||
|
||||
int CFontData::getWidth(unsigned short glyphId)
|
||||
{
|
||||
if (m_kerningTable == NULL || m_sFontData == NULL || glyphId >= m_sFontData->m_uiGlyphCount)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return m_kerningTable[glyphId];
|
||||
}
|
||||
|
||||
bool CFontData::glyphIsWhitespace(unsigned short glyphId)
|
||||
{
|
||||
if (m_sFontData == NULL || glyphId >= m_sFontData->m_uiGlyphCount)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return unicodeIsWhitespace( getUnicode(glyphId) );
|
||||
}
|
||||
|
||||
|
|
@ -337,5 +387,9 @@ bool CFontData::unicodeIsWhitespace(unsigned int unicode)
|
|||
|
||||
void CFontData::moveCursor(unsigned char *&cursor, unsigned int dx, unsigned int dy)
|
||||
{
|
||||
if (m_sFontData == NULL || cursor == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
cursor += (dy * m_sFontData->m_uiGlyphMapX) + dx;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ UIGroup::UIGroup(EUIGroup group, int iPad)
|
|||
m_bIgnorePlayerJoinMenuDisplayed = false;
|
||||
|
||||
m_updateFocusStateCountdown = 0;
|
||||
m_viewportType = C4JRender::VIEWPORT_TYPE_FULLSCREEN;
|
||||
|
||||
for(unsigned int i = 0; i < eUILayer_COUNT; ++i)
|
||||
{
|
||||
|
|
@ -31,16 +32,12 @@ UIGroup::UIGroup(EUIGroup group, int iPad)
|
|||
m_tutorialPopup = (UIComponent_TutorialPopup *)m_layers[(int)eUILayer_Popup]->addComponent(m_iPad, eUIComponent_TutorialPopup);
|
||||
|
||||
m_hud = (UIScene_HUD *)m_layers[(int)eUILayer_HUD]->addComponent(m_iPad, eUIScene_HUD);
|
||||
|
||||
//m_layers[(int)eUILayer_Chat]->addComponent(m_iPad, eUIComponent_Chat);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pressStartToPlay = (UIComponent_PressStartToPlay *)m_layers[(int)eUILayer_Tooltips]->addComponent(0, eUIComponent_PressStartToPlay);
|
||||
}
|
||||
|
||||
m_viewportType = C4JRender::VIEWPORT_TYPE_FULLSCREEN;
|
||||
|
||||
// 4J Stu - Pre-allocate this for cached rendering in scenes. It's horribly slow to do dynamically, but we should only need one
|
||||
// per group as we will only be displaying one of these types of scenes at a time
|
||||
m_commandBufferList = MemoryTracker::genLists(1);
|
||||
|
|
@ -419,3 +416,4 @@ UIScene *UIGroup::FindScene(EUIScene sceneType)
|
|||
|
||||
return pScene;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -109,8 +109,6 @@ public:
|
|||
#ifdef __PSVITA__
|
||||
UILayer *GetParentLayer() {return m_parentLayer;}
|
||||
EUIGroup GetParentLayerGroup() {return m_parentLayer->m_parentGroup->GetGroup();}
|
||||
#endif
|
||||
#if defined(__PSVITA__) || defined(_WINDOWS64)
|
||||
vector<UIControl *> *GetControls() {return &m_controls;}
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -2,10 +2,6 @@
|
|||
#include "UI.h"
|
||||
#include "UIScene_AbstractContainerMenu.h"
|
||||
|
||||
#ifdef _WINDOWS64
|
||||
#include "..\..\KeyboardMouseInput.h"
|
||||
#endif
|
||||
|
||||
#include "..\..\..\Minecraft.World\net.minecraft.world.inventory.h"
|
||||
#include "..\..\..\Minecraft.World\net.minecraft.world.item.h"
|
||||
#include "..\..\MultiplayerLocalPlayer.h"
|
||||
|
|
@ -39,15 +35,6 @@ UIScene_AbstractContainerMenu::~UIScene_AbstractContainerMenu()
|
|||
void UIScene_AbstractContainerMenu::handleDestroy()
|
||||
{
|
||||
app.DebugPrintf("UIScene_AbstractContainerMenu::handleDestroy\n");
|
||||
|
||||
#ifdef _WINDOWS64
|
||||
g_savedInventoryCursorPos.x = m_pointerPos.x;
|
||||
g_savedInventoryCursorPos.y = m_pointerPos.y;
|
||||
g_savedInventoryCursorPos.hasSavedPos = true;
|
||||
|
||||
g_KBMInput.SetCursorHiddenForUI(false);
|
||||
#endif
|
||||
|
||||
Minecraft *pMinecraft = Minecraft::GetInstance();
|
||||
if( pMinecraft->localgameModes[m_iPad] != NULL )
|
||||
{
|
||||
|
|
@ -72,7 +59,6 @@ void UIScene_AbstractContainerMenu::handleDestroy()
|
|||
ui.OverrideSFX(m_iPad,ACTION_MENU_RIGHT,false);
|
||||
ui.OverrideSFX(m_iPad,ACTION_MENU_UP,false);
|
||||
ui.OverrideSFX(m_iPad,ACTION_MENU_DOWN,false);
|
||||
|
||||
}
|
||||
|
||||
void UIScene_AbstractContainerMenu::InitDataAssociations(int iPad, AbstractContainerMenu *menu, int startIndex)
|
||||
|
|
@ -81,9 +67,6 @@ void UIScene_AbstractContainerMenu::InitDataAssociations(int iPad, AbstractConta
|
|||
|
||||
void UIScene_AbstractContainerMenu::PlatformInitialize(int iPad, int startIndex)
|
||||
{
|
||||
#ifdef _WINDOWS64
|
||||
g_KBMInput.SetCursorHiddenForUI(true);
|
||||
#endif
|
||||
|
||||
m_labelInventory.init( app.GetString(IDS_INVENTORY) );
|
||||
|
||||
|
|
@ -123,8 +106,8 @@ void UIScene_AbstractContainerMenu::PlatformInitialize(int iPad, int startIndex)
|
|||
#ifdef __ORBIS__
|
||||
// we need to map the touchpad rectangle to the UI rectangle. While it works great for the creative menu, it is much too sensitive for the smaller menus.
|
||||
//X coordinate of the touch point (0 to 1919)
|
||||
//Y coordinate of the touch point (0 to 941: DUALSHOCK<EFBFBD>4 wireless controllers and the CUH-ZCT1J/CAP-ZCT1J/CAP-ZCT1U controllers for the PlayStation<6F>4 development tool,
|
||||
//0 to 753: JDX-1000x series controllers for the PlayStation<EFBFBD>4 development tool,)
|
||||
//Y coordinate of the touch point (0 to 941: DUALSHOCK®4 wireless controllers and the CUH-ZCT1J/CAP-ZCT1J/CAP-ZCT1U controllers for the PlayStation®4 development tool,
|
||||
//0 to 753: JDX-1000x series controllers for the PlayStation®4 development tool,)
|
||||
m_fTouchPadMulX=fPanelWidth/1919.0f;
|
||||
m_fTouchPadMulY=fPanelHeight/941.0f;
|
||||
m_fTouchPadDeadZoneX=15.0f*m_fTouchPadMulX;
|
||||
|
|
@ -168,30 +151,17 @@ void UIScene_AbstractContainerMenu::PlatformInitialize(int iPad, int startIndex)
|
|||
//m_pointerControl->SetPosition( &vPointerPos );
|
||||
m_pointerPos = vPointerPos;
|
||||
|
||||
#ifdef _WINDOWS64
|
||||
if (g_savedInventoryCursorPos.hasSavedPos)
|
||||
{
|
||||
m_pointerPos.x = g_savedInventoryCursorPos.x;
|
||||
m_pointerPos.y = g_savedInventoryCursorPos.y;
|
||||
|
||||
if (m_pointerPos.x < m_fPointerMinX) m_pointerPos.x = m_fPointerMinX;
|
||||
if (m_pointerPos.x > m_fPointerMaxX) m_pointerPos.x = m_fPointerMaxX;
|
||||
if (m_pointerPos.y < m_fPointerMinY) m_pointerPos.y = m_fPointerMinY;
|
||||
if (m_pointerPos.y > m_fPointerMaxY) m_pointerPos.y = m_fPointerMaxY;
|
||||
}
|
||||
#endif
|
||||
|
||||
IggyEvent mouseEvent;
|
||||
S32 width, height;
|
||||
m_parentLayer->getRenderDimensions(width, height);
|
||||
S32 x = m_pointerPos.x*((float)width/m_movieWidth);
|
||||
S32 y = m_pointerPos.y*((float)height/m_movieHeight);
|
||||
S32 y = m_pointerPos.y*((float)height/m_movieHeight);
|
||||
IggyMakeEventMouseMove( &mouseEvent, x, y);
|
||||
|
||||
IggyEventResult result;
|
||||
IggyPlayerDispatchEventRS ( getMovie() , &mouseEvent , &result );
|
||||
|
||||
#ifdef USE_POINTER_ACCEL
|
||||
#ifdef USE_POINTER_ACCEL
|
||||
m_fPointerVelX = 0.0f;
|
||||
m_fPointerVelY = 0.0f;
|
||||
m_fPointerAccelX = 0.0f;
|
||||
|
|
@ -208,10 +178,8 @@ void UIScene_AbstractContainerMenu::tick()
|
|||
IggyEvent mouseEvent;
|
||||
S32 width, height;
|
||||
m_parentLayer->getRenderDimensions(width, height);
|
||||
|
||||
S32 x = (S32)(m_pointerPos.x * ((float)width / m_movieWidth));
|
||||
S32 y = (S32)(m_pointerPos.y * ((float)height / m_movieHeight));
|
||||
|
||||
S32 x = m_pointerPos.x*((float)width/m_movieWidth);
|
||||
S32 y = m_pointerPos.y*((float)height/m_movieHeight);
|
||||
IggyMakeEventMouseMove( &mouseEvent, x, y);
|
||||
|
||||
// 4J Stu - This seems to be broken on Durango, so do it ourself
|
||||
|
|
@ -224,7 +192,6 @@ void UIScene_AbstractContainerMenu::tick()
|
|||
IggyPlayerDispatchEventRS ( getMovie() , &mouseEvent , &result );
|
||||
}
|
||||
|
||||
|
||||
void UIScene_AbstractContainerMenu::render(S32 width, S32 height, C4JRender::eViewportType viewpBort)
|
||||
{
|
||||
m_cacheSlotRenders = true;
|
||||
|
|
|
|||
|
|
@ -36,8 +36,6 @@ public:
|
|||
virtual void handleDestroy();
|
||||
|
||||
int getPad() { return m_iPad; }
|
||||
int getMovieWidth() { return m_movieWidth; }
|
||||
int getMovieHeight() { return m_movieHeight; }
|
||||
bool getIgnoreInput() { return m_bIgnoreInput; }
|
||||
void setIgnoreInput(bool bVal) { m_bIgnoreInput=bVal; }
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,9 @@
|
|||
#include "UI.h"
|
||||
#include "UIScene_ConnectingProgress.h"
|
||||
#include "..\..\Minecraft.h"
|
||||
#ifdef _WINDOWS64
|
||||
#include "..\Network\PlatformNetworkManagerStub.h"
|
||||
#endif
|
||||
|
||||
UIScene_ConnectingProgress::UIScene_ConnectingProgress(int iPad, void *_initData, UILayer *parentLayer) : UIScene(iPad, parentLayer)
|
||||
{
|
||||
|
|
@ -113,6 +116,16 @@ void UIScene_ConnectingProgress::handleTimerComplete(int id)
|
|||
// Check if the connection failed
|
||||
Minecraft *pMinecraft = Minecraft::GetInstance();
|
||||
|
||||
#ifdef _WINDOWS64
|
||||
if (CPlatformNetworkManagerStub::IsServerTransferInProgress())
|
||||
{
|
||||
pMinecraft->m_connectionFailed[m_iPad] = false;
|
||||
pMinecraft->m_connectionFailedReason[m_iPad] = DisconnectPacket::eDisconnect_None;
|
||||
addTimer(0, m_timerTime);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if( pMinecraft->m_connectionFailed[m_iPad] || !g_NetworkManager.IsInSession() )
|
||||
{
|
||||
|
||||
|
|
@ -132,6 +145,9 @@ void UIScene_ConnectingProgress::handleTimerComplete(int id)
|
|||
case DisconnectPacket::eDisconnect_Kicked:
|
||||
exitReasonStringId = IDS_DISCONNECTED_KICKED;
|
||||
break;
|
||||
case DisconnectPacket::eDisconnect_Banned:
|
||||
exitReasonStringId = IDS_DISCONNECTED_BANNED;
|
||||
break;
|
||||
case DisconnectPacket::eDisconnect_NoUGC_AllLocal:
|
||||
exitReasonStringId = IDS_NO_USER_CREATED_CONTENT_PRIVILEGE_ALL_LOCAL;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
#include "stdafx.h"
|
||||
#include "UI.h"
|
||||
#include "UIScene_LoadOrJoinMenu.h"
|
||||
#include <cwctype>
|
||||
|
||||
#include "..\..\..\Minecraft.World\StringHelpers.h"
|
||||
#include "..\..\..\Minecraft.World\LevelSettings.h"
|
||||
#include "..\..\..\Minecraft.World\net.minecraft.world.item.h"
|
||||
#include "..\..\..\Minecraft.World\net.minecraft.world.level.h"
|
||||
#include "..\..\..\Minecraft.World\net.minecraft.world.level.chunk.storage.h"
|
||||
|
|
@ -11,9 +13,14 @@
|
|||
#include "..\..\..\Minecraft.World\ConsoleSaveFileSplit.h"
|
||||
#include "..\..\ProgressRenderer.h"
|
||||
#include "..\..\MinecraftServer.h"
|
||||
#include "..\..\User.h"
|
||||
#include "..\..\Options.h"
|
||||
#include "..\..\TexturePackRepository.h"
|
||||
#include "..\..\TexturePack.h"
|
||||
#include "..\Network\SessionInfo.h"
|
||||
#ifdef _WINDOWS64
|
||||
#include "..\..\Windows64\Network\WinsockNetLayer.h"
|
||||
#endif
|
||||
#if defined(__PS3__) || defined(__ORBIS__) || defined(__PSVITA__)
|
||||
#include "Common\Network\Sony\SonyHttp.h"
|
||||
#include "Common\Network\Sony\SonyRemoteStorage.h"
|
||||
|
|
@ -25,6 +32,79 @@
|
|||
#include "message_dialog.h"
|
||||
#endif
|
||||
|
||||
namespace
|
||||
{
|
||||
// Custom, Windows64-only metadata packed into the host settings bitfield so LAN browser rows
|
||||
// can show the selected LCE minigame type.
|
||||
const unsigned int MINIGAME_SETTINGS_FLAG = 0x80000000u;
|
||||
const unsigned int MINIGAME_SETTINGS_TYPE_MASK = 0x70000000u;
|
||||
const unsigned int MINIGAME_SETTINGS_TYPE_SHIFT = 28u;
|
||||
const unsigned int MINIGAME_SETTINGS_ROLE_MASK = 0x0C000000u;
|
||||
const unsigned int MINIGAME_SETTINGS_ROLE_SHIFT = 26u;
|
||||
const unsigned int MINIGAME_SETTINGS_QUEUE_MASK = 0x03000000u;
|
||||
const unsigned int MINIGAME_SETTINGS_QUEUE_SHIFT = 24u;
|
||||
const unsigned int MINIGAME_ROLE_HUB = 0u;
|
||||
const unsigned int MINIGAME_ROLE_MATCH = 1u;
|
||||
|
||||
const wchar_t *GetQueueLabelFromSettings(unsigned int gameHostSettings)
|
||||
{
|
||||
const unsigned int queueMode = (gameHostSettings & MINIGAME_SETTINGS_QUEUE_MASK) >> MINIGAME_SETTINGS_QUEUE_SHIFT;
|
||||
switch(queueMode)
|
||||
{
|
||||
case 0: return L"Solo";
|
||||
case 1: return L"Doubles";
|
||||
case 2: return L"Squads";
|
||||
case 3: return L"Practice";
|
||||
default: return L"Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
const wchar_t *GetMinigameNameFromSettings(unsigned int gameHostSettings)
|
||||
{
|
||||
if ((gameHostSettings & MINIGAME_SETTINGS_FLAG) == 0)
|
||||
{
|
||||
return L"Unknown";
|
||||
}
|
||||
|
||||
const unsigned int minigameIndex = (gameHostSettings & MINIGAME_SETTINGS_TYPE_MASK) >> MINIGAME_SETTINGS_TYPE_SHIFT;
|
||||
switch(minigameIndex)
|
||||
{
|
||||
case 0: return L"Battle";
|
||||
case 1: return L"Tumble";
|
||||
case 2: return L"Glide";
|
||||
case 3:
|
||||
{
|
||||
const unsigned int role = (gameHostSettings & MINIGAME_SETTINGS_ROLE_MASK) >> MINIGAME_SETTINGS_ROLE_SHIFT;
|
||||
if (role == MINIGAME_ROLE_MATCH)
|
||||
{
|
||||
static wchar_t bedwarsMatchLabel[64];
|
||||
swprintf_s(bedwarsMatchLabel, 64, L"Bedwars %ls Match", GetQueueLabelFromSettings(gameHostSettings));
|
||||
return bedwarsMatchLabel;
|
||||
}
|
||||
return L"Bedwars Hub";
|
||||
}
|
||||
default: return L"Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
wstring TrimWhitespace(const wstring &input)
|
||||
{
|
||||
size_t first = 0;
|
||||
while(first < input.length() && std::iswspace(input[first]))
|
||||
{
|
||||
++first;
|
||||
}
|
||||
|
||||
size_t last = input.length();
|
||||
while(last > first && std::iswspace(input[last - 1]))
|
||||
{
|
||||
--last;
|
||||
}
|
||||
|
||||
return input.substr(first, last - first);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef SONY_REMOTE_STORAGE_DOWNLOAD
|
||||
unsigned long UIScene_LoadOrJoinMenu::m_ulFileSize=0L;
|
||||
|
|
@ -119,6 +199,7 @@ UIScene_LoadOrJoinMenu::UIScene_LoadOrJoinMenu(int iPad, void *initData, UILayer
|
|||
m_bAllLoaded = false;
|
||||
m_bRetrievingSaveThumbnails = false;
|
||||
m_bSaveThumbnailReady = false;
|
||||
m_bMinigamesMode = false;
|
||||
m_bExitScene=false;
|
||||
m_pSaveDetails=NULL;
|
||||
m_bSavesDisplayed=false;
|
||||
|
|
@ -133,6 +214,22 @@ UIScene_LoadOrJoinMenu::UIScene_LoadOrJoinMenu(int iPad, void *initData, UILayer
|
|||
m_bSaveTransferInProgress=false;
|
||||
#endif
|
||||
m_eAction = eAction_None;
|
||||
m_pDirectConnectSession = NULL;
|
||||
|
||||
LoadOrJoinMenuInitData *loadOrJoinInit = (LoadOrJoinMenuInitData *)initData;
|
||||
if(loadOrJoinInit != NULL &&
|
||||
loadOrJoinInit->magic == LOAD_OR_JOIN_MENU_INIT_MAGIC &&
|
||||
loadOrJoinInit->bMinigamesMode)
|
||||
{
|
||||
m_bMinigamesMode = true;
|
||||
}
|
||||
|
||||
if(m_bMinigamesMode)
|
||||
{
|
||||
m_labelSavesListTitle.init(L"Create Minigame Server");
|
||||
m_labelJoinListTitle.init(L"Server Browser");
|
||||
m_labelNoGames.init(L"No servers found");
|
||||
}
|
||||
|
||||
m_bMultiplayerAllowed = ProfileManager.IsSignedInLive( m_iPad ) && ProfileManager.AllowedToPlayMultiplayer(m_iPad);
|
||||
|
||||
|
|
@ -164,7 +261,11 @@ UIScene_LoadOrJoinMenu::UIScene_LoadOrJoinMenu(int iPad, void *initData, UILayer
|
|||
#endif
|
||||
|
||||
// block input if we're waiting for DLC to install, and wipe the saves list. The end of dlc mounting custom message will fill the list again
|
||||
if(app.StartInstallDLCProcess(m_iPad)==true || app.DLCInstallPending())
|
||||
if(m_bMinigamesMode)
|
||||
{
|
||||
Initialise();
|
||||
}
|
||||
else if(app.StartInstallDLCProcess(m_iPad)==true || app.DLCInstallPending())
|
||||
{
|
||||
// if we're waiting for DLC to mount, don't fill the save list. The custom message on end of dlc mounting will do that
|
||||
m_bIgnoreInput = true;
|
||||
|
|
@ -192,7 +293,7 @@ UIScene_LoadOrJoinMenu::UIScene_LoadOrJoinMenu(int iPad, void *initData, UILayer
|
|||
MinecraftServer::resetFlags();
|
||||
|
||||
// If we're not ignoring input, then we aren't still waiting for the DLC to mount, and can now check for corrupt dlc. Otherwise this will happen when the dlc has finished mounting.
|
||||
if( !m_bIgnoreInput)
|
||||
if( !m_bIgnoreInput && !m_bMinigamesMode)
|
||||
{
|
||||
app.m_dlcManager.checkForCorruptDLCAndAlert();
|
||||
}
|
||||
|
|
@ -299,10 +400,24 @@ UIScene_LoadOrJoinMenu::~UIScene_LoadOrJoinMenu()
|
|||
}
|
||||
delete [] m_saveDetails;
|
||||
}
|
||||
|
||||
delete m_pDirectConnectSession;
|
||||
m_pDirectConnectSession = NULL;
|
||||
}
|
||||
|
||||
void UIScene_LoadOrJoinMenu::updateTooltips()
|
||||
{
|
||||
if(m_bMinigamesMode)
|
||||
{
|
||||
int iY = -1;
|
||||
if(DoesGamesListHaveFocus() && m_buttonListGames.getItemCount() > 0)
|
||||
{
|
||||
iY = IDS_TOOLTIPS_VIEW_GAMERCARD;
|
||||
}
|
||||
ui.SetTooltips( DEFAULT_XUI_MENU_USER, IDS_TOOLTIPS_SELECT, IDS_TOOLTIPS_BACK, -1, iY);
|
||||
return;
|
||||
}
|
||||
|
||||
// update the tooltips
|
||||
// if the saves list has focus, then we should show the Delete Save tooltip
|
||||
// if the games list has focus, then we should the the View Gamercard tooltip
|
||||
|
|
@ -391,6 +506,12 @@ void UIScene_LoadOrJoinMenu::updateTooltips()
|
|||
//
|
||||
void UIScene_LoadOrJoinMenu::Initialise()
|
||||
{
|
||||
if(m_bMinigamesMode)
|
||||
{
|
||||
InitialiseMinigamesMode();
|
||||
return;
|
||||
}
|
||||
|
||||
m_iSaveListIndex = 0;
|
||||
m_iGameListIndex = 0;
|
||||
|
||||
|
|
@ -445,6 +566,35 @@ void UIScene_LoadOrJoinMenu::Initialise()
|
|||
app.m_dlcManager.checkForCorruptDLCAndAlert();
|
||||
}
|
||||
|
||||
void UIScene_LoadOrJoinMenu::InitialiseMinigamesMode()
|
||||
{
|
||||
app.DebugPrintf("UIScene_LoadOrJoinMenu::InitialiseMinigamesMode\n");
|
||||
|
||||
m_iSaveListIndex = 0;
|
||||
m_iGameListIndex = 0;
|
||||
m_iDefaultButtonsC = 0;
|
||||
m_iMashUpButtonsC = 0;
|
||||
m_generators.clear();
|
||||
|
||||
m_buttonListSaves.clearList();
|
||||
m_buttonListSaves.addItem(L"Battle");
|
||||
m_buttonListSaves.addItem(L"Tumble");
|
||||
m_buttonListSaves.addItem(L"Glide");
|
||||
m_buttonListSaves.addItem(L"Bedwars");
|
||||
m_buttonListSaves.addItem(L"Direct Connect");
|
||||
|
||||
m_iDefaultButtonsC = m_buttonListSaves.getItemCount();
|
||||
m_controlSavesTimer.setVisible(false);
|
||||
m_labelNoGames.setVisible(false);
|
||||
|
||||
m_iRequestingThumbnailId = 0;
|
||||
m_bAllLoaded = true;
|
||||
m_bSavesDisplayed = true;
|
||||
m_bRetrievingSaveThumbnails = false;
|
||||
m_bSaveThumbnailReady = false;
|
||||
m_bIgnoreInput = false;
|
||||
}
|
||||
|
||||
void UIScene_LoadOrJoinMenu::updateComponents()
|
||||
{
|
||||
m_parentLayer->showComponent(m_iPad,eUIComponent_Panorama,true);
|
||||
|
|
@ -472,6 +622,16 @@ void UIScene_LoadOrJoinMenu::handleGainFocus(bool navBack)
|
|||
// Add load online timer
|
||||
addTimer(JOIN_LOAD_ONLINE_TIMER_ID,JOIN_LOAD_ONLINE_TIMER_TIME);
|
||||
|
||||
if(m_bMinigamesMode)
|
||||
{
|
||||
if(navBack)
|
||||
{
|
||||
m_bIgnoreInput = false;
|
||||
UpdateGamesList();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if(navBack)
|
||||
{
|
||||
app.SetLiveLinkRequired( true );
|
||||
|
|
@ -962,6 +1122,15 @@ void UIScene_LoadOrJoinMenu::handleInput(int iPad, int key, bool repeat, bool pr
|
|||
}
|
||||
break;
|
||||
case ACTION_MENU_X:
|
||||
if(m_bMinigamesMode)
|
||||
{
|
||||
if(pressed)
|
||||
{
|
||||
StartDirectConnectKeyboard();
|
||||
handled = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
#if TO_BE_IMPLEMENTED
|
||||
// Change device
|
||||
// Fix for #12531 - TCR 001: BAS Game Stability: When a player selects to change a storage
|
||||
|
|
@ -1041,6 +1210,10 @@ void UIScene_LoadOrJoinMenu::handleInput(int iPad, int key, bool repeat, bool pr
|
|||
break;
|
||||
|
||||
case ACTION_MENU_RIGHT_SCROLL:
|
||||
if(m_bMinigamesMode)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if(DoesSavesListHaveFocus())
|
||||
{
|
||||
// 4J-PB - check we are on a valid save
|
||||
|
|
@ -1194,6 +1367,139 @@ int UIScene_LoadOrJoinMenu::KeyboardCompleteWorldNameCallback(LPVOID lpParam,boo
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void UIScene_LoadOrJoinMenu::StartDirectConnectKeyboard()
|
||||
{
|
||||
#ifdef _WINDOWS64
|
||||
m_bIgnoreInput = true;
|
||||
ui.PlayUISFX(eSFX_Press);
|
||||
InputManager.RequestKeyboard(L"Direct Connect", L"", (DWORD)m_iPad, 63, &UIScene_LoadOrJoinMenu::KeyboardCompleteDirectConnectCallback, this, C_4JInput::EKeyboardMode_Default);
|
||||
#else
|
||||
UINT uiIDA[1];
|
||||
uiIDA[0] = IDS_CONFIRM_OK;
|
||||
ui.RequestMessageBox(IDS_ERROR_NETWORK_TITLE, IDS_ERROR_NETWORK, uiIDA, 1, m_iPad, NULL, NULL, app.GetStringTable());
|
||||
#endif
|
||||
}
|
||||
|
||||
int UIScene_LoadOrJoinMenu::KeyboardCompleteDirectConnectCallback(LPVOID lpParam, bool bRes)
|
||||
{
|
||||
UIScene_LoadOrJoinMenu *pClass = (UIScene_LoadOrJoinMenu *)lpParam;
|
||||
pClass->m_bIgnoreInput = false;
|
||||
|
||||
if(!bRes)
|
||||
{
|
||||
pClass->updateTooltips();
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint16_t ui16Text[128];
|
||||
ZeroMemory(ui16Text, sizeof(ui16Text));
|
||||
InputManager.GetText(ui16Text);
|
||||
pClass->HandleDirectConnectInput((const wchar_t *)ui16Text);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void UIScene_LoadOrJoinMenu::HandleDirectConnectInput(const wchar_t *inputText)
|
||||
{
|
||||
#ifdef _WINDOWS64
|
||||
char hostIp[64];
|
||||
int hostPort = WIN64_NET_DEFAULT_PORT;
|
||||
|
||||
if(!ParseDirectConnectAddress(inputText, hostIp, sizeof(hostIp), hostPort))
|
||||
{
|
||||
app.DebugPrintf("UIScene_LoadOrJoinMenu::HandleDirectConnectInput - invalid address input\n");
|
||||
UINT uiIDA[1];
|
||||
uiIDA[0] = IDS_CONFIRM_OK;
|
||||
ui.RequestMessageBox(IDS_ERROR_NETWORK_TITLE, IDS_ERROR_NETWORK, uiIDA, 1, m_iPad, NULL, NULL, app.GetStringTable());
|
||||
return;
|
||||
}
|
||||
|
||||
delete m_pDirectConnectSession;
|
||||
m_pDirectConnectSession = new FriendSessionInfo();
|
||||
|
||||
wstring label = TrimWhitespace(inputText != NULL ? inputText : L"");
|
||||
if(label.length() == 0)
|
||||
{
|
||||
label = convStringToWstring(string(hostIp));
|
||||
}
|
||||
|
||||
size_t labelLen = label.length();
|
||||
m_pDirectConnectSession->displayLabel = new wchar_t[labelLen + 1];
|
||||
wcscpy_s(m_pDirectConnectSession->displayLabel, labelLen + 1, label.c_str());
|
||||
m_pDirectConnectSession->displayLabelLength = (unsigned char)((labelLen > 255) ? 255 : labelLen);
|
||||
m_pDirectConnectSession->displayLabelViewableStartIndex = 0;
|
||||
m_pDirectConnectSession->data.isJoinable = true;
|
||||
m_pDirectConnectSession->data.isReadyToJoin = true;
|
||||
m_pDirectConnectSession->data.hostPort = hostPort;
|
||||
m_pDirectConnectSession->data.playerCount = 0;
|
||||
m_pDirectConnectSession->data.maxPlayers = MINECRAFT_NET_MAX_PLAYERS;
|
||||
strncpy_s(m_pDirectConnectSession->data.hostIP, sizeof(m_pDirectConnectSession->data.hostIP), hostIp, _TRUNCATE);
|
||||
|
||||
wstring hostName = convStringToWstring(string(hostIp));
|
||||
wcsncpy_s(m_pDirectConnectSession->data.hostName, XUSER_NAME_SIZE, hostName.c_str(), _TRUNCATE);
|
||||
m_pDirectConnectSession->sessionId = 0;
|
||||
|
||||
app.DebugPrintf("UIScene_LoadOrJoinMenu::HandleDirectConnectInput - joining %s:%d\n", hostIp, hostPort);
|
||||
|
||||
m_initData->iPad = 0;
|
||||
m_initData->selectedSession = m_pDirectConnectSession;
|
||||
m_controlJoinTimer.setVisible(false);
|
||||
|
||||
m_bIgnoreInput = true;
|
||||
ui.NavigateToScene(ProfileManager.GetPrimaryPad(), eUIScene_JoinMenu, m_initData);
|
||||
#else
|
||||
(void)inputText;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef _WINDOWS64
|
||||
bool UIScene_LoadOrJoinMenu::ParseDirectConnectAddress(const wchar_t *inputText, char *outHostIp, size_t outHostIpSize, int &outHostPort)
|
||||
{
|
||||
if(inputText == NULL || outHostIp == NULL || outHostIpSize == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
outHostIp[0] = '\0';
|
||||
outHostPort = WIN64_NET_DEFAULT_PORT;
|
||||
|
||||
wstring trimmedInput = TrimWhitespace(inputText);
|
||||
if(trimmedInput.length() == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
wstring hostPart = trimmedInput;
|
||||
wstring portPart;
|
||||
size_t separatorPos = trimmedInput.rfind(L':');
|
||||
if(separatorPos != wstring::npos)
|
||||
{
|
||||
hostPart = TrimWhitespace(trimmedInput.substr(0, separatorPos));
|
||||
portPart = TrimWhitespace(trimmedInput.substr(separatorPos + 1));
|
||||
if(hostPart.length() == 0 || portPart.length() == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int parsedPort = _wtoi(portPart.c_str());
|
||||
if(parsedPort <= 0 || parsedPort > 65535)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
outHostPort = parsedPort;
|
||||
}
|
||||
|
||||
size_t convertedCount = 0;
|
||||
errno_t convertResult = wcstombs_s(&convertedCount, outHostIp, outHostIpSize, hostPart.c_str(), _TRUNCATE);
|
||||
if(convertResult != 0 || outHostIp[0] == '\0')
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
void UIScene_LoadOrJoinMenu::handleInitFocus(F64 controlId, F64 childId)
|
||||
{
|
||||
app.DebugPrintf(app.USER_SR, "UIScene_LoadOrJoinMenu::handleInitFocus - %d , %d\n", (int)controlId, (int)childId);
|
||||
|
|
@ -1235,11 +1541,24 @@ void UIScene_LoadOrJoinMenu::handlePress(F64 controlId, F64 childId)
|
|||
{
|
||||
m_bIgnoreInput=true;
|
||||
|
||||
int lGenID = (int)childId - 1;
|
||||
|
||||
//CD - Added for audio
|
||||
ui.PlayUISFX(eSFX_Press);
|
||||
|
||||
if(m_bMinigamesMode)
|
||||
{
|
||||
if((int)childId == (int)eMinigame_Count)
|
||||
{
|
||||
StartDirectConnectKeyboard();
|
||||
}
|
||||
else
|
||||
{
|
||||
StartMinigameServer((int)childId);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
int lGenID = (int)childId - 1;
|
||||
|
||||
if((int)childId == JOIN_LOAD_CREATE_BUTTON_INDEX)
|
||||
{
|
||||
app.SetTutorialMode( false );
|
||||
|
|
@ -1354,8 +1673,10 @@ void UIScene_LoadOrJoinMenu::handlePress(F64 controlId, F64 childId)
|
|||
|
||||
void UIScene_LoadOrJoinMenu::CheckAndJoinGame(int gameIndex)
|
||||
{
|
||||
if( m_buttonListGames.getItemCount() > 0 && gameIndex < m_currentSessions->size() )
|
||||
if( m_currentSessions != NULL && m_buttonListGames.getItemCount() > 0 && gameIndex >= 0 && gameIndex < (int)m_currentSessions->size() )
|
||||
{
|
||||
FriendSessionInfo *selectedSession = m_currentSessions->at(gameIndex);
|
||||
|
||||
#if defined(__PS3__) || defined(__ORBIS__) || defined(__PSVITA__)
|
||||
// 4J-PB - is the player allowed to join games?
|
||||
bool noUGC=false;
|
||||
|
|
@ -1472,7 +1793,7 @@ void UIScene_LoadOrJoinMenu::CheckAndJoinGame(int gameIndex)
|
|||
|
||||
//CScene_MultiGameInfo::JoinMenuInitData *initData = new CScene_MultiGameInfo::JoinMenuInitData();
|
||||
m_initData->iPad = 0;;
|
||||
m_initData->selectedSession = m_currentSessions->at( gameIndex );
|
||||
m_initData->selectedSession = selectedSession;
|
||||
|
||||
// check that we have the texture pack available
|
||||
// If it's not the default texture pack
|
||||
|
|
@ -1526,6 +1847,165 @@ void UIScene_LoadOrJoinMenu::CheckAndJoinGame(int gameIndex)
|
|||
}
|
||||
}
|
||||
|
||||
void UIScene_LoadOrJoinMenu::StartMinigameServer(int minigameIndex)
|
||||
{
|
||||
static const wchar_t *minigameNames[eMinigame_Count] =
|
||||
{
|
||||
L"Battle",
|
||||
L"Tumble",
|
||||
L"Glide",
|
||||
L"Bedwars",
|
||||
};
|
||||
|
||||
if(minigameIndex < 0 || minigameIndex >= (int)eMinigame_Count)
|
||||
{
|
||||
app.DebugPrintf("UIScene_LoadOrJoinMenu::StartMinigameServer - invalid minigame index %d\n", minigameIndex);
|
||||
m_bIgnoreInput = false;
|
||||
return;
|
||||
}
|
||||
|
||||
app.DebugPrintf("UIScene_LoadOrJoinMenu::StartMinigameServer - selected %ls (%d)\n",
|
||||
minigameNames[minigameIndex], minigameIndex);
|
||||
|
||||
int hostPad = m_iPad;
|
||||
if(hostPad < 0 || !ProfileManager.IsSignedIn(hostPad))
|
||||
{
|
||||
hostPad = ProfileManager.GetPrimaryPad();
|
||||
}
|
||||
|
||||
UINT uiIDA[1];
|
||||
uiIDA[0] = IDS_OK;
|
||||
|
||||
if(hostPad < 0)
|
||||
{
|
||||
app.DebugPrintf("UIScene_LoadOrJoinMenu::StartMinigameServer - no signed in host pad\n");
|
||||
m_bIgnoreInput = false;
|
||||
ui.RequestMessageBox(IDS_MUST_SIGN_IN_TITLE, IDS_MUST_SIGN_IN_TEXT, uiIDA, 1, m_iPad, NULL, NULL, app.GetStringTable());
|
||||
return;
|
||||
}
|
||||
|
||||
if(ProfileManager.IsGuest(hostPad))
|
||||
{
|
||||
app.DebugPrintf("UIScene_LoadOrJoinMenu::StartMinigameServer - host pad %d is guest\n", hostPad);
|
||||
m_bIgnoreInput = false;
|
||||
ui.RequestMessageBox(IDS_PRO_GUESTPROFILE_TITLE, IDS_PRO_GUESTPROFILE_TEXT, uiIDA, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
bool isClientSide = ProfileManager.IsSignedInLive(hostPad);
|
||||
#ifdef __PSVITA__
|
||||
if(app.GetGameSettings(ProfileManager.GetPrimaryPad(),eGameSetting_PSVita_NetworkModeAdhoc) == true)
|
||||
{
|
||||
CGameNetworkManager::setAdhocMode(true);
|
||||
isClientSide = SQRNetworkManager_AdHoc_Vita::GetAdhocStatus();
|
||||
}
|
||||
else
|
||||
{
|
||||
CGameNetworkManager::setAdhocMode(false);
|
||||
}
|
||||
#endif
|
||||
|
||||
if(!isClientSide)
|
||||
{
|
||||
app.DebugPrintf("UIScene_LoadOrJoinMenu::StartMinigameServer - host pad %d is offline\n", hostPad);
|
||||
m_bIgnoreInput = false;
|
||||
ui.RequestMessageBox(IDS_PRO_NOTONLINE_TITLE, IDS_PRO_NOTONLINE_TEXT, uiIDA, 1, hostPad, NULL, NULL, app.GetStringTable());
|
||||
return;
|
||||
}
|
||||
|
||||
Minecraft *pMinecraft = Minecraft::GetInstance();
|
||||
ProfileManager.SetLockedProfile(hostPad);
|
||||
ProfileManager.QuerySigninStatus();
|
||||
|
||||
pMinecraft->user->name = convStringToWstring(ProfileManager.GetGamertag(hostPad));
|
||||
app.ApplyGameSettingsChanged(hostPad);
|
||||
|
||||
const bool launchingBedwarsHub = (minigameIndex == (int)eMinigame_Bedwars);
|
||||
wstring saveTitle = L"LCE ";
|
||||
saveTitle += launchingBedwarsHub ? L"Bedwars Hub" : minigameNames[minigameIndex];
|
||||
|
||||
app.ClearTerrainFeaturePosition();
|
||||
StorageManager.ResetSaveData();
|
||||
StorageManager.SetSaveTitle(saveTitle.c_str());
|
||||
|
||||
app.SetTutorialMode(false);
|
||||
app.setLevelGenerationOptions(NULL);
|
||||
|
||||
int difficulty = 2;
|
||||
if(pMinecraft->options != NULL)
|
||||
{
|
||||
difficulty = pMinecraft->options->difficulty;
|
||||
}
|
||||
|
||||
app.SetGameHostOption(eGameHostOption_Difficulty, difficulty);
|
||||
app.SetGameHostOption(eGameHostOption_FriendsOfFriends, 1);
|
||||
app.SetGameHostOption(eGameHostOption_Gamertags, app.GetGameSettings(hostPad, eGameSetting_GamertagsVisible) ? 1 : 0);
|
||||
app.SetGameHostOption(eGameHostOption_BedrockFog, app.GetGameSettings(hostPad, eGameSetting_BedrockFog) ? 1 : 0);
|
||||
|
||||
app.SetGameHostOption(eGameHostOption_GameType, GameType::SURVIVAL->getId());
|
||||
app.SetGameHostOption(eGameHostOption_LevelType, 1);
|
||||
app.SetGameHostOption(eGameHostOption_Structures, 0);
|
||||
app.SetGameHostOption(eGameHostOption_BonusChest, 0);
|
||||
app.SetGameHostOption(eGameHostOption_DisableSaving, 1);
|
||||
StorageManager.SetSaveDisabled(true);
|
||||
|
||||
app.SetGameHostOption(eGameHostOption_PvP, launchingBedwarsHub ? 0 : 1);
|
||||
app.SetGameHostOption(eGameHostOption_TrustPlayers, 0);
|
||||
app.SetGameHostOption(eGameHostOption_FireSpreads, launchingBedwarsHub ? 0 : 1);
|
||||
app.SetGameHostOption(eGameHostOption_TNT, launchingBedwarsHub ? 0 : 1);
|
||||
app.SetGameHostOption(eGameHostOption_HostCanFly, 0);
|
||||
app.SetGameHostOption(eGameHostOption_HostCanChangeHunger, 0);
|
||||
app.SetGameHostOption(eGameHostOption_HostCanBeInvisible, 0);
|
||||
|
||||
// Tag the session with a minigame type so the server browser can show it.
|
||||
unsigned int hostSettings = app.GetGameHostOption(eGameHostOption_All);
|
||||
hostSettings |= MINIGAME_SETTINGS_FLAG;
|
||||
hostSettings &= ~MINIGAME_SETTINGS_TYPE_MASK;
|
||||
hostSettings |= ((unsigned int)(minigameIndex & 0x7) << MINIGAME_SETTINGS_TYPE_SHIFT);
|
||||
hostSettings &= ~MINIGAME_SETTINGS_ROLE_MASK;
|
||||
hostSettings |= (MINIGAME_ROLE_HUB << MINIGAME_SETTINGS_ROLE_SHIFT);
|
||||
hostSettings &= ~MINIGAME_SETTINGS_QUEUE_MASK;
|
||||
hostSettings |= (0u << MINIGAME_SETTINGS_QUEUE_SHIFT);
|
||||
app.SetGameHostOption(eGameHostOption_All, hostSettings);
|
||||
|
||||
DWORD dwLocalUsersMask = CGameNetworkManager::GetLocalPlayerMask(hostPad);
|
||||
if(dwLocalUsersMask == 0)
|
||||
{
|
||||
dwLocalUsersMask = CGameNetworkManager::GetLocalPlayerMask(ProfileManager.GetPrimaryPad());
|
||||
}
|
||||
g_NetworkManager.HostGame(dwLocalUsersMask, isClientSide, false, MINECRAFT_NET_MAX_PLAYERS, 0);
|
||||
app.DebugPrintf("UIScene_LoadOrJoinMenu::StartMinigameServer - HostGame called (mask=0x%08X)\n", dwLocalUsersMask);
|
||||
|
||||
#ifndef _XBOX
|
||||
g_NetworkManager.FakeLocalPlayerJoined();
|
||||
#endif
|
||||
|
||||
NetworkGameInitData *param = new NetworkGameInitData();
|
||||
param->seed = 0;
|
||||
param->findSeed = true;
|
||||
param->saveData = NULL;
|
||||
param->settings = app.GetGameHostOption(eGameHostOption_All);
|
||||
param->texturePackId = pMinecraft->getCurrentTexturePackId();
|
||||
param->xzSize = LEVEL_MAX_WIDTH;
|
||||
param->hellScale = HELL_LEVEL_MAX_SCALE;
|
||||
|
||||
LoadingInputParams *loadingParams = new LoadingInputParams();
|
||||
loadingParams->func = &CGameNetworkManager::RunNetworkGameThreadProc;
|
||||
loadingParams->lpParam = (LPVOID)param;
|
||||
|
||||
app.SetAutosaveTimerTime();
|
||||
|
||||
UIFullscreenProgressCompletionData *completionData = new UIFullscreenProgressCompletionData();
|
||||
completionData->bShowBackground = TRUE;
|
||||
completionData->bShowLogo = TRUE;
|
||||
completionData->type = e_ProgressCompletion_CloseAllPlayersUIScenes;
|
||||
completionData->iPad = DEFAULT_XUI_MENU_USER;
|
||||
loadingParams->completionData = completionData;
|
||||
|
||||
ui.NavigateToScene(hostPad, eUIScene_FullscreenProgress, loadingParams);
|
||||
app.DebugPrintf("UIScene_LoadOrJoinMenu::StartMinigameServer - navigating to fullscreen progress\n");
|
||||
}
|
||||
|
||||
void UIScene_LoadOrJoinMenu::LoadLevelGen(LevelGenerationOptions *levelGen)
|
||||
{
|
||||
// Load data from disc
|
||||
|
|
@ -1610,10 +2090,13 @@ void UIScene_LoadOrJoinMenu::UpdateGamesList()
|
|||
|
||||
|
||||
FriendSessionInfo *pSelectedSession = NULL;
|
||||
if(DoesGamesListHaveFocus() && m_buttonListGames.getItemCount() > 0)
|
||||
if(DoesGamesListHaveFocus() && m_buttonListGames.getItemCount() > 0 && m_currentSessions != NULL)
|
||||
{
|
||||
unsigned int nIndex = m_buttonListGames.getCurrentSelection();
|
||||
pSelectedSession = m_currentSessions->at( nIndex );
|
||||
if(nIndex < m_currentSessions->size())
|
||||
{
|
||||
pSelectedSession = m_currentSessions->at( nIndex );
|
||||
}
|
||||
}
|
||||
|
||||
SessionID selectedSessionId;
|
||||
|
|
@ -1729,7 +2212,32 @@ void UIScene_LoadOrJoinMenu::UpdateGamesList()
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef _WINDOWS64
|
||||
wstring rowLabel = sessionInfo->displayLabel != NULL ? sessionInfo->displayLabel : L"Unknown Host";
|
||||
|
||||
int playerCount = (int)sessionInfo->data.playerCount;
|
||||
int maxPlayers = (int)sessionInfo->data.maxPlayers;
|
||||
if(maxPlayers <= 0)
|
||||
{
|
||||
maxPlayers = MINECRAFT_NET_MAX_PLAYERS;
|
||||
}
|
||||
|
||||
wchar_t sessionDetail[96];
|
||||
if(m_bMinigamesMode)
|
||||
{
|
||||
const wchar_t *minigameName = GetMinigameNameFromSettings(sessionInfo->data.m_uiGameHostSettings);
|
||||
swprintf(sessionDetail, 96, L" [%d/%d] - %ls", playerCount, maxPlayers, minigameName);
|
||||
}
|
||||
else
|
||||
{
|
||||
swprintf(sessionDetail, 96, L" [%d/%d]", playerCount, maxPlayers);
|
||||
}
|
||||
|
||||
rowLabel += sessionDetail;
|
||||
m_buttonListGames.addItem(rowLabel, textureName);
|
||||
#else
|
||||
m_buttonListGames.addItem( sessionInfo->displayLabel, textureName );
|
||||
#endif
|
||||
|
||||
if(memcmp( &selectedSessionId, &sessionInfo->sessionId, sizeof(SessionID) ) == 0)
|
||||
{
|
||||
|
|
@ -3529,3 +4037,7 @@ int UIScene_LoadOrJoinMenu::CopySaveErrorDialogFinishedCallback(void *pParam,int
|
|||
}
|
||||
|
||||
#endif // _XBOX_ONE
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -42,6 +42,15 @@ private:
|
|||
};
|
||||
eActions m_eAction;
|
||||
|
||||
enum EMinigameButtons
|
||||
{
|
||||
eMinigame_Battle = 0,
|
||||
eMinigame_Tumble,
|
||||
eMinigame_Glide,
|
||||
eMinigame_Bedwars,
|
||||
eMinigame_Count,
|
||||
};
|
||||
|
||||
static const int JOIN_LOAD_CREATE_BUTTON_INDEX = 0;
|
||||
|
||||
SaveListDetails *m_saveDetails;
|
||||
|
|
@ -85,6 +94,7 @@ private:
|
|||
bool m_bAllLoaded;
|
||||
bool m_bRetrievingSaveThumbnails;
|
||||
bool m_bSaveThumbnailReady;
|
||||
bool m_bMinigamesMode;
|
||||
bool m_bShowingPartyGamesOnly;
|
||||
bool m_bInParty;
|
||||
JoinMenuInitData *m_initData;
|
||||
|
|
@ -105,6 +115,7 @@ private:
|
|||
bool m_bSaveTransferCancelled;
|
||||
#endif
|
||||
bool m_bUpdateSaveSize;
|
||||
FriendSessionInfo *m_pDirectConnectSession;
|
||||
|
||||
public:
|
||||
UIScene_LoadOrJoinMenu(int iPad, void *initData, UILayer *parentLayer);
|
||||
|
|
@ -132,6 +143,7 @@ public:
|
|||
|
||||
private:
|
||||
void Initialise();
|
||||
void InitialiseMinigamesMode();
|
||||
void GetSaveInfo();
|
||||
void UpdateGamesList();
|
||||
void AddDefaultButtons();
|
||||
|
|
@ -153,8 +165,15 @@ public:
|
|||
static int DeleteSaveDataReturned(LPVOID lpParam,bool bRes);
|
||||
static int RenameSaveDataReturned(LPVOID lpParam,bool bRes);
|
||||
static int KeyboardCompleteWorldNameCallback(LPVOID lpParam,bool bRes);
|
||||
static int KeyboardCompleteDirectConnectCallback(LPVOID lpParam,bool bRes);
|
||||
protected:
|
||||
void handlePress(F64 controlId, F64 childId);
|
||||
void StartMinigameServer(int minigameIndex);
|
||||
void StartDirectConnectKeyboard();
|
||||
void HandleDirectConnectInput(const wchar_t *inputText);
|
||||
#ifdef _WINDOWS64
|
||||
bool ParseDirectConnectAddress(const wchar_t *inputText, char *outHostIp, size_t outHostIpSize, int &outHostPort);
|
||||
#endif
|
||||
void LoadLevelGen(LevelGenerationOptions *levelGen);
|
||||
void LoadSaveFromDisk(File *saveFile, ESavePlatform savePlatform = SAVE_FILE_PLATFORM_LOCAL);
|
||||
#if defined(__PS3__) || defined(__PSVITA__) || defined(__ORBIS__)
|
||||
|
|
|
|||
|
|
@ -2,8 +2,10 @@
|
|||
#include "..\..\..\Minecraft.World\Mth.h"
|
||||
#include "..\..\..\Minecraft.World\StringHelpers.h"
|
||||
#include "..\..\..\Minecraft.World\Random.h"
|
||||
#include "..\..\..\Minecraft.World\LevelSettings.h"
|
||||
#include "..\..\User.h"
|
||||
#include "..\..\MinecraftServer.h"
|
||||
#include "..\..\Options.h"
|
||||
#include "UI.h"
|
||||
#include "UIScene_MainMenu.h"
|
||||
#ifdef __ORBIS__
|
||||
|
|
@ -51,6 +53,7 @@ UIScene_MainMenu::UIScene_MainMenu(int iPad, void *initData, UILayer *parentLaye
|
|||
m_bTrialVersion=true;
|
||||
m_buttons[(int)eControl_UnlockOrDLC].init(app.GetString(IDS_UNLOCK_FULL_GAME),eControl_UnlockOrDLC);
|
||||
}
|
||||
m_buttons[(int)eControl_Minigames].init(L"LCE Minigames", eControl_Minigames);
|
||||
|
||||
#ifndef _DURANGO
|
||||
m_buttons[(int)eControl_Exit].init(app.GetString(IDS_EXIT_GAME),eControl_Exit);
|
||||
|
|
@ -334,6 +337,12 @@ void UIScene_MainMenu::handlePress(F64 controlId, F64 childId)
|
|||
m_eAction=eAction_RunUnlockOrDLC;
|
||||
signInReturnedFunc = &UIScene_MainMenu::UnlockFullGame_SignInReturned;
|
||||
break;
|
||||
case eControl_Minigames:
|
||||
// Launch the dedicated LCE minigames world flow.
|
||||
ui.PlayUISFX(eSFX_Press);
|
||||
m_eAction = eAction_RunMinigames;
|
||||
signInReturnedFunc = &UIScene_MainMenu::Minigames_SignInReturned;
|
||||
break;
|
||||
#if defined _XBOX
|
||||
case eControl_Exit:
|
||||
if( ProfileManager.IsFullVersion() )
|
||||
|
|
@ -400,6 +409,9 @@ void UIScene_MainMenu::RunAction(int iPad)
|
|||
case eAction_RunGame:
|
||||
RunPlayGame(iPad);
|
||||
break;
|
||||
case eAction_RunMinigames:
|
||||
RunMinigames(iPad);
|
||||
break;
|
||||
case eAction_RunLeaderboards:
|
||||
RunLeaderboards(iPad);
|
||||
break;
|
||||
|
|
@ -493,6 +505,7 @@ int UIScene_MainMenu::MustSignInReturned(void *pParam, int iPad, C4JStorage::EMe
|
|||
switch(pClass->m_eAction)
|
||||
{
|
||||
case eAction_RunGame: ProfileManager.RequestSignInUI(false, true, false, false, true, &UIScene_MainMenu::CreateLoad_SignInReturned, pClass, iPad ); break;
|
||||
case eAction_RunMinigames: ProfileManager.RequestSignInUI(false, false, true, false, true, &UIScene_MainMenu::Minigames_SignInReturned, pClass, iPad ); break;
|
||||
case eAction_RunHelpAndOptions: ProfileManager.RequestSignInUI(false, false, true, false, true, &UIScene_MainMenu::HelpAndOptions_SignInReturned, pClass, iPad ); break;
|
||||
case eAction_RunLeaderboards: ProfileManager.RequestSignInUI(false, false, true, false, true, &UIScene_MainMenu::Leaderboards_SignInReturned, pClass, iPad ); break;
|
||||
case eAction_RunAchievements: ProfileManager.RequestSignInUI(false, false, true, false, true, &UIScene_MainMenu::Achievements_SignInReturned, pClass, iPad ); break;
|
||||
|
|
@ -658,6 +671,30 @@ int UIScene_MainMenu::HelpAndOptions_SignInReturned(void *pParam,bool bContinue,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int UIScene_MainMenu::Minigames_SignInReturned(void *pParam,bool bContinue,int iPad)
|
||||
{
|
||||
UIScene_MainMenu *pClass = (UIScene_MainMenu *)pParam;
|
||||
|
||||
if(bContinue)
|
||||
{
|
||||
pClass->RunMinigames(iPad);
|
||||
}
|
||||
else
|
||||
{
|
||||
pClass->m_bIgnorePress=false;
|
||||
ProfileManager.SetLockedProfile(-1);
|
||||
for(int i=0;i<XUSER_MAX_COUNT;i++)
|
||||
{
|
||||
if(ProfileManager.IsSignedIn(i))
|
||||
{
|
||||
ProfileManager.SetCurrentGameActivity(i,CONTEXT_PRESENCE_MENUS,false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef _XBOX_ONE
|
||||
int UIScene_MainMenu::ChooseUser_SignInReturned(void *pParam, bool bContinue, int iPad)
|
||||
{
|
||||
|
|
@ -1471,6 +1508,66 @@ void UIScene_MainMenu::RunPlayGame(int iPad)
|
|||
}
|
||||
}
|
||||
|
||||
void UIScene_MainMenu::RunMinigames(int iPad)
|
||||
{
|
||||
app.DebugPrintf("UIScene_MainMenu::RunMinigames - requested by pad %d\n", iPad);
|
||||
|
||||
int hostPad = iPad;
|
||||
if(hostPad < 0 || !ProfileManager.IsSignedIn(hostPad))
|
||||
{
|
||||
hostPad = ProfileManager.GetPrimaryPad();
|
||||
}
|
||||
|
||||
UINT uiIDA[1];
|
||||
uiIDA[0]=IDS_OK;
|
||||
|
||||
if(hostPad < 0)
|
||||
{
|
||||
m_bIgnorePress=false;
|
||||
ui.RequestMessageBox(IDS_MUST_SIGN_IN_TITLE, IDS_MUST_SIGN_IN_TEXT, uiIDA, 1, iPad, NULL, NULL, app.GetStringTable());
|
||||
return;
|
||||
}
|
||||
|
||||
if(ProfileManager.IsGuest(hostPad))
|
||||
{
|
||||
m_bIgnorePress=false;
|
||||
ui.RequestMessageBox(IDS_PRO_GUESTPROFILE_TITLE, IDS_PRO_GUESTPROFILE_TEXT, uiIDA, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
bool isClientSide = ProfileManager.IsSignedInLive(hostPad);
|
||||
#ifdef __PSVITA__
|
||||
if(app.GetGameSettings(ProfileManager.GetPrimaryPad(),eGameSetting_PSVita_NetworkModeAdhoc) == true)
|
||||
{
|
||||
CGameNetworkManager::setAdhocMode(true);
|
||||
isClientSide = SQRNetworkManager_AdHoc_Vita::GetAdhocStatus();
|
||||
}
|
||||
else
|
||||
{
|
||||
CGameNetworkManager::setAdhocMode(false);
|
||||
}
|
||||
#endif
|
||||
|
||||
if(!isClientSide)
|
||||
{
|
||||
m_bIgnorePress=false;
|
||||
ui.RequestMessageBox(IDS_PRO_NOTONLINE_TITLE, IDS_PRO_NOTONLINE_TEXT, uiIDA, 1, hostPad, NULL, NULL, app.GetStringTable());
|
||||
return;
|
||||
}
|
||||
|
||||
ProfileManager.SetLockedProfile(hostPad);
|
||||
ProfileManager.QuerySigninStatus();
|
||||
|
||||
Minecraft *pMinecraft = Minecraft::GetInstance();
|
||||
pMinecraft->user->name = convStringToWstring(ProfileManager.GetGamertag(ProfileManager.GetPrimaryPad()));
|
||||
app.ApplyGameSettingsChanged(hostPad);
|
||||
|
||||
LoadOrJoinMenuInitData *params = new LoadOrJoinMenuInitData();
|
||||
params->bMinigamesMode = TRUE;
|
||||
app.DebugPrintf("UIScene_MainMenu::RunMinigames - navigating to LoadOrJoin minigames hub (hostPad=%d)\n", hostPad);
|
||||
ui.NavigateToScene(hostPad, eUIScene_LoadOrJoinMenu, params);
|
||||
}
|
||||
|
||||
void UIScene_MainMenu::RunLeaderboards(int iPad)
|
||||
{
|
||||
UINT uiIDA[1];
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ private:
|
|||
enum EControls
|
||||
{
|
||||
eControl_PlayGame,
|
||||
eControl_Minigames,
|
||||
eControl_Leaderboards,
|
||||
eControl_Achievements,
|
||||
eControl_HelpAndOptions,
|
||||
|
|
@ -33,14 +34,15 @@ private:
|
|||
UIControl m_controlTimer;
|
||||
UI_BEGIN_MAP_ELEMENTS_AND_NAMES(UIScene)
|
||||
UI_MAP_ELEMENT( m_buttons[(int)eControl_PlayGame], "Button1")
|
||||
UI_MAP_ELEMENT( m_buttons[(int)eControl_Leaderboards], "Button2")
|
||||
UI_MAP_ELEMENT( m_buttons[(int)eControl_Achievements], "Button3")
|
||||
UI_MAP_ELEMENT( m_buttons[(int)eControl_HelpAndOptions], "Button4")
|
||||
UI_MAP_ELEMENT( m_buttons[(int)eControl_UnlockOrDLC], "Button5")
|
||||
UI_MAP_ELEMENT( m_buttons[(int)eControl_Minigames], "Button2")
|
||||
UI_MAP_ELEMENT( m_buttons[(int)eControl_Leaderboards], "Button3")
|
||||
UI_MAP_ELEMENT( m_buttons[(int)eControl_Achievements], "Button4")
|
||||
UI_MAP_ELEMENT( m_buttons[(int)eControl_HelpAndOptions], "Button5")
|
||||
UI_MAP_ELEMENT( m_buttons[(int)eControl_UnlockOrDLC], "Button6")
|
||||
#ifndef _DURANGO
|
||||
UI_MAP_ELEMENT( m_buttons[(int)eControl_Exit], "Button6")
|
||||
UI_MAP_ELEMENT( m_buttons[(int)eControl_Exit], "Button7")
|
||||
#else
|
||||
UI_MAP_ELEMENT( m_buttons[(int)eControl_XboxHelp], "Button6")
|
||||
UI_MAP_ELEMENT( m_buttons[(int)eControl_XboxHelp], "Button7")
|
||||
#endif
|
||||
UI_MAP_ELEMENT( m_controlTimer, "Timer")
|
||||
UI_END_MAP_ELEMENTS_AND_NAMES()
|
||||
|
|
@ -76,6 +78,7 @@ private:
|
|||
{
|
||||
eAction_None=0,
|
||||
eAction_RunGame,
|
||||
eAction_RunMinigames,
|
||||
eAction_RunLeaderboards,
|
||||
eAction_RunAchievements,
|
||||
eAction_RunHelpAndOptions,
|
||||
|
|
@ -127,6 +130,7 @@ protected:
|
|||
|
||||
private:
|
||||
void RunPlayGame(int iPad);
|
||||
void RunMinigames(int iPad);
|
||||
void RunLeaderboards(int iPad);
|
||||
void RunUnlockOrDLC(int iPad);
|
||||
void RunAchievements(int iPad);
|
||||
|
|
@ -141,6 +145,7 @@ private:
|
|||
#endif
|
||||
static int CreateLoad_SignInReturned(void *pParam,bool bContinue, int iPad);
|
||||
static int HelpAndOptions_SignInReturned(void *pParam,bool bContinue,int iPad);
|
||||
static int Minigames_SignInReturned(void *pParam,bool bContinue,int iPad);
|
||||
static int Achievements_SignInReturned(void *pParam,bool bContinue,int iPad);
|
||||
static int MustSignInReturned(void *pParam,int iPad,C4JStorage::EMessageResult result);
|
||||
|
||||
|
|
|
|||
|
|
@ -216,6 +216,19 @@ typedef struct _SaveListDetails
|
|||
|
||||
} SaveListDetails;
|
||||
|
||||
#define LOAD_OR_JOIN_MENU_INIT_MAGIC 0x4C4F4A4D
|
||||
typedef struct _LoadOrJoinMenuInitData
|
||||
{
|
||||
DWORD magic;
|
||||
BOOL bMinigamesMode;
|
||||
|
||||
_LoadOrJoinMenuInitData()
|
||||
{
|
||||
magic = LOAD_OR_JOIN_MENU_INIT_MAGIC;
|
||||
bMinigamesMode = FALSE;
|
||||
}
|
||||
} LoadOrJoinMenuInitData;
|
||||
|
||||
// Load world
|
||||
typedef struct _LoadMenuInitData
|
||||
{
|
||||
|
|
|
|||
|
|
@ -6,6 +6,9 @@
|
|||
#include <assert.h>
|
||||
#include "..\..\Minecraft.h"
|
||||
#include "..\..\..\Minecraft.World\DisconnectPacket.h"
|
||||
#ifdef _WINDOWS64
|
||||
#include "..\Network\PlatformNetworkManagerStub.h"
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Performs initialization tasks - retrieves controls.
|
||||
|
|
@ -144,6 +147,15 @@ HRESULT CScene_ConnectingProgress::OnTimer( XUIMessageTimer *pTimer, BOOL& bHand
|
|||
// Check if the connection failed
|
||||
Minecraft *pMinecraft = Minecraft::GetInstance();
|
||||
|
||||
#ifdef _WINDOWS64
|
||||
if (CPlatformNetworkManagerStub::IsServerTransferInProgress())
|
||||
{
|
||||
pMinecraft->m_connectionFailed[m_iPad] = false;
|
||||
pMinecraft->m_connectionFailedReason[m_iPad] = DisconnectPacket::eDisconnect_None;
|
||||
return S_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
if( pMinecraft->m_connectionFailed[m_iPad] || !g_NetworkManager.IsInSession() )
|
||||
{
|
||||
app.RemoveBackScene(m_iPad);
|
||||
|
|
|
|||
|
|
@ -14,10 +14,12 @@
|
|||
//#include "XUI_CreateLoad.h"
|
||||
#include "..\..\..\Minecraft.World\StringHelpers.h"
|
||||
#include "..\..\..\Minecraft.World\Random.h"
|
||||
#include "..\..\..\Minecraft.World\LevelSettings.h"
|
||||
#include "..\..\MinecraftServer.h"
|
||||
#include "..\..\Minecraft.h"
|
||||
#include "..\..\Options.h"
|
||||
#include "..\..\Font.h"
|
||||
#include "..\UI\UIStructs.h"
|
||||
#include "..\..\Common\GameRules\ConsoleGameRules.h"
|
||||
|
||||
#define DLC_INSTALLED_TIMER_ID 1
|
||||
|
|
@ -38,6 +40,7 @@ HRESULT CScene_Main::OnInit( XUIMessageInit* pInitData, BOOL& bHandled )
|
|||
XuiControlSetText(m_Buttons[BUTTON_ACHIEVEMENTS],app.GetString(IDS_ACHIEVEMENTS));
|
||||
XuiControlSetText(m_Buttons[BUTTON_HELPANDOPTIONS],app.GetString(IDS_HELP_AND_OPTIONS));
|
||||
XuiControlSetText(m_Buttons[BUTTON_UNLOCKFULLGAME],app.GetString(IDS_UNLOCK_FULL_GAME));
|
||||
XuiControlSetText(m_Buttons[BUTTON_MINIGAMES],L"LCE Minigames");
|
||||
XuiControlSetText(m_Buttons[BUTTON_EXITGAME],app.GetString(IDS_EXIT_GAME));
|
||||
|
||||
m_Timer.SetShow(FALSE);
|
||||
|
|
@ -261,6 +264,20 @@ HRESULT CScene_Main::OnNotifyPressEx(HXUIOBJ hObjPressed, XUINotifyPress* pNotif
|
|||
}
|
||||
}
|
||||
break;
|
||||
case BUTTON_MINIGAMES:
|
||||
m_eAction = eAction_RunMinigames;
|
||||
if(ProfileManager.IsSignedIn(pNotifyPressData->UserIndex))
|
||||
{
|
||||
RunMinigames(pNotifyPressData->UserIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
UINT uiIDA[2];
|
||||
uiIDA[0]=IDS_CONFIRM_OK;
|
||||
uiIDA[1]=IDS_CONFIRM_CANCEL;
|
||||
StorageManager.RequestMessageBox(IDS_MUST_SIGN_IN_TITLE, IDS_MUST_SIGN_IN_TEXT, uiIDA, 2, pNotifyPressData->UserIndex,&CScene_Main::MustSignInReturned,this, app.GetStringTable());
|
||||
}
|
||||
break;
|
||||
case BUTTON_EXITGAME:
|
||||
if( ProfileManager.IsFullVersion() )
|
||||
{
|
||||
|
|
@ -672,6 +689,9 @@ int CScene_Main::MustSignInReturned(void *pParam,int iPad,C4JStorage::EMessageRe
|
|||
case eAction_RunGame:
|
||||
ProfileManager.RequestSignInUI(false, true, false,false,true,&CScene_Main::CreateLoad_SignInReturned,pClass ,iPad);
|
||||
break;
|
||||
case eAction_RunMinigames:
|
||||
ProfileManager.RequestSignInUI(false, false, true,false,true,&CScene_Main::Minigames_SignInReturned,pClass,iPad );
|
||||
break;
|
||||
case eAction_RunLeaderboards:
|
||||
ProfileManager.RequestSignInUI(false, false, true,false,true, &CScene_Main::Leaderboards_SignInReturned, pClass,iPad);
|
||||
break;
|
||||
|
|
@ -704,6 +724,29 @@ int CScene_Main::MustSignInReturned(void *pParam,int iPad,C4JStorage::EMessageRe
|
|||
return 0;
|
||||
}
|
||||
|
||||
int CScene_Main::Minigames_SignInReturned(void *pParam,bool bContinue,int iPad)
|
||||
{
|
||||
CScene_Main* pClass = (CScene_Main*)pParam;
|
||||
|
||||
if(bContinue==true)
|
||||
{
|
||||
pClass->RunMinigames(iPad);
|
||||
}
|
||||
else
|
||||
{
|
||||
ProfileManager.SetLockedProfile(-1);
|
||||
for(int i=0;i<XUSER_MAX_COUNT;i++)
|
||||
{
|
||||
if(ProfileManager.IsSignedIn(i))
|
||||
{
|
||||
ProfileManager.SetCurrentGameActivity(i,CONTEXT_PRESENCE_MENUS,false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -1031,6 +1074,50 @@ void CScene_Main::RunPlayGame(int iPad)
|
|||
}
|
||||
}
|
||||
|
||||
void CScene_Main::RunMinigames(int iPad)
|
||||
{
|
||||
app.DebugPrintf("CScene_Main::RunMinigames - requested by pad %d\n", iPad);
|
||||
|
||||
int hostPad = iPad;
|
||||
if(hostPad < 0 || !ProfileManager.IsSignedIn(hostPad))
|
||||
{
|
||||
hostPad = ProfileManager.GetPrimaryPad();
|
||||
}
|
||||
|
||||
UINT uiIDA[1];
|
||||
uiIDA[0]=IDS_OK;
|
||||
|
||||
if(hostPad < 0)
|
||||
{
|
||||
StorageManager.RequestMessageBox(IDS_MUST_SIGN_IN_TITLE, IDS_MUST_SIGN_IN_TEXT, uiIDA, 1, iPad, NULL, NULL, app.GetStringTable());
|
||||
return;
|
||||
}
|
||||
|
||||
if(ProfileManager.IsGuest(hostPad))
|
||||
{
|
||||
StorageManager.RequestMessageBox(IDS_PRO_GUESTPROFILE_TITLE, IDS_PRO_GUESTPROFILE_TEXT, uiIDA, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
if(!ProfileManager.IsSignedInLive(hostPad))
|
||||
{
|
||||
StorageManager.RequestMessageBox(IDS_PRO_NOTONLINE_TITLE, IDS_PRO_NOTONLINE_TEXT, uiIDA, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
ProfileManager.SetLockedProfile(hostPad);
|
||||
ProfileManager.QuerySigninStatus();
|
||||
|
||||
Minecraft *pMinecraft=Minecraft::GetInstance();
|
||||
pMinecraft->user->name = convStringToWstring(ProfileManager.GetGamertag(ProfileManager.GetPrimaryPad()));
|
||||
app.ApplyGameSettingsChanged(hostPad);
|
||||
|
||||
LoadOrJoinMenuInitData *params = new LoadOrJoinMenuInitData();
|
||||
params->bMinigamesMode = TRUE;
|
||||
app.DebugPrintf("CScene_Main::RunMinigames - navigating to LoadOrJoin minigames hub (hostPad=%d)\n", hostPad);
|
||||
app.NavigateToScene(hostPad, eUIScene_LoadOrJoinMenu, params);
|
||||
}
|
||||
|
||||
HRESULT CScene_Main::OnTMSBanFileRetrieved()
|
||||
{
|
||||
Minecraft *pMinecraft=Minecraft::GetInstance();
|
||||
|
|
@ -1285,4 +1372,4 @@ HRESULT CScene_Main::OnTimer( XUIMessageTimer *pTimer, BOOL& bHandled )
|
|||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,11 +4,12 @@
|
|||
#include "XUI_CustomMessages.h"
|
||||
|
||||
#define BUTTON_PLAYGAME 0
|
||||
#define BUTTON_LEADERBOARDS 1
|
||||
#define BUTTON_ACHIEVEMENTS 2
|
||||
#define BUTTON_HELPANDOPTIONS 3
|
||||
#define BUTTON_UNLOCKFULLGAME 4
|
||||
#define BUTTON_EXITGAME 5
|
||||
#define BUTTON_MINIGAMES 1
|
||||
#define BUTTON_LEADERBOARDS 2
|
||||
#define BUTTON_ACHIEVEMENTS 3
|
||||
#define BUTTON_HELPANDOPTIONS 4
|
||||
#define BUTTON_UNLOCKFULLGAME 5
|
||||
#define BUTTON_EXITGAME 6
|
||||
#define BUTTONS_MAX BUTTON_EXITGAME + 1
|
||||
|
||||
#define MAIN_MENU_MAX_TEXT_SCALE 1.5f
|
||||
|
|
@ -41,6 +42,7 @@ private:
|
|||
{
|
||||
eAction_None=0,
|
||||
eAction_RunGame,
|
||||
eAction_RunMinigames,
|
||||
eAction_RunLeaderboards,
|
||||
eAction_RunAchievements,
|
||||
eAction_RunHelpAndOptions,
|
||||
|
|
@ -70,11 +72,12 @@ protected:
|
|||
// Control mapping to objects
|
||||
BEGIN_CONTROL_MAP()
|
||||
MAP_CONTROL(IDC_XuiButton1, m_Buttons[BUTTON_PLAYGAME])
|
||||
MAP_CONTROL(IDC_XuiButton2, m_Buttons[BUTTON_LEADERBOARDS ])
|
||||
MAP_CONTROL(IDC_XuiButton3, m_Buttons[BUTTON_ACHIEVEMENTS ])
|
||||
MAP_CONTROL(IDC_XuiButton4, m_Buttons[BUTTON_HELPANDOPTIONS])
|
||||
MAP_CONTROL(IDC_XuiButton5, m_Buttons[BUTTON_UNLOCKFULLGAME])
|
||||
MAP_CONTROL(IDC_XuiButton6, m_Buttons[BUTTON_EXITGAME])
|
||||
MAP_CONTROL(IDC_XuiButton2, m_Buttons[BUTTON_MINIGAMES])
|
||||
MAP_CONTROL(IDC_XuiButton3, m_Buttons[BUTTON_LEADERBOARDS ])
|
||||
MAP_CONTROL(IDC_XuiButton4, m_Buttons[BUTTON_ACHIEVEMENTS ])
|
||||
MAP_CONTROL(IDC_XuiButton5, m_Buttons[BUTTON_HELPANDOPTIONS])
|
||||
MAP_CONTROL(IDC_XuiButton6, m_Buttons[BUTTON_UNLOCKFULLGAME])
|
||||
MAP_CONTROL(IDC_XuiButton7, m_Buttons[BUTTON_EXITGAME])
|
||||
MAP_CONTROL(IDC_XuiSplash, m_Subtitle)
|
||||
MAP_CONTROL(IDC_XuiSplashMCFont, m_SubtitleMCFont)
|
||||
MAP_CONTROL(IDC_Timer, m_Timer)
|
||||
|
|
@ -95,6 +98,7 @@ protected:
|
|||
static void LoadTrial();
|
||||
|
||||
void RunPlayGame(int iPad);
|
||||
void RunMinigames(int iPad);
|
||||
void RunLeaderboards(int iPad);
|
||||
void RunAchievements(int iPad);
|
||||
void RunHelpAndOptions(int iPad);
|
||||
|
|
@ -114,6 +118,7 @@ public:
|
|||
static int DeviceSelectReturned(void *pParam,bool bContinue);
|
||||
static int SaveGameReturned(void *pParam,bool bContinue);
|
||||
static int HelpAndOptions_SignInReturned(void *pParam,bool bContinue,int iPad);
|
||||
static int Minigames_SignInReturned(void *pParam,bool bContinue,int iPad);
|
||||
static int ExitGameReturned(void *pParam,int iPad,C4JStorage::EMessageResult result);
|
||||
static int AchievementsDeviceSelectReturned(void *pParam,bool bContinue);
|
||||
static int Achievements_SignInReturned(void *pParam,bool bContinue,int iPad);
|
||||
|
|
|
|||
|
|
@ -168,7 +168,7 @@ void PIXSetMarkerDeprecated(int a, char *b, ...) {}
|
|||
|
||||
bool IsEqualXUID(PlayerUID a, PlayerUID b)
|
||||
{
|
||||
#if defined(__PS3__) || defined(__ORBIS__) || defined (__PSVITA__) || defined(_DURANGO)
|
||||
#if defined(__PS3__) || defined(__ORBIS__) || defined (__PSVITA__) || defined(_DURANGO) || defined(_WINDOWS64)
|
||||
return (a == b);
|
||||
#else
|
||||
return false;
|
||||
|
|
@ -187,6 +187,8 @@ D3DXVECTOR3& D3DXVECTOR3::operator += ( CONST D3DXVECTOR3& add ) { x += add.x; y
|
|||
|
||||
#include "Windows64\Network\WinsockNetLayer.h"
|
||||
|
||||
extern bool g_Win64DedicatedServerMode;
|
||||
|
||||
BYTE IQNetPlayer::GetSmallId() { return m_smallId; }
|
||||
void IQNetPlayer::SendData(IQNetPlayer *player, const void *pvData, DWORD dwDataSize, DWORD dwFlags)
|
||||
{
|
||||
|
|
@ -195,7 +197,14 @@ void IQNetPlayer::SendData(IQNetPlayer *player, const void *pvData, DWORD dwData
|
|||
WinsockNetLayer::SendToSmallId(player->m_smallId, pvData, dwDataSize);
|
||||
}
|
||||
}
|
||||
bool IQNetPlayer::IsSameSystem(IQNetPlayer *player) { return (this == player) || (!m_isRemote && !player->m_isRemote); }
|
||||
bool IQNetPlayer::IsSameSystem(IQNetPlayer *player)
|
||||
{
|
||||
if (player == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return (this == player) || (!m_isRemote && !player->m_isRemote);
|
||||
}
|
||||
DWORD IQNetPlayer::GetSendQueueSize( IQNetPlayer *player, DWORD dwFlags ) { return 0; }
|
||||
DWORD IQNetPlayer::GetCurrentRtt() { return 0; }
|
||||
bool IQNetPlayer::IsHost() { return m_isHostPlayer; }
|
||||
|
|
@ -232,13 +241,17 @@ void Win64_SetupRemoteQNetPlayer(IQNetPlayer *player, BYTE smallId, bool isHost,
|
|||
IQNet::s_playerCount = smallId + 1;
|
||||
}
|
||||
|
||||
static bool Win64_IsActivePlayer(IQNetPlayer *p, DWORD index);
|
||||
|
||||
HRESULT IQNet::AddLocalPlayerByUserIndex(DWORD dwUserIndex){ return S_OK; }
|
||||
IQNetPlayer *IQNet::GetHostPlayer() { return &m_player[0]; }
|
||||
IQNetPlayer *IQNet::GetLocalPlayerByUserIndex(DWORD dwUserIndex)
|
||||
{
|
||||
if (s_isHosting)
|
||||
{
|
||||
if (dwUserIndex < MINECRAFT_NET_MAX_PLAYERS && !m_player[dwUserIndex].m_isRemote)
|
||||
if (dwUserIndex < MINECRAFT_NET_MAX_PLAYERS &&
|
||||
!m_player[dwUserIndex].m_isRemote &&
|
||||
Win64_IsActivePlayer(&m_player[dwUserIndex], dwUserIndex))
|
||||
return &m_player[dwUserIndex];
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -246,14 +259,20 @@ IQNetPlayer *IQNet::GetLocalPlayerByUserIndex(DWORD dwUserIndex)
|
|||
return NULL;
|
||||
for (DWORD i = 0; i < s_playerCount; i++)
|
||||
{
|
||||
if (!m_player[i].m_isRemote)
|
||||
if (!m_player[i].m_isRemote && Win64_IsActivePlayer(&m_player[i], i))
|
||||
return &m_player[i];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
static bool Win64_IsActivePlayer(IQNetPlayer *p, DWORD index)
|
||||
{
|
||||
if (index == 0) return true;
|
||||
if (index == 0)
|
||||
{
|
||||
// Keep host slot active for index/session-id consistency in server queue logic.
|
||||
// Dedicated mode suppresses host "player count" through advertising logic instead.
|
||||
(void)g_Win64DedicatedServerMode;
|
||||
return true;
|
||||
}
|
||||
return (p->GetCustomDataValue() != 0);
|
||||
}
|
||||
|
||||
|
|
@ -272,19 +291,24 @@ IQNetPlayer *IQNet::GetPlayerByIndex(DWORD dwPlayerIndex)
|
|||
}
|
||||
IQNetPlayer *IQNet::GetPlayerBySmallId(BYTE SmallId)
|
||||
{
|
||||
for (DWORD i = 0; i < s_playerCount; i++)
|
||||
{
|
||||
if (m_player[i].m_smallId == SmallId && Win64_IsActivePlayer(&m_player[i], i)) return &m_player[i];
|
||||
}
|
||||
return NULL;
|
||||
if (SmallId >= MINECRAFT_NET_MAX_PLAYERS)
|
||||
return NULL;
|
||||
|
||||
// On Win64 LAN, clients can receive packets for a newly-joined higher smallId
|
||||
// before local span bookkeeping catches up (e.g. local smallId=1 receiving smallId=2).
|
||||
// Always provide the slot and grow the span so downstream code can materialize it.
|
||||
m_player[SmallId].m_smallId = SmallId;
|
||||
if (SmallId >= s_playerCount)
|
||||
s_playerCount = SmallId + 1;
|
||||
return &m_player[SmallId];
|
||||
}
|
||||
IQNetPlayer *IQNet::GetPlayerByXuid(PlayerUID xuid)
|
||||
{
|
||||
for (DWORD i = 0; i < s_playerCount; i++)
|
||||
for (DWORD i = 0; i < MINECRAFT_NET_MAX_PLAYERS; i++)
|
||||
{
|
||||
if (Win64_IsActivePlayer(&m_player[i], i) && m_player[i].GetXuid() == xuid) return &m_player[i];
|
||||
}
|
||||
return &m_player[0];
|
||||
return NULL;
|
||||
}
|
||||
DWORD IQNet::GetPlayerCount()
|
||||
{
|
||||
|
|
@ -299,15 +323,29 @@ QNET_STATE IQNet::GetState() { return _iQNetStubState; }
|
|||
bool IQNet::IsHost() { return s_isHosting; }
|
||||
HRESULT IQNet::JoinGameFromInviteInfo(DWORD dwUserIndex, DWORD dwUserMask, const INVITE_INFO *pInviteInfo) { return S_OK; }
|
||||
void IQNet::HostGame() { _iQNetStubState = QNET_STATE_SESSION_STARTING; s_isHosting = true; }
|
||||
void IQNet::ClientJoinGame() { _iQNetStubState = QNET_STATE_SESSION_STARTING; s_isHosting = false; }
|
||||
void IQNet::ClientJoinGame()
|
||||
{
|
||||
_iQNetStubState = QNET_STATE_SESSION_STARTING;
|
||||
s_isHosting = false;
|
||||
|
||||
// Reset all slots so no stale network-player pointers survive between sessions.
|
||||
for (int i = 0; i < MINECRAFT_NET_MAX_PLAYERS; i++)
|
||||
{
|
||||
m_player[i].m_smallId = (BYTE)i;
|
||||
m_player[i].m_isRemote = true;
|
||||
m_player[i].m_isHostPlayer = false;
|
||||
m_player[i].m_gamertag[0] = 0;
|
||||
m_player[i].SetCustomDataValue(0);
|
||||
}
|
||||
}
|
||||
void IQNet::EndGame()
|
||||
{
|
||||
_iQNetStubState = QNET_STATE_IDLE;
|
||||
s_isHosting = false;
|
||||
s_playerCount = 1;
|
||||
for (int i = 1; i < MINECRAFT_NET_MAX_PLAYERS; i++)
|
||||
for (int i = 0; i < MINECRAFT_NET_MAX_PLAYERS; i++)
|
||||
{
|
||||
m_player[i].m_smallId = 0;
|
||||
m_player[i].m_smallId = (BYTE)i;
|
||||
m_player[i].m_isRemote = false;
|
||||
m_player[i].m_isHostPlayer = false;
|
||||
m_player[i].m_gamertag[0] = 0;
|
||||
|
|
|
|||
|
|
@ -48,6 +48,9 @@
|
|||
|
||||
#include "TexturePackRepository.h"
|
||||
#include "TexturePack.h"
|
||||
#ifdef _WINDOWS64
|
||||
#include "Common\Network\PlatformNetworkManagerStub.h"
|
||||
#endif
|
||||
|
||||
bool GameRenderer::anaglyph3d = false;
|
||||
int GameRenderer::anaglyphPass = 0;
|
||||
|
|
@ -1164,6 +1167,26 @@ int GameRenderer::runUpdate(LPVOID lpParam)
|
|||
|
||||
m_updateEvents->Set(eUpdateCanRun);
|
||||
|
||||
#ifdef _WINDOWS64
|
||||
// Cross-server transfer can overlap old-level teardown and new-level connect.
|
||||
// Do not touch chunk rebuild queues in this transition window.
|
||||
if (CPlatformNetworkManagerStub::IsServerTransferInProgress())
|
||||
{
|
||||
RenderManager.CBuffDeferredModeEnd();
|
||||
m_updateEvents->Set(eUpdateEventIsFinished);
|
||||
Sleep(1);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (minecraft == NULL || minecraft->levelRenderer == NULL || minecraft->level == NULL)
|
||||
{
|
||||
RenderManager.CBuffDeferredModeEnd();
|
||||
m_updateEvents->Set(eUpdateEventIsFinished);
|
||||
Sleep(1);
|
||||
continue;
|
||||
}
|
||||
|
||||
// PIXBeginNamedEvent(0,"Updating dirty chunks %d",(count++)&7);
|
||||
|
||||
// Update chunks atomically until there aren't any very near ones left - they will be deferred for rendering
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@
|
|||
#include "..\Minecraft.World\net.minecraft.world.h"
|
||||
#include "..\Minecraft.World\LevelChunk.h"
|
||||
#include "..\Minecraft.World\Biome.h"
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
|
||||
#define RENDER_HUD 0
|
||||
//#ifndef _XBOX
|
||||
|
|
@ -34,6 +36,50 @@
|
|||
//#define RENDER_HUD 1
|
||||
//#endif
|
||||
|
||||
namespace
|
||||
{
|
||||
const unsigned int MINIGAME_SETTINGS_FLAG = 0x80000000u;
|
||||
const unsigned int MINIGAME_SETTINGS_TYPE_MASK = 0x70000000u;
|
||||
const unsigned int MINIGAME_SETTINGS_TYPE_SHIFT = 28u;
|
||||
const unsigned int MINIGAME_SETTINGS_ROLE_MASK = 0x0C000000u;
|
||||
const unsigned int MINIGAME_SETTINGS_ROLE_SHIFT = 26u;
|
||||
const unsigned int MINIGAME_SETTINGS_QUEUE_MASK = 0x03000000u;
|
||||
const unsigned int MINIGAME_SETTINGS_QUEUE_SHIFT = 24u;
|
||||
const unsigned int MINIGAME_TYPE_BEDWARS = 3u;
|
||||
const unsigned int MINIGAME_ROLE_HUB = 0u;
|
||||
|
||||
struct BedwarsHudRow
|
||||
{
|
||||
wstring name;
|
||||
int health;
|
||||
int distanceBlocks;
|
||||
bool isSelf;
|
||||
};
|
||||
|
||||
bool IsBedwarsSettings(unsigned int hostSettings)
|
||||
{
|
||||
if ((hostSettings & MINIGAME_SETTINGS_FLAG) == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
const unsigned int minigameType = (hostSettings & MINIGAME_SETTINGS_TYPE_MASK) >> MINIGAME_SETTINGS_TYPE_SHIFT;
|
||||
return (minigameType == MINIGAME_TYPE_BEDWARS);
|
||||
}
|
||||
|
||||
wstring GetBedwarsQueueLabel(unsigned int hostSettings)
|
||||
{
|
||||
const unsigned int queueMode = (hostSettings & MINIGAME_SETTINGS_QUEUE_MASK) >> MINIGAME_SETTINGS_QUEUE_SHIFT;
|
||||
switch (queueMode)
|
||||
{
|
||||
case 0u: return L"Solo";
|
||||
case 1u: return L"Doubles";
|
||||
case 2u: return L"Squads";
|
||||
case 3u: return L"Practice";
|
||||
default: return L"Unknown";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float Gui::currentGuiBlendFactor = 1.0f; // 4J added
|
||||
float Gui::currentGuiScaleFactor = 1.0f; // 4J added
|
||||
ItemRenderer *Gui::itemRenderer = new ItemRenderer();
|
||||
|
|
@ -735,6 +781,91 @@ void Gui::render(float a, bool mouseFree, int xMouse, int yMouse)
|
|||
glDisable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
// Bedwars party/status panel (mid-right)
|
||||
if (bDisplayGui && !bTwoPlayerSplitscreen && minecraft->level != NULL && minecraft->player != NULL)
|
||||
{
|
||||
const unsigned int hostSettings = app.GetGameHostOption(eGameHostOption_All);
|
||||
if (IsBedwarsSettings(hostSettings))
|
||||
{
|
||||
vector<BedwarsHudRow> rows;
|
||||
rows.reserve(minecraft->level->players.size());
|
||||
|
||||
for (AUTO_VAR(itP, minecraft->level->players.begin()); itP != minecraft->level->players.end(); ++itP)
|
||||
{
|
||||
shared_ptr<Player> p = *itP;
|
||||
if (p == NULL)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
BedwarsHudRow row;
|
||||
row.name = p->displayName.empty() ? p->name : p->displayName;
|
||||
row.health = p->getHealth();
|
||||
const double dx = p->x - minecraft->player->x;
|
||||
const double dy = p->y - minecraft->player->y;
|
||||
const double dz = p->z - minecraft->player->z;
|
||||
row.distanceBlocks = (int)std::sqrt(dx * dx + dy * dy + dz * dz);
|
||||
row.isSelf = (p.get() == minecraft->player.get());
|
||||
rows.push_back(row);
|
||||
}
|
||||
|
||||
std::sort(rows.begin(), rows.end(), [](const BedwarsHudRow &a, const BedwarsHudRow &b)
|
||||
{
|
||||
if (a.isSelf != b.isSelf)
|
||||
{
|
||||
return a.isSelf;
|
||||
}
|
||||
if (a.distanceBlocks != b.distanceBlocks)
|
||||
{
|
||||
return a.distanceBlocks < b.distanceBlocks;
|
||||
}
|
||||
return a.name < b.name;
|
||||
});
|
||||
|
||||
const int shownCount = (int)std::min<size_t>(rows.size(), 6);
|
||||
const int panelWidth = 144;
|
||||
const int headerHeight = 12;
|
||||
const int lineHeight = 9;
|
||||
const int bodyTop = headerHeight + 12;
|
||||
const int bodyHeight = shownCount * lineHeight;
|
||||
const int footerHeight = 10;
|
||||
const int panelHeight = bodyTop + bodyHeight + footerHeight;
|
||||
const int panelX = screenWidth - panelWidth - 2;
|
||||
const int panelY = (screenHeight / 2) - (panelHeight / 2);
|
||||
|
||||
fill(panelX - 1, panelY - 1, panelX + panelWidth + 1, panelY + panelHeight + 1, 0xA0101010);
|
||||
fill(panelX, panelY, panelX + panelWidth, panelY + headerHeight, 0xB0303030);
|
||||
fill(panelX, panelY + headerHeight, panelX + panelWidth, panelY + panelHeight, 0x70101010);
|
||||
|
||||
drawString(font, L"Party", panelX + 3, panelY + 2, 0x55FFFF);
|
||||
|
||||
const bool isHubRole = (((hostSettings & MINIGAME_SETTINGS_ROLE_MASK) >> MINIGAME_SETTINGS_ROLE_SHIFT) == MINIGAME_ROLE_HUB);
|
||||
const wstring modeText = isHubRole ? L"Hub" : L"Match";
|
||||
const wstring queueText = GetBedwarsQueueLabel(hostSettings);
|
||||
wchar_t infoLine[96];
|
||||
swprintf_s(infoLine, L"%ls | %ls | %d online", modeText.c_str(), queueText.c_str(), (int)rows.size());
|
||||
drawString(font, infoLine, panelX + 3, panelY + headerHeight + 1, 0xCFCFCF);
|
||||
|
||||
for (int i = 0; i < shownCount; ++i)
|
||||
{
|
||||
const BedwarsHudRow &r = rows[(size_t)i];
|
||||
const int y = panelY + bodyTop + i * lineHeight;
|
||||
const int nameColor = r.isSelf ? 0xFFFF55 : 0xE0E0E0;
|
||||
drawString(font, r.name, panelX + 3, y, nameColor);
|
||||
|
||||
wchar_t rightText[48];
|
||||
const int clampedHp = (r.health < 0) ? 0 : r.health;
|
||||
swprintf_s(rightText, L"%dHP %dm", clampedHp, r.distanceBlocks);
|
||||
int hpColor = 0x55FF55;
|
||||
if (clampedHp <= 10) hpColor = 0xFFAA55;
|
||||
if (clampedHp <= 4) hpColor = 0xFF5555;
|
||||
drawString(font, rightText, panelX + panelWidth - font->width(rightText) - 3, y, hpColor);
|
||||
}
|
||||
|
||||
drawString(font, L"/party /queue", panelX + 3, panelY + panelHeight - 9, 0x909090);
|
||||
}
|
||||
}
|
||||
|
||||
// if the player is falling asleep we render a dark overlay
|
||||
if (minecraft->player->getSleepTimer() > 0)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ Input::Input()
|
|||
wasJumping = false;
|
||||
jumping = false;
|
||||
sneaking = false;
|
||||
sprinting = false;
|
||||
|
||||
lReset = false;
|
||||
rReset = false;
|
||||
|
|
@ -94,35 +93,11 @@ void Input::tick(LocalPlayer *player)
|
|||
}
|
||||
|
||||
#ifdef _WINDOWS64
|
||||
if (iPad == 0 && g_KBMInput.IsMouseGrabbed())
|
||||
if (iPad == 0 && g_KBMInput.IsMouseGrabbed() && pMinecraft->localgameModes[iPad]->isInputAllowed(MINECRAFT_ACTION_SNEAK_TOGGLE))
|
||||
{
|
||||
// Left Shift = sneak (hold to crouch)
|
||||
if (pMinecraft->localgameModes[iPad]->isInputAllowed(MINECRAFT_ACTION_SNEAK_TOGGLE))
|
||||
{
|
||||
if (!player->abilities.flying)
|
||||
{
|
||||
sneaking = g_KBMInput.IsKeyDown(KeyboardMouseInput::KEY_SNEAK);
|
||||
}
|
||||
}
|
||||
|
||||
// Left Ctrl + forward = sprint (hold to sprint)
|
||||
if (!player->abilities.flying)
|
||||
{
|
||||
bool ctrlHeld = g_KBMInput.IsKeyDown(KeyboardMouseInput::KEY_SPRINT);
|
||||
bool movingForward = (kbYA > 0.0f);
|
||||
|
||||
if (ctrlHeld && movingForward)
|
||||
{
|
||||
sprinting = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
sprinting = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sprinting = false;
|
||||
sneaking = g_KBMInput.IsKeyDown(KeyboardMouseInput::KEY_SNEAK);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
@ -169,7 +144,7 @@ void Input::tick(LocalPlayer *player)
|
|||
if (iPad == 0 && g_KBMInput.IsMouseGrabbed())
|
||||
{
|
||||
float mouseSensitivity = ((float)app.GetGameSettings(iPad,eGameSetting_Sensitivity_InGame)) / 100.0f;
|
||||
float mouseLookScale = 5.0f;
|
||||
float mouseLookScale = 1.0f;
|
||||
float mx = g_KBMInput.GetLookX(mouseSensitivity * mouseLookScale);
|
||||
float my = g_KBMInput.GetLookY(mouseSensitivity * mouseLookScale);
|
||||
|
||||
|
|
|
|||
|
|
@ -10,8 +10,7 @@ public:
|
|||
bool wasJumping;
|
||||
bool jumping;
|
||||
bool sneaking;
|
||||
bool sprinting;
|
||||
|
||||
|
||||
Input(); // 4J - added
|
||||
|
||||
virtual void tick(LocalPlayer *player);
|
||||
|
|
|
|||
|
|
@ -6,9 +6,6 @@ KeyboardMouseInput g_KBMInput;
|
|||
|
||||
extern HWND g_hWnd;
|
||||
|
||||
// Forward declaration
|
||||
static void ClipCursorToWindow(HWND hWnd);
|
||||
|
||||
// coded by notpies fr
|
||||
void KeyboardMouseInput::Init()
|
||||
{
|
||||
|
|
@ -33,7 +30,6 @@ void KeyboardMouseInput::Init()
|
|||
m_mouseWheel = 0;
|
||||
m_mouseWheelAccum = 0;
|
||||
m_mouseGrabbed = false;
|
||||
m_cursorHiddenForUI = false;
|
||||
m_windowFocused = true;
|
||||
m_hasInput = false;
|
||||
|
||||
|
|
@ -44,6 +40,10 @@ void KeyboardMouseInput::Init()
|
|||
rid.hwndTarget = g_hWnd;
|
||||
RegisterRawInputDevices(&rid, 1, sizeof(rid));
|
||||
|
||||
if (g_hWnd)
|
||||
{
|
||||
while (ShowCursor(FALSE) >= 0) {}
|
||||
}
|
||||
}
|
||||
|
||||
void KeyboardMouseInput::ClearAllState()
|
||||
|
|
@ -107,7 +107,7 @@ void KeyboardMouseInput::Tick()
|
|||
}
|
||||
}
|
||||
|
||||
if ((m_mouseGrabbed || m_cursorHiddenForUI) && g_hWnd)
|
||||
if (m_mouseGrabbed && g_hWnd)
|
||||
{
|
||||
RECT rc;
|
||||
GetClientRect(g_hWnd, &rc);
|
||||
|
|
@ -226,9 +226,6 @@ void KeyboardMouseInput::SetMouseGrabbed(bool grabbed)
|
|||
m_mouseGrabbed = grabbed;
|
||||
if (grabbed && g_hWnd)
|
||||
{
|
||||
while (ShowCursor(FALSE) >= 0) {}
|
||||
ClipCursorToWindow(g_hWnd);
|
||||
|
||||
RECT rc;
|
||||
GetClientRect(g_hWnd, &rc);
|
||||
POINT center;
|
||||
|
|
@ -240,40 +237,6 @@ void KeyboardMouseInput::SetMouseGrabbed(bool grabbed)
|
|||
m_mouseDeltaAccumX = 0;
|
||||
m_mouseDeltaAccumY = 0;
|
||||
}
|
||||
else if (!grabbed && !m_cursorHiddenForUI && g_hWnd)
|
||||
{
|
||||
while (ShowCursor(TRUE) < 0) {}
|
||||
ClipCursor(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void KeyboardMouseInput::SetCursorHiddenForUI(bool hidden)
|
||||
{
|
||||
if (m_cursorHiddenForUI == hidden)
|
||||
return;
|
||||
|
||||
m_cursorHiddenForUI = hidden;
|
||||
if (hidden && g_hWnd)
|
||||
{
|
||||
while (ShowCursor(FALSE) >= 0) {}
|
||||
ClipCursorToWindow(g_hWnd);
|
||||
|
||||
RECT rc;
|
||||
GetClientRect(g_hWnd, &rc);
|
||||
POINT center;
|
||||
center.x = (rc.right - rc.left) / 2;
|
||||
center.y = (rc.bottom - rc.top) / 2;
|
||||
ClientToScreen(g_hWnd, ¢er);
|
||||
SetCursorPos(center.x, center.y);
|
||||
|
||||
m_mouseDeltaAccumX = 0;
|
||||
m_mouseDeltaAccumY = 0;
|
||||
}
|
||||
else if (!hidden && !m_mouseGrabbed && g_hWnd)
|
||||
{
|
||||
while (ShowCursor(TRUE) < 0) {}
|
||||
ClipCursor(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void ClipCursorToWindow(HWND hWnd)
|
||||
|
|
@ -294,16 +257,8 @@ void KeyboardMouseInput::SetWindowFocused(bool focused)
|
|||
m_windowFocused = focused;
|
||||
if (focused)
|
||||
{
|
||||
if (m_mouseGrabbed || m_cursorHiddenForUI)
|
||||
{
|
||||
while (ShowCursor(FALSE) >= 0) {}
|
||||
ClipCursorToWindow(g_hWnd);
|
||||
}
|
||||
else
|
||||
{
|
||||
while (ShowCursor(TRUE) < 0) {}
|
||||
ClipCursor(NULL);
|
||||
}
|
||||
while (ShowCursor(FALSE) >= 0) {}
|
||||
ClipCursorToWindow(g_hWnd);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -18,11 +18,9 @@ public:
|
|||
static const int KEY_RIGHT = 'D';
|
||||
static const int KEY_JUMP = VK_SPACE;
|
||||
static const int KEY_SNEAK = VK_LSHIFT;
|
||||
static const int KEY_SPRINT = VK_LCONTROL;
|
||||
static const int KEY_INVENTORY = 'E';
|
||||
static const int KEY_DROP = 'Q';
|
||||
static const int KEY_CRAFTING = VK_TAB;
|
||||
static const int KEY_CRAFTING_ALT = 'R';
|
||||
static const int KEY_PAUSE = VK_ESCAPE;
|
||||
static const int KEY_THIRD_PERSON = VK_F5;
|
||||
static const int KEY_DEBUG_INFO = VK_F3;
|
||||
|
|
@ -58,9 +56,6 @@ public:
|
|||
void SetMouseGrabbed(bool grabbed);
|
||||
bool IsMouseGrabbed() const { return m_mouseGrabbed; }
|
||||
|
||||
void SetCursorHiddenForUI(bool hidden);
|
||||
bool IsCursorHiddenForUI() const { return m_cursorHiddenForUI; }
|
||||
|
||||
void SetWindowFocused(bool focused);
|
||||
bool IsWindowFocused() const { return m_windowFocused; }
|
||||
|
||||
|
|
@ -102,8 +97,6 @@ private:
|
|||
|
||||
bool m_mouseGrabbed;
|
||||
|
||||
bool m_cursorHiddenForUI;
|
||||
|
||||
bool m_windowFocused;
|
||||
|
||||
bool m_hasInput;
|
||||
|
|
|
|||
|
|
@ -1794,6 +1794,11 @@ void LevelRenderer::renderAdvancedClouds(float alpha)
|
|||
|
||||
bool LevelRenderer::updateDirtyChunks()
|
||||
{
|
||||
if (level == NULL || mc == NULL || mc->level == NULL || globalChunkFlags == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef _LARGE_WORLDS
|
||||
std::list< std::pair<ClipChunk *, int> > nearestClipChunks;
|
||||
#endif
|
||||
|
|
@ -3641,4 +3646,4 @@ int LevelRenderer::rebuildChunkThreadProc(LPVOID lpParam)
|
|||
void LevelRenderer::nonStackDirtyChunksAdded()
|
||||
{
|
||||
dirtyChunksLockFreeStack.Push((int *)1);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -328,12 +328,6 @@ void LocalPlayer::aiStep()
|
|||
}
|
||||
}
|
||||
if (isSneaking()) sprintTriggerTime = 0;
|
||||
#ifdef _WINDOWS64
|
||||
if (input->sprinting && onGround && enoughFoodToSprint && !isUsingItem() && !hasEffect(MobEffect::blindness) && !isSneaking())
|
||||
{
|
||||
setSprinting(true);
|
||||
}
|
||||
#endif
|
||||
// 4J-PB - try not stopping sprint on collision
|
||||
//if (isSprinting() && (input->ya < runTreshold || horizontalCollision || !enoughFoodToSprint))
|
||||
if (isSprinting() && (input->ya < runTreshold || !enoughFoodToSprint))
|
||||
|
|
@ -591,9 +585,7 @@ void LocalPlayer::closeContainer()
|
|||
|
||||
void LocalPlayer::openTextEdit(shared_ptr<SignTileEntity> sign)
|
||||
{
|
||||
bool success = app.LoadSignEntryMenu(GetXboxPad(), sign );
|
||||
if( success ) ui.PlayUISFX(eSFX_Press);
|
||||
//minecraft->setScreen(new TextEditScreen(sign));
|
||||
minecraft->setScreen(new TextEditScreen(sign));
|
||||
}
|
||||
|
||||
bool LocalPlayer::openContainer(shared_ptr<Container> container)
|
||||
|
|
@ -1619,4 +1611,3 @@ void LocalPlayer::SetPlayerAdditionalModelParts(vector<ModelPart *>pAdditionalMo
|
|||
{
|
||||
m_pAdditionalModelParts=pAdditionalModelParts;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="ContentPackage_NO_TU|Durango">
|
||||
|
|
@ -1311,17 +1311,6 @@ if not exist "$(TargetDir)\savedata" mkdir "$(TargetDir)\savedata"</Command>
|
|||
<DeploymentType>CopyToHardDrive</DeploymentType>
|
||||
<DeploymentFiles>$(RemoteRoot)=$(ImagePath);$(RemoteRoot)\res=Xbox\res;$(RemoteRoot)=Xbox\AvatarAwards;$(RemoteRoot)\Tutorial=Xbox\Tutorial\Tutorial;$(RemoteRoot)=Xbox\584111F70AAAAAAA;$(RemoteRoot)=Xbox\kinect\speech;$(RemoteRoot)=Xbox\XZP\TMSFiles.xzp</DeploymentFiles>
|
||||
</Deploy>
|
||||
<PostBuildEvent>
|
||||
<Command>copy /Y "$(TargetPath)" "$(ProjectDir)"
|
||||
copy /Y "$(ProjectDir)Windows64\Iggy\lib\redist64\iggy_w64.dll" "$(ProjectDir)"
|
||||
copy /Y "$(ProjectDir)Windows64\Miles\lib\redist64\mss64.dll" "$(ProjectDir)"
|
||||
copy /Y "$(ProjectDir)Windows64\Iggy\lib\redist64\iggy_w64.dll" "$(OutDir)"
|
||||
copy /Y "$(ProjectDir)Windows64\Miles\lib\redist64\mss64.dll" "$(OutDir)"
|
||||
xcopy /Y /I /E "$(ProjectDir)redist64" "$(OutDir)redist64\"
|
||||
if not exist "$(OutDir)Durango\Sound\" mkdir "$(OutDir)Durango\Sound\"
|
||||
copy /Y "$(ProjectDir)Durango\Sound\Minecraft.msscmp" "$(OutDir)Durango\Sound\"</Command>
|
||||
<Message>Copying exe and DLLs to Minecraft.Client and output folders</Message>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Durango'">
|
||||
<ClCompile>
|
||||
|
|
@ -1432,7 +1421,7 @@ xcopy /q /y /i /s /e $(ProjectDir)Durango\CU $(LayoutDir)Image\Loose\CU</Comman
|
|||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<ProgramDatabaseFile>$(OutDir)$(ProjectName).pdb</ProgramDatabaseFile>
|
||||
<AdditionalDependencies>d3d11.lib;..\Minecraft.World\x64_Release\Minecraft.World.lib;XInput9_1_0.lib;Windows64\Iggy\lib\iggy_w64.lib;..\Minecraft.Client\Windows64\Miles\Lib\mss64.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>d3d11.lib;..\Minecraft.World\x64_Release\Minecraft.World.lib;XInput9_1_0.lib;Windows64\Iggy\lib\iggy_w64.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<ShowProgress>NotSet</ShowProgress>
|
||||
<SuppressStartupBanner>false</SuppressStartupBanner>
|
||||
</Link>
|
||||
|
|
@ -1450,17 +1439,6 @@ xcopy /q /y /i /s /e $(ProjectDir)Durango\CU $(LayoutDir)Image\Loose\CU</Comman
|
|||
<DeploymentType>CopyToHardDrive</DeploymentType>
|
||||
<DeploymentFiles>$(RemoteRoot)=$(ImagePath);$(RemoteRoot)\res=Xbox\res;$(RemoteRoot)=Xbox\AvatarAwards;$(RemoteRoot)\Tutorial=Xbox\Tutorial\Tutorial;$(RemoteRoot)=Xbox\584111F70AAAAAAA;$(RemoteRoot)=Xbox\kinect\speech;$(RemoteRoot)=Xbox\XZP\TMSFiles.xzp</DeploymentFiles>
|
||||
</Deploy>
|
||||
<PostBuildEvent>
|
||||
<Command>copy /Y "$(TargetPath)" "$(ProjectDir)"
|
||||
copy /Y "$(ProjectDir)Windows64\Iggy\lib\redist64\iggy_w64.dll" "$(ProjectDir)"
|
||||
copy /Y "$(ProjectDir)Windows64\Miles\lib\redist64\mss64.dll" "$(ProjectDir)"
|
||||
copy /Y "$(ProjectDir)Windows64\Iggy\lib\redist64\iggy_w64.dll" "$(OutDir)"
|
||||
copy /Y "$(ProjectDir)Windows64\Miles\lib\redist64\mss64.dll" "$(OutDir)"
|
||||
xcopy /Y /I /E "$(ProjectDir)redist64" "$(OutDir)redist64\"
|
||||
if not exist "$(OutDir)Durango\Sound\" mkdir "$(OutDir)Durango\Sound\"
|
||||
copy /Y "$(ProjectDir)Durango\Sound\Minecraft.msscmp" "$(OutDir)Durango\Sound\"</Command>
|
||||
<Message>Copying exe and DLLs to Minecraft.Client and output folders</Message>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ContentPackage_Vita|x64'">
|
||||
<ClCompile>
|
||||
|
|
@ -2850,7 +2828,7 @@ xcopy /q /y /i /s /e $(ProjectDir)Durango\CU $(LayoutDir)Image\Loose\CU</Comman
|
|||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseForArt|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ContentPackage_NO_TU|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ContentPackage_Vita|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ContentPackage|Xbox 360'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CONTENTPACKAGE_SYMBOLS|Xbox 360'">true</ExcludedFromBuild>
|
||||
|
|
@ -2894,8 +2872,8 @@ xcopy /q /y /i /s /e $(ProjectDir)Durango\CU $(LayoutDir)Image\Loose\CU</Comman
|
|||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CONTENTPACKAGE_SYMBOLS|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseForArt|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ContentPackage_NO_TU|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ContentPackage_Vita|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ContentPackage|Xbox 360'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CONTENTPACKAGE_SYMBOLS|Xbox 360'">true</ExcludedFromBuild>
|
||||
|
|
@ -2939,7 +2917,7 @@ xcopy /q /y /i /s /e $(ProjectDir)Durango\CU $(LayoutDir)Image\Loose\CU</Comman
|
|||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CONTENTPACKAGE_SYMBOLS|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseForArt|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ContentPackage_NO_TU|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ContentPackage_Vita|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ContentPackage|Xbox 360'">true</ExcludedFromBuild>
|
||||
|
|
@ -28935,7 +28913,7 @@ xcopy /q /y /i /s /e $(ProjectDir)Durango\CU $(LayoutDir)Image\Loose\CU</Comman
|
|||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ContentPackage_Vita|PS3'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|PSVita'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ContentPackage_Vita|PSVita'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ContentPackage_Vita|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Xbox 360'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ContentPackage_Vita|Xbox 360'">true</ExcludedFromBuild>
|
||||
|
|
@ -28943,7 +28921,7 @@ xcopy /q /y /i /s /e $(ProjectDir)Durango\CU $(LayoutDir)Image\Loose\CU</Comman
|
|||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ORBIS'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|PS3'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|PSVita'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Xbox 360'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Texture.cpp" />
|
||||
|
|
@ -34103,7 +34081,6 @@ xcopy /q /y /i /s /e $(ProjectDir)Durango\CU $(LayoutDir)Image\Loose\CU</Comman
|
|||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Xbox 360'">true</ExcludedFromBuild>
|
||||
</Library>
|
||||
<Library Include="PSVita\4JLibs\libs\4J_Input.a">
|
||||
<ExcludedFromBuild Condition="'$(Platform)'=='x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ContentPackage|PSVita'">false</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ContentPackage_NO_TU|PSVita'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseForArt|PSVita'">true</ExcludedFromBuild>
|
||||
|
|
@ -34148,7 +34125,6 @@ xcopy /q /y /i /s /e $(ProjectDir)Durango\CU $(LayoutDir)Image\Loose\CU</Comman
|
|||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CONTENTPACKAGE_SYMBOLS|Xbox 360'">true</ExcludedFromBuild>
|
||||
</Library>
|
||||
<Library Include="PSVita\4JLibs\libs\4J_Input_d.a">
|
||||
<ExcludedFromBuild Condition="'$(Platform)'=='x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ContentPackage|PSVita'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ContentPackage_NO_TU|PSVita'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseForArt|PSVita'">true</ExcludedFromBuild>
|
||||
|
|
@ -34193,7 +34169,6 @@ xcopy /q /y /i /s /e $(ProjectDir)Durango\CU $(LayoutDir)Image\Loose\CU</Comman
|
|||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CONTENTPACKAGE_SYMBOLS|Xbox 360'">true</ExcludedFromBuild>
|
||||
</Library>
|
||||
<Library Include="PSVita\4JLibs\libs\4J_Input_r.a">
|
||||
<ExcludedFromBuild Condition="'$(Platform)'=='x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ContentPackage|PSVita'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ContentPackage_NO_TU|PSVita'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseForArt|PSVita'">true</ExcludedFromBuild>
|
||||
|
|
@ -34238,7 +34213,6 @@ xcopy /q /y /i /s /e $(ProjectDir)Durango\CU $(LayoutDir)Image\Loose\CU</Comman
|
|||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CONTENTPACKAGE_SYMBOLS|Xbox 360'">true</ExcludedFromBuild>
|
||||
</Library>
|
||||
<Library Include="PSVita\4JLibs\libs\4J_Profile.a">
|
||||
<ExcludedFromBuild Condition="'$(Platform)'=='x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ContentPackage|PSVita'">false</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ContentPackage_NO_TU|PSVita'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseForArt|PSVita'">true</ExcludedFromBuild>
|
||||
|
|
@ -34283,7 +34257,6 @@ xcopy /q /y /i /s /e $(ProjectDir)Durango\CU $(LayoutDir)Image\Loose\CU</Comman
|
|||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CONTENTPACKAGE_SYMBOLS|Xbox 360'">true</ExcludedFromBuild>
|
||||
</Library>
|
||||
<Library Include="PSVita\4JLibs\libs\4J_Profile_d.a">
|
||||
<ExcludedFromBuild Condition="'$(Platform)'=='x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ContentPackage|PSVita'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ContentPackage_NO_TU|PSVita'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseForArt|PSVita'">true</ExcludedFromBuild>
|
||||
|
|
@ -34328,7 +34301,6 @@ xcopy /q /y /i /s /e $(ProjectDir)Durango\CU $(LayoutDir)Image\Loose\CU</Comman
|
|||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CONTENTPACKAGE_SYMBOLS|Xbox 360'">true</ExcludedFromBuild>
|
||||
</Library>
|
||||
<Library Include="PSVita\4JLibs\libs\4J_Profile_r.a">
|
||||
<ExcludedFromBuild Condition="'$(Platform)'=='x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ContentPackage|PSVita'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ContentPackage_NO_TU|PSVita'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseForArt|PSVita'">true</ExcludedFromBuild>
|
||||
|
|
@ -34373,7 +34345,6 @@ xcopy /q /y /i /s /e $(ProjectDir)Durango\CU $(LayoutDir)Image\Loose\CU</Comman
|
|||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CONTENTPACKAGE_SYMBOLS|Xbox 360'">true</ExcludedFromBuild>
|
||||
</Library>
|
||||
<Library Include="PSVita\4JLibs\libs\4J_Render.a">
|
||||
<ExcludedFromBuild Condition="'$(Platform)'=='x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ContentPackage|PSVita'">false</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ContentPackage_NO_TU|PSVita'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseForArt|PSVita'">true</ExcludedFromBuild>
|
||||
|
|
@ -34418,7 +34389,6 @@ xcopy /q /y /i /s /e $(ProjectDir)Durango\CU $(LayoutDir)Image\Loose\CU</Comman
|
|||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CONTENTPACKAGE_SYMBOLS|Xbox 360'">true</ExcludedFromBuild>
|
||||
</Library>
|
||||
<Library Include="PSVita\4JLibs\libs\4J_Render_d.a">
|
||||
<ExcludedFromBuild Condition="'$(Platform)'=='x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ContentPackage|PSVita'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ContentPackage_NO_TU|PSVita'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseForArt|PSVita'">true</ExcludedFromBuild>
|
||||
|
|
@ -34463,7 +34433,6 @@ xcopy /q /y /i /s /e $(ProjectDir)Durango\CU $(LayoutDir)Image\Loose\CU</Comman
|
|||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CONTENTPACKAGE_SYMBOLS|Xbox 360'">true</ExcludedFromBuild>
|
||||
</Library>
|
||||
<Library Include="PSVita\4JLibs\libs\4J_Render_r.a">
|
||||
<ExcludedFromBuild Condition="'$(Platform)'=='x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ContentPackage|PSVita'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ContentPackage_NO_TU|PSVita'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseForArt|PSVita'">true</ExcludedFromBuild>
|
||||
|
|
@ -34508,7 +34477,6 @@ xcopy /q /y /i /s /e $(ProjectDir)Durango\CU $(LayoutDir)Image\Loose\CU</Comman
|
|||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CONTENTPACKAGE_SYMBOLS|Xbox 360'">true</ExcludedFromBuild>
|
||||
</Library>
|
||||
<Library Include="PSVita\4JLibs\libs\4J_Storage.a">
|
||||
<ExcludedFromBuild Condition="'$(Platform)'=='x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ContentPackage|PSVita'">false</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ContentPackage_NO_TU|PSVita'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseForArt|PSVita'">true</ExcludedFromBuild>
|
||||
|
|
@ -34553,7 +34521,6 @@ xcopy /q /y /i /s /e $(ProjectDir)Durango\CU $(LayoutDir)Image\Loose\CU</Comman
|
|||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CONTENTPACKAGE_SYMBOLS|Xbox 360'">true</ExcludedFromBuild>
|
||||
</Library>
|
||||
<Library Include="PSVita\4JLibs\libs\4J_Storage_d.a">
|
||||
<ExcludedFromBuild Condition="'$(Platform)'=='x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ContentPackage|PSVita'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ContentPackage_NO_TU|PSVita'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseForArt|PSVita'">true</ExcludedFromBuild>
|
||||
|
|
@ -34598,7 +34565,6 @@ xcopy /q /y /i /s /e $(ProjectDir)Durango\CU $(LayoutDir)Image\Loose\CU</Comman
|
|||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CONTENTPACKAGE_SYMBOLS|Xbox 360'">true</ExcludedFromBuild>
|
||||
</Library>
|
||||
<Library Include="PSVita\4JLibs\libs\4J_Storage_r.a">
|
||||
<ExcludedFromBuild Condition="'$(Platform)'=='x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ContentPackage|PSVita'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ContentPackage_NO_TU|PSVita'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseForArt|PSVita'">true</ExcludedFromBuild>
|
||||
|
|
@ -34643,21 +34609,14 @@ xcopy /q /y /i /s /e $(ProjectDir)Durango\CU $(LayoutDir)Image\Loose\CU</Comman
|
|||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CONTENTPACKAGE_SYMBOLS|Xbox 360'">true</ExcludedFromBuild>
|
||||
</Library>
|
||||
<Library Include="PSVita\4JLibs\libs\libSceNpToolkitUtils_rtti.a">
|
||||
<ExcludedFromBuild Condition="'$(Platform)'=='x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|PSVita'">true</ExcludedFromBuild>
|
||||
</Library>
|
||||
<Library Include="PSVita\4JLibs\libs\libSceNpToolkitUtils_rtti_dbg.a">
|
||||
<ExcludedFromBuild Condition="'$(Platform)'=='x64'">true</ExcludedFromBuild>
|
||||
</Library>
|
||||
<Library Include="PSVita\4JLibs\libs\libSceNpToolkitUtils_rtti_dbg.a" />
|
||||
<Library Include="PSVita\4JLibs\libs\libSceNpToolkit_rtti.a">
|
||||
<ExcludedFromBuild Condition="'$(Platform)'=='x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|PSVita'">true</ExcludedFromBuild>
|
||||
</Library>
|
||||
<Library Include="PSVita\4JLibs\libs\libSceNpToolkit_rtti_dbg.a">
|
||||
<ExcludedFromBuild Condition="'$(Platform)'=='x64'">true</ExcludedFromBuild>
|
||||
</Library>
|
||||
<Library Include="PSVita\4JLibs\libs\libSceNpToolkit_rtti_dbg.a" />
|
||||
<Library Include="PSVita\Iggy\lib\libiggyperfmon_psp2.a">
|
||||
<ExcludedFromBuild Condition="'$(Platform)'=='x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ContentPackage|Durango'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ContentPackage_NO_TU|Durango'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseForArt|Durango'">true</ExcludedFromBuild>
|
||||
|
|
@ -34695,7 +34654,6 @@ xcopy /q /y /i /s /e $(ProjectDir)Durango\CU $(LayoutDir)Image\Loose\CU</Comman
|
|||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CONTENTPACKAGE_SYMBOLS|Xbox 360'">true</ExcludedFromBuild>
|
||||
</Library>
|
||||
<Library Include="PSVita\Iggy\lib\libiggy_psp2.a">
|
||||
<ExcludedFromBuild Condition="'$(Platform)'=='x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ContentPackage|Durango'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ContentPackage_NO_TU|Durango'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseForArt|Durango'">true</ExcludedFromBuild>
|
||||
|
|
@ -34732,18 +34690,10 @@ xcopy /q /y /i /s /e $(ProjectDir)Durango\CU $(LayoutDir)Image\Loose\CU</Comman
|
|||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Xbox 360'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CONTENTPACKAGE_SYMBOLS|Xbox 360'">true</ExcludedFromBuild>
|
||||
</Library>
|
||||
<Library Include="PSVita\Miles\lib\binkapsp2.a">
|
||||
<ExcludedFromBuild Condition="'$(Platform)'=='x64'">true</ExcludedFromBuild>
|
||||
</Library>
|
||||
<Library Include="PSVita\Miles\lib\fltpsp2.a">
|
||||
<ExcludedFromBuild Condition="'$(Platform)'=='x64'">true</ExcludedFromBuild>
|
||||
</Library>
|
||||
<Library Include="PSVita\Miles\lib\msspsp2.a">
|
||||
<ExcludedFromBuild Condition="'$(Platform)'=='x64'">true</ExcludedFromBuild>
|
||||
</Library>
|
||||
<Library Include="PSVita\Miles\lib\msspsp2midi.a">
|
||||
<ExcludedFromBuild Condition="'$(Platform)'=='x64'">true</ExcludedFromBuild>
|
||||
</Library>
|
||||
<Library Include="PSVita\Miles\lib\binkapsp2.a" />
|
||||
<Library Include="PSVita\Miles\lib\fltpsp2.a" />
|
||||
<Library Include="PSVita\Miles\lib\msspsp2.a" />
|
||||
<Library Include="PSVita\Miles\lib\msspsp2midi.a" />
|
||||
<Library Include="Windows64\4JLibs\libs\4J_Input.lib">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ContentPackage|Durango'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CONTENTPACKAGE_SYMBOLS|Durango'">true</ExcludedFromBuild>
|
||||
|
|
@ -36889,4 +36839,5 @@ xcopy /q /y /i /s /e $(ProjectDir)Durango\CU $(LayoutDir)Image\Loose\CU</Comman
|
|||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
#include "TitleScreen.h"
|
||||
#include "InventoryScreen.h"
|
||||
#include "InBedChatScreen.h"
|
||||
#include "ChatScreen.h"
|
||||
#include "AchievementPopup.h"
|
||||
#include "Input.h"
|
||||
#include "FrustumCuller.h"
|
||||
|
|
@ -172,7 +173,6 @@ Minecraft::Minecraft(Component *mouseComponent, Canvas *parent, MinecraftApplet
|
|||
//lastTickTime = System::currentTimeMillis();
|
||||
recheckPlayerIn = 0;
|
||||
running = true;
|
||||
showFpsCounter = false;
|
||||
unoccupiedQuadrant = -1;
|
||||
|
||||
Stats::init();
|
||||
|
|
@ -1481,7 +1481,7 @@ void Minecraft::run_middle()
|
|||
if(g_KBMInput.IsKeyPressed(KeyboardMouseInput::KEY_DROP))
|
||||
localplayers[i]->ullButtonsPressed|=1LL<<MINECRAFT_ACTION_DROP;
|
||||
|
||||
if(g_KBMInput.IsKeyPressed(KeyboardMouseInput::KEY_CRAFTING) || g_KBMInput.IsKeyPressed(KeyboardMouseInput::KEY_CRAFTING_ALT))
|
||||
if(g_KBMInput.IsKeyPressed(KeyboardMouseInput::KEY_CRAFTING))
|
||||
localplayers[i]->ullButtonsPressed|=1LL<<MINECRAFT_ACTION_CRAFTING;
|
||||
|
||||
if(g_KBMInput.IsKeyPressed(KeyboardMouseInput::KEY_PAUSE))
|
||||
|
|
@ -1494,15 +1494,7 @@ void Minecraft::run_middle()
|
|||
localplayers[i]->ullButtonsPressed|=1LL<<MINECRAFT_ACTION_RENDER_THIRD_PERSON;
|
||||
|
||||
if(g_KBMInput.IsKeyPressed(KeyboardMouseInput::KEY_DEBUG_INFO))
|
||||
{
|
||||
localplayers[i]->ullButtonsPressed|=1LL<<MINECRAFT_ACTION_GAME_INFO;
|
||||
//localplayers[i]->ullButtonsPressed|=1LL<<MINECRAFT_ACTION_RENDER_DEBUG;
|
||||
}
|
||||
|
||||
if(g_KBMInput.IsKeyPressed(VK_F4))
|
||||
{
|
||||
showFpsCounter = !showFpsCounter;
|
||||
}
|
||||
|
||||
int wheel = g_KBMInput.GetMouseWheel();
|
||||
if (wheel > 0)
|
||||
|
|
@ -1529,7 +1521,7 @@ void Minecraft::run_middle()
|
|||
localplayers[i]->ullDpad_filtered = 0;
|
||||
if(InputManager.ButtonPressed(i, MINECRAFT_ACTION_DPAD_RIGHT)) localplayers[i]->ullButtonsPressed|=1LL<<MINECRAFT_ACTION_CHANGE_SKIN;
|
||||
if(InputManager.ButtonPressed(i, MINECRAFT_ACTION_DPAD_UP)) localplayers[i]->ullButtonsPressed|=1LL<<MINECRAFT_ACTION_FLY_TOGGLE;
|
||||
if(InputManager.ButtonPressed(i, MINECRAFT_ACTION_DPAD_DOWN)) localplayers[i]->ullButtonsPressed|=1LL<<MINECRAFT_ACTION_RENDER_DEBUG;
|
||||
if(InputManager.ButtonPressed(i, MINECRAFT_ACTION_DPAD_DOWN)) //localplayers[i]->ullButtonsPressed|=1LL<<MINECRAFT_ACTION_RENDER_DEBUG;
|
||||
if(InputManager.ButtonPressed(i, MINECRAFT_ACTION_DPAD_LEFT)) localplayers[i]->ullButtonsPressed|=1LL<<MINECRAFT_ACTION_SPAWN_CREEPER;
|
||||
}
|
||||
else
|
||||
|
|
@ -2324,6 +2316,21 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures)
|
|||
{
|
||||
g_KBMInput.SetMouseGrabbed(true);
|
||||
}
|
||||
|
||||
if (iPad == 0)
|
||||
{
|
||||
const int vkChat = Keyboard::toVK(Keyboard::KEY_T);
|
||||
static bool s_chatKeyWasDown = false;
|
||||
const bool chatKeyDown = (vkChat != 0) && g_KBMInput.IsKeyDown(vkChat);
|
||||
if (chatKeyDown && !s_chatKeyWasDown)
|
||||
{
|
||||
app.DebugPrintf("Chat hotkey pressed - opening ChatScreen");
|
||||
setScreen(new ChatScreen());
|
||||
s_chatKeyWasDown = true;
|
||||
return;
|
||||
}
|
||||
s_chatKeyWasDown = chatKeyDown;
|
||||
}
|
||||
#endif
|
||||
// 4J-PB - add some tooltips if required
|
||||
int iA=-1, iB=-1, iX, iY=IDS_CONTROLS_INVENTORY, iLT=-1, iRT=-1, iLB=-1, iRB=-1;
|
||||
|
|
@ -3691,7 +3698,7 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures)
|
|||
if (Keyboard.getEventKey() == options.keyDrop.key) {
|
||||
player->drop();
|
||||
}
|
||||
if (isClientSide() && Keyboard.getEventKey() == options.keyChat.key) {
|
||||
if ((isClientSide() || g_NetworkManager.IsInSession()) && Keyboard.getEventKey() == options.keyChat.key) {
|
||||
setScreen(new ChatScreen());
|
||||
}
|
||||
}
|
||||
|
|
@ -4989,4 +4996,3 @@ int Minecraft::MustSignInReturnedPSN(void *pParam, int iPad, C4JStorage::EMessag
|
|||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -211,7 +211,6 @@ private:
|
|||
public:
|
||||
void destroy();
|
||||
volatile bool running;
|
||||
bool showFpsCounter;
|
||||
wstring fpsString;
|
||||
void run();
|
||||
// 4J-PB - split the run into 3 parts so we can run it from our xbox game loop
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
#include "..\Minecraft.World\net.minecraft.world.h"
|
||||
#include "..\Minecraft.World\net.minecraft.world.level.h"
|
||||
#include "..\Minecraft.World\net.minecraft.world.level.tile.h"
|
||||
#include "..\Minecraft.World\net.minecraft.world.level.tile.entity.h"
|
||||
#include "..\Minecraft.World\Pos.h"
|
||||
#include "..\Minecraft.World\System.h"
|
||||
#include "..\Minecraft.World\StringHelpers.h"
|
||||
|
|
@ -66,6 +67,227 @@ bool MinecraftServer::s_slowQueuePacketSent = false;
|
|||
|
||||
unordered_map<wstring, int> MinecraftServer::ironTimers;
|
||||
|
||||
namespace
|
||||
{
|
||||
const unsigned int MINIGAME_SETTINGS_FLAG = 0x80000000u;
|
||||
const unsigned int MINIGAME_SETTINGS_TYPE_MASK = 0x70000000u;
|
||||
const unsigned int MINIGAME_SETTINGS_TYPE_SHIFT = 28u;
|
||||
const unsigned int MINIGAME_SETTINGS_ROLE_MASK = 0x0C000000u;
|
||||
const unsigned int MINIGAME_SETTINGS_ROLE_SHIFT = 26u;
|
||||
const unsigned int MINIGAME_TYPE_BEDWARS = 3u;
|
||||
const unsigned int MINIGAME_ROLE_HUB = 0u;
|
||||
|
||||
struct BedwarsNpcDef
|
||||
{
|
||||
const wchar_t *label;
|
||||
int offX;
|
||||
int offZ;
|
||||
float yRot;
|
||||
};
|
||||
|
||||
static const BedwarsNpcDef kBedwarsNpcDefs[] =
|
||||
{
|
||||
{ L"Solo Queue", -3, 0, 90.0f },
|
||||
{ L"Doubles Queue", 0, 3, 180.0f },
|
||||
{ L"Squads Queue", 3, 0, 270.0f },
|
||||
{ L"Practice NPC", 0, -3, 0.0f },
|
||||
};
|
||||
static const wchar_t *kBedwarsNpcRainbowLabels[] =
|
||||
{
|
||||
L"\u00A7cS\u00A76o\u00A7el\u00A7ao \u00A7bQ\u00A7du\u00A7ce\u00A76u\u00A7ee",
|
||||
L"\u00A7cD\u00A76o\u00A7eu\u00A7ab\u00A7bl\u00A7de\u00A7cs",
|
||||
L"\u00A7cS\u00A76q\u00A7eu\u00A7aa\u00A7bd\u00A7ds",
|
||||
L"\u00A7cP\u00A76r\u00A7ea\u00A7ac\u00A7bt\u00A7di\u00A7cc\u00A76e"
|
||||
};
|
||||
|
||||
bool IsBedwarsMinigameSettings(unsigned int hostSettings)
|
||||
{
|
||||
if ((hostSettings & MINIGAME_SETTINGS_FLAG) == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const unsigned int minigameType = (hostSettings & MINIGAME_SETTINGS_TYPE_MASK) >> MINIGAME_SETTINGS_TYPE_SHIFT;
|
||||
return (minigameType == MINIGAME_TYPE_BEDWARS);
|
||||
}
|
||||
|
||||
bool IsBedwarsHubSettings(unsigned int hostSettings)
|
||||
{
|
||||
if (!IsBedwarsMinigameSettings(hostSettings))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
const unsigned int role = (hostSettings & MINIGAME_SETTINGS_ROLE_MASK) >> MINIGAME_SETTINGS_ROLE_SHIFT;
|
||||
return (role == MINIGAME_ROLE_HUB);
|
||||
}
|
||||
|
||||
void SpawnBedwarsQueueSign(ServerLevel *level, int x, int y, int z, const wchar_t *line1, const wchar_t *line2)
|
||||
{
|
||||
if (level == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
level->setTile(x, y - 1, z, Tile::cloth_Id);
|
||||
level->setTileAndData(x, y, z, Tile::sign_Id, 8);
|
||||
|
||||
shared_ptr<SignTileEntity> sign = dynamic_pointer_cast<SignTileEntity>(level->getTileEntity(x, y, z));
|
||||
if (sign != NULL)
|
||||
{
|
||||
wstring s1 = line1 != NULL ? line1 : L"";
|
||||
wstring s2 = line2 != NULL ? line2 : L"";
|
||||
wstring s3 = L"\u00A7aClick NPC";
|
||||
wstring s4 = L"to join";
|
||||
sign->SetMessage(0, s1);
|
||||
sign->SetMessage(1, s2);
|
||||
sign->SetMessage(2, s3);
|
||||
sign->SetMessage(3, s4);
|
||||
sign->setChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void KeepBedwarsLobbyNpcsStationary(ServerLevel *level)
|
||||
{
|
||||
if (level == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
Pos *spawnPos = level->getSharedSpawnPos();
|
||||
if (spawnPos == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
const double spawnX = (double)spawnPos->x + 0.5;
|
||||
const double spawnY = (double)spawnPos->y + 1.0;
|
||||
const double spawnZ = (double)spawnPos->z + 0.5;
|
||||
delete spawnPos;
|
||||
vector<shared_ptr<Entity> > entities = level->getAllEntities();
|
||||
for (size_t i = 0; i < entities.size(); ++i)
|
||||
{
|
||||
shared_ptr<Entity> entity = entities[i];
|
||||
if (entity == NULL || entity->GetType() != eTYPE_VILLAGER)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
for (size_t j = 0; j < (sizeof(kBedwarsNpcDefs) / sizeof(kBedwarsNpcDefs[0])); ++j)
|
||||
{
|
||||
const BedwarsNpcDef &def = kBedwarsNpcDefs[j];
|
||||
const double anchorX = spawnX + (double)def.offX;
|
||||
const double anchorZ = spawnZ + (double)def.offZ;
|
||||
const double dx = entity->x - anchorX;
|
||||
const double dz = entity->z - anchorZ;
|
||||
if ((dx * dx + dz * dz) <= (3.0 * 3.0))
|
||||
{
|
||||
entity->xd = 0.0;
|
||||
entity->yd = 0.0;
|
||||
entity->zd = 0.0;
|
||||
entity->moveTo(anchorX, spawnY, anchorZ, def.yRot, 0.0f);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
void BuildBedwarsHub(ServerLevel *level)
|
||||
{
|
||||
if (level == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
Pos *spawnPos = level->getSharedSpawnPos();
|
||||
if (spawnPos == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
const int sx = spawnPos->x;
|
||||
const int sy = spawnPos->y;
|
||||
const int sz = spawnPos->z;
|
||||
delete spawnPos;
|
||||
for (int dx = -14; dx <= 14; ++dx)
|
||||
{
|
||||
for (int dz = -14; dz <= 14; ++dz)
|
||||
{
|
||||
const int x = sx + dx;
|
||||
const int z = sz + dz;
|
||||
const int ax = abs(dx);
|
||||
const int az = abs(dz);
|
||||
for (int y = sy + 1; y <= sy + 6; ++y)
|
||||
{
|
||||
level->setTile(x, y, z, 0);
|
||||
}
|
||||
if (ax == 14 || az == 14)
|
||||
{
|
||||
level->setTile(x, sy, z, Tile::stoneBrick_Id);
|
||||
if (((dx + dz) & 1) == 0)
|
||||
{
|
||||
level->setTile(x, sy + 1, z, Tile::glass_Id);
|
||||
}
|
||||
}
|
||||
else if (ax <= 2 || az <= 2)
|
||||
{
|
||||
level->setTile(x, sy, z, Tile::stoneBrick_Id);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (size_t i = 0; i < (sizeof(kBedwarsNpcDefs) / sizeof(kBedwarsNpcDefs[0])); ++i)
|
||||
{
|
||||
const BedwarsNpcDef &def = kBedwarsNpcDefs[i];
|
||||
const int px = sx + def.offX;
|
||||
const int pz = sz + def.offZ;
|
||||
const int woolColor = (int)i + 1;
|
||||
for (int ox = -1; ox <= 1; ++ox)
|
||||
{
|
||||
for (int oz = -1; oz <= 1; ++oz)
|
||||
{
|
||||
level->setTileAndData(px + ox, sy, pz + oz, Tile::cloth_Id, woolColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
void SpawnBedwarsLobbyNpcs(ServerLevel *level)
|
||||
{
|
||||
if (level == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Pos *spawnPos = level->getSharedSpawnPos();
|
||||
if (spawnPos == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const int spawnXi = spawnPos->x;
|
||||
const int spawnYi = spawnPos->y;
|
||||
const int spawnZi = spawnPos->z;
|
||||
const double spawnX = (double)spawnXi + 0.5;
|
||||
const double spawnY = (double)spawnYi + 1.0;
|
||||
const double spawnZ = (double)spawnZi + 0.5;
|
||||
delete spawnPos;
|
||||
|
||||
for (size_t i = 0; i < (sizeof(kBedwarsNpcDefs) / sizeof(kBedwarsNpcDefs[0])); ++i)
|
||||
{
|
||||
const BedwarsNpcDef &def = kBedwarsNpcDefs[i];
|
||||
shared_ptr<Entity> npc(EntityIO::newByEnumType(eTYPE_VILLAGER, level));
|
||||
if (npc == NULL)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
npc->moveTo(spawnX + (double)def.offX, spawnY, spawnZ + (double)def.offZ, def.yRot, 0.0f);
|
||||
npc->setDespawnProtected();
|
||||
level->addEntity(npc);
|
||||
|
||||
const wchar_t *rainbowLabel = kBedwarsNpcRainbowLabels[i];
|
||||
SpawnBedwarsQueueSign(level, spawnXi + def.offX, spawnYi + 2, spawnZi + def.offZ, L"\u00A7cB\u00A76e\u00A7ed\u00A7aw\u00A7ba\u00A7dr\u00A7cs", rainbowLabel);
|
||||
|
||||
app.DebugPrintf("Bedwars lobby NPC spawned: %ls at (%.1f, %.1f, %.1f)\n",
|
||||
def.label,
|
||||
spawnX + (double)def.offX,
|
||||
spawnY,
|
||||
spawnZ + (double)def.offZ);
|
||||
}
|
||||
}
|
||||
}
|
||||
MinecraftServer::MinecraftServer()
|
||||
{
|
||||
// 4J - added initialisers
|
||||
|
|
@ -91,6 +313,9 @@ MinecraftServer::MinecraftServer()
|
|||
m_texturePackId = 0;
|
||||
maxBuildHeight = Level::maxBuildHeight;
|
||||
m_postUpdateThread = NULL;
|
||||
m_recentTps = (float)SharedConstants::TICKS_PER_SECOND;
|
||||
m_lastTpsSampleMs = 0;
|
||||
m_lastTpsSampleTick = 0;
|
||||
|
||||
commandDispatcher = new ServerCommandDispatcher();
|
||||
}
|
||||
|
|
@ -1060,6 +1285,12 @@ void MinecraftServer::run(__int64 seed, void *lpParameter)
|
|||
if (initServer(seed, initData, initSettings,findSeed))
|
||||
{
|
||||
ServerLevel *levelNormalDimension = levels[0];
|
||||
if (IsBedwarsHubSettings(initSettings))
|
||||
{
|
||||
app.DebugPrintf("Bedwars mode detected - building hub and spawning lobby NPCs\n");
|
||||
BuildBedwarsHub(levelNormalDimension);
|
||||
SpawnBedwarsLobbyNpcs(levelNormalDimension);
|
||||
}
|
||||
// 4J-PB - Set the Stronghold position in the leveldata if there isn't one in there
|
||||
Minecraft *pMinecraft = Minecraft::GetInstance();
|
||||
LevelData *pLevelData=levelNormalDimension->getLevelData();
|
||||
|
|
@ -1077,6 +1308,8 @@ void MinecraftServer::run(__int64 seed, void *lpParameter)
|
|||
|
||||
__int64 lastTime = System::currentTimeMillis();
|
||||
__int64 unprocessedTime = 0;
|
||||
m_lastTpsSampleMs = lastTime;
|
||||
m_lastTpsSampleTick = tickCount;
|
||||
while (running && !s_bServerHalted)
|
||||
{
|
||||
__int64 now = System::currentTimeMillis();
|
||||
|
|
@ -1152,6 +1385,21 @@ void MinecraftServer::run(__int64 seed, void *lpParameter)
|
|||
connection->tick();
|
||||
}
|
||||
}
|
||||
__int64 tpsNow = System::currentTimeMillis();
|
||||
__int64 tpsElapsed = tpsNow - m_lastTpsSampleMs;
|
||||
if (tpsElapsed >= 1000)
|
||||
{
|
||||
int tickDelta = tickCount - m_lastTpsSampleTick;
|
||||
if (tpsElapsed > 0)
|
||||
{
|
||||
m_recentTps = ((float)tickDelta * 1000.0f) / (float)tpsElapsed;
|
||||
if (m_recentTps < 0.0f) m_recentTps = 0.0f;
|
||||
float maxTps = (float)SharedConstants::TICKS_PER_SECOND;
|
||||
if (m_recentTps > maxTps) m_recentTps = maxTps;
|
||||
}
|
||||
m_lastTpsSampleMs = tpsNow;
|
||||
m_lastTpsSampleTick = tickCount;
|
||||
}
|
||||
if(MinecraftServer::setTimeAtEndOfTick)
|
||||
{
|
||||
MinecraftServer::setTimeAtEndOfTick = false;
|
||||
|
|
@ -1468,6 +1716,11 @@ void MinecraftServer::tick()
|
|||
// 4J Stu - We set the levels difficulty based on the minecraft options
|
||||
level->difficulty = app.GetGameHostOption(eGameHostOption_Difficulty); //pMinecraft->options->difficulty;
|
||||
|
||||
if (i == 0 && IsBedwarsHubSettings(app.GetGameHostOption(eGameHostOption_All)))
|
||||
{
|
||||
KeepBedwarsLobbyNpcsStationary(level);
|
||||
}
|
||||
|
||||
#if DEBUG_SERVER_DONT_SPAWN_MOBS
|
||||
level->setSpawnSettings(false, false);
|
||||
#else
|
||||
|
|
@ -1682,4 +1935,14 @@ bool MinecraftServer::flagEntitiesToBeRemoved(unsigned int *flags)
|
|||
}
|
||||
}
|
||||
return removedFound;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -111,6 +111,9 @@ public:
|
|||
private:
|
||||
// 4J Added
|
||||
//int m_lastSentDifficulty;
|
||||
float m_recentTps;
|
||||
__int64 m_lastTpsSampleMs;
|
||||
int m_lastTpsSampleTick;
|
||||
|
||||
public:
|
||||
// 4J Stu - This value should be incremented every time the list of players with friends-only UGC settings changes
|
||||
|
|
@ -236,6 +239,7 @@ public:
|
|||
//static int getSlowQueueIndex() { return s_slowQueuePlayerIndex; }
|
||||
static bool canSendOnSlowQueue(INetworkPlayer *player);
|
||||
static void cycleSlowQueueIndex();
|
||||
float getRecentTps() const { return m_recentTps; }
|
||||
|
||||
void setSaveOnExit(bool save) { m_saveOnExit = save; s_bSaveOnExitAnswered = true; }
|
||||
void Suspend();
|
||||
|
|
|
|||
|
|
@ -102,12 +102,20 @@ MultiPlayerChunkCache::~MultiPlayerChunkCache()
|
|||
{
|
||||
delete emptyChunk;
|
||||
delete waterChunk;
|
||||
delete cache;
|
||||
delete hasData;
|
||||
// Defensive: avoid deleting loaded chunk objects here.
|
||||
// During transfer/exit there can still be shared or duplicated references to chunk internals
|
||||
// (especially light storage) across teardown paths, which can lead to double-free crashes.
|
||||
// We release cache containers and clear references; chunk memory is reclaimed with process lifetime.
|
||||
EnterCriticalSection(&m_csLoadCreate);
|
||||
if (cache != NULL)
|
||||
{
|
||||
memset(cache, 0, XZSIZE * XZSIZE * sizeof(LevelChunk *));
|
||||
}
|
||||
loadedChunkList.clear();
|
||||
LeaveCriticalSection(&m_csLoadCreate);
|
||||
|
||||
AUTO_VAR(itEnd, loadedChunkList.end());
|
||||
for (AUTO_VAR(it, loadedChunkList.begin()); it != itEnd; it++)
|
||||
delete *it;
|
||||
delete[] cache;
|
||||
delete[] hasData;
|
||||
|
||||
DeleteCriticalSection(&m_csLoadCreate);
|
||||
}
|
||||
|
|
@ -172,7 +180,11 @@ LevelChunk *MultiPlayerChunkCache::create(int x, int z)
|
|||
if( g_NetworkManager.IsHost() ) // force here to disable sharing of data
|
||||
{
|
||||
// 4J-JEV: We are about to use shared data, abort if the server is stopped and the data is deleted.
|
||||
if (MinecraftServer::getInstance()->serverHalted()) return NULL;
|
||||
if (MinecraftServer::getInstance()->serverHalted())
|
||||
{
|
||||
LeaveCriticalSection(&m_csLoadCreate);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// If we're the host, then don't create the chunk, share data from the server's copy
|
||||
#ifdef _LARGE_WORLDS
|
||||
|
|
@ -303,4 +315,4 @@ void MultiPlayerChunkCache::dataReceived(int x, int z)
|
|||
if( ( iz < 0 ) || ( iz >= XZSIZE ) ) return;
|
||||
int idx = ix * XZSIZE + iz;
|
||||
hasData[idx] = true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
#include "..\Minecraft.World\net.minecraft.world.item.h"
|
||||
#include "..\Minecraft.World\SharedConstants.h"
|
||||
#include "Settings.h"
|
||||
#include "Common\Network\NetworkPlayerInterface.h"
|
||||
// #ifdef __PS3__
|
||||
// #include "PS3\Network\NetworkPlayerSony.h"
|
||||
// #endif
|
||||
|
|
@ -21,7 +22,9 @@
|
|||
Random *PendingConnection::random = new Random();
|
||||
|
||||
#ifdef _WINDOWS64
|
||||
bool g_bRejectDuplicateNames = true;
|
||||
// Windows64 LAN/minigame testing commonly uses repeated display names across clients.
|
||||
// Keep joins permissive by default; duplicate names can still be rejected by toggling this.
|
||||
bool g_bRejectDuplicateNames = false;
|
||||
#endif
|
||||
|
||||
PendingConnection::PendingConnection(MinecraftServer *server, Socket *socket, const wstring& id)
|
||||
|
|
@ -161,13 +164,51 @@ void PendingConnection::handleLogin(shared_ptr<LoginPacket> packet)
|
|||
|
||||
//if (true)// 4J removed !server->onlineMode)
|
||||
bool sentDisconnect = false;
|
||||
if (server->getPlayers()->isNameBanned(name))
|
||||
{
|
||||
app.DebugPrintf("Rejecting banned player name: %ls\n", name.c_str());
|
||||
disconnect(DisconnectPacket::eDisconnect_Banned);
|
||||
return;
|
||||
}
|
||||
if (server->getPlayers()->isWhitelistEnabled() && !server->getPlayers()->isWhiteListed(name))
|
||||
{
|
||||
app.DebugPrintf("Rejecting non-whitelisted player name: %ls\n", name.c_str());
|
||||
disconnect(DisconnectPacket::eDisconnect_Kicked);
|
||||
return;
|
||||
}
|
||||
PlayerUID onlineXuidForBanCheck = packet->m_onlineXuid;
|
||||
#ifdef _WINDOWS64
|
||||
BYTE onlineSmallIdForBanCheck = 255;
|
||||
if (connection != NULL && connection->getSocket() != NULL)
|
||||
{
|
||||
INetworkPlayer *networkPlayer = connection->getSocket()->getPlayer();
|
||||
if (networkPlayer != NULL)
|
||||
{
|
||||
onlineXuidForBanCheck = networkPlayer->GetUID();
|
||||
onlineSmallIdForBanCheck = networkPlayer->GetSmallId();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
bool rejectAsBanned = server->getPlayers()->isXuidBanned(onlineXuidForBanCheck);
|
||||
#ifdef _WINDOWS64
|
||||
if (rejectAsBanned)
|
||||
{
|
||||
// Windows64 stub player identity is slot-based, so suppress persistent ban rejections
|
||||
// to avoid false "previously kicked" failures for new joiners.
|
||||
app.DebugPrintf("PendingConnection::handleLogin - suppressed stale ban for %ls (smallId=%u)\n",
|
||||
name.c_str(),
|
||||
(unsigned int)onlineSmallIdForBanCheck);
|
||||
rejectAsBanned = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
if( sentDisconnect )
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
else if( server->getPlayers()->isXuidBanned( packet->m_onlineXuid ) )
|
||||
else if( rejectAsBanned )
|
||||
{
|
||||
app.DebugPrintf("Rejecting banned XUID for player: %ls\n", name.c_str());
|
||||
disconnect(DisconnectPacket::eDisconnect_Banned);
|
||||
}
|
||||
#ifdef _WINDOWS64
|
||||
|
|
@ -186,7 +227,8 @@ void PendingConnection::handleLogin(shared_ptr<LoginPacket> packet)
|
|||
if (nameTaken)
|
||||
{
|
||||
app.DebugPrintf("Rejecting duplicate name: %ls\n", name.c_str());
|
||||
disconnect(DisconnectPacket::eDisconnect_Banned);
|
||||
// Don't map duplicate-name rejection to "banned by host".
|
||||
disconnect(DisconnectPacket::eDisconnect_Kicked);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -294,4 +336,4 @@ wstring PendingConnection::getName()
|
|||
bool PendingConnection::isServerPacketListener()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -24,6 +24,9 @@
|
|||
#include "..\Minecraft.World\net.minecraft.world.level.storage.h"
|
||||
#include "..\Minecraft.World\net.minecraft.world.level.saveddata.h"
|
||||
#include "..\Minecraft.World\JavaMath.h"
|
||||
#include <fstream>
|
||||
#include <algorithm>
|
||||
#include <cwctype>
|
||||
#if defined(_XBOX) || defined(_WINDOWS64)
|
||||
#include "Xbox\Network\NetworkPlayerXbox.h"
|
||||
#elif defined(__PS3__) || defined(__ORBIS__)
|
||||
|
|
@ -31,6 +34,68 @@
|
|||
#endif
|
||||
|
||||
// 4J - this class is fairly substantially altered as there didn't seem any point in porting code for banning, whitelisting, ops etc.
|
||||
namespace
|
||||
{
|
||||
static const wchar_t *kWhitelistFile = L"whitelist.txt";
|
||||
static const wchar_t *kOpsFile = L"ops.txt";
|
||||
static const wchar_t *kBansFile = L"banned-players.txt";
|
||||
|
||||
static wstring NormalizePlayerName(const wstring &name)
|
||||
{
|
||||
wstring out = name;
|
||||
std::transform(out.begin(), out.end(), out.begin(), [](wchar_t c) { return (wchar_t)std::towlower(c); });
|
||||
return out;
|
||||
}
|
||||
|
||||
static void LoadNameSetFromFile(const wchar_t *fileName, set<wstring> &outSet)
|
||||
{
|
||||
outSet.clear();
|
||||
std::wifstream in(fileName);
|
||||
if (!in.good())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
wstring line;
|
||||
while (std::getline(in, line))
|
||||
{
|
||||
// Strip comments.
|
||||
size_t hashPos = line.find(L'#');
|
||||
if (hashPos != wstring::npos)
|
||||
{
|
||||
line = line.substr(0, hashPos);
|
||||
}
|
||||
|
||||
while (!line.empty() && iswspace(line.front()))
|
||||
{
|
||||
line.erase(line.begin());
|
||||
}
|
||||
while (!line.empty() && iswspace(line.back()))
|
||||
{
|
||||
line.pop_back();
|
||||
}
|
||||
|
||||
if (!line.empty())
|
||||
{
|
||||
outSet.insert(NormalizePlayerName(line));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void SaveNameSetToFile(const wchar_t *fileName, const set<wstring> &values)
|
||||
{
|
||||
std::wofstream out(fileName, std::ios::out | std::ios::trunc);
|
||||
if (!out.good())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (AUTO_VAR(it, values.begin()); it != values.end(); ++it)
|
||||
{
|
||||
out << *it << L"\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PlayerList::PlayerList(MinecraftServer *server)
|
||||
{
|
||||
|
|
@ -58,6 +123,10 @@ PlayerList::PlayerList(MinecraftServer *server)
|
|||
maxPlayers = server->settings->getInt(L"max-players", 20);
|
||||
#endif
|
||||
doWhiteList = false;
|
||||
|
||||
reloadWhitelist();
|
||||
reloadOps();
|
||||
reloadBans();
|
||||
|
||||
InitializeCriticalSection(&m_kickPlayersCS);
|
||||
InitializeCriticalSection(&m_closePlayersCS);
|
||||
|
|
@ -90,6 +159,12 @@ void PlayerList::placeNewPlayer(Connection *connection, shared_ptr<ServerPlayer>
|
|||
player->setPlayerGamePrivilege(Player::ePlayerGamePrivilege_HOST,1);
|
||||
}
|
||||
|
||||
// Apply persisted operator status on join (dedicated and local-host modes).
|
||||
if (isOp(player->name))
|
||||
{
|
||||
player->setPlayerGamePrivilege(Player::ePlayerGamePrivilege_Op, 1);
|
||||
}
|
||||
|
||||
#if defined(__PS3__) || defined(__ORBIS__)
|
||||
// PS3 networking library doesn't automatically assign PlayerUIDs to the network players for anything remote, so need to tell it what to set from the data in this packet now
|
||||
if( !g_NetworkManager.IsLocalGame() )
|
||||
|
|
@ -467,8 +542,64 @@ shared_ptr<ServerPlayer> PlayerList::getPlayerForLogin(PendingConnection *pendin
|
|||
return shared_ptr<ServerPlayer>();
|
||||
}
|
||||
#endif
|
||||
|
||||
if (isNameBanned(userName))
|
||||
{
|
||||
pendingConnection->disconnect(DisconnectPacket::eDisconnect_Banned);
|
||||
return shared_ptr<ServerPlayer>();
|
||||
}
|
||||
|
||||
if (doWhiteList)
|
||||
{
|
||||
INetworkPlayer *joiningNetworkPlayer = NULL;
|
||||
if (pendingConnection != NULL && pendingConnection->connection != NULL && pendingConnection->connection->getSocket() != NULL)
|
||||
{
|
||||
joiningNetworkPlayer = pendingConnection->connection->getSocket()->getPlayer();
|
||||
}
|
||||
|
||||
if (joiningNetworkPlayer == NULL || !joiningNetworkPlayer->IsHost())
|
||||
{
|
||||
if (!isWhiteListed(userName))
|
||||
{
|
||||
app.DebugPrintf("PlayerList::getPlayerForLogin - rejecting non-whitelisted player %ls\n", userName.c_str());
|
||||
pendingConnection->disconnect(DisconnectPacket::eDisconnect_Kicked);
|
||||
return shared_ptr<ServerPlayer>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
shared_ptr<ServerPlayer> player = shared_ptr<ServerPlayer>(new ServerPlayer(server, server->getLevel(0), userName, new ServerPlayerGameMode(server->getLevel(0)) ));
|
||||
wstring resolvedName = userName;
|
||||
#ifdef _WINDOWS64
|
||||
// Win64 testing often has multiple clients with the same OS username.
|
||||
// Keep server-side player names unique to avoid legacy name-based collisions.
|
||||
if (!resolvedName.empty())
|
||||
{
|
||||
const wstring baseName = resolvedName;
|
||||
int suffix = 2;
|
||||
bool unique = false;
|
||||
while (!unique)
|
||||
{
|
||||
unique = true;
|
||||
for (AUTO_VAR(it, players.begin()); it != players.end(); ++it)
|
||||
{
|
||||
shared_ptr<ServerPlayer> existing = *it;
|
||||
if (existing != NULL && existing->name == resolvedName)
|
||||
{
|
||||
const int currentSuffix = suffix++;
|
||||
wstring trimmedBase = baseName;
|
||||
if (trimmedBase.length() > 56)
|
||||
{
|
||||
trimmedBase = trimmedBase.substr(0, 56);
|
||||
}
|
||||
resolvedName = trimmedBase + L"_" + to_wstring(currentSuffix);
|
||||
unique = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
shared_ptr<ServerPlayer> player = shared_ptr<ServerPlayer>(new ServerPlayer(server, server->getLevel(0), resolvedName, new ServerPlayerGameMode(server->getLevel(0)) ));
|
||||
player->gameMode->player = player; // 4J added as had to remove this assignment from ServerPlayer ctor
|
||||
player->setXuid( xuid ); // 4J Added
|
||||
player->setOnlineXuid( onlineXuid ); // 4J Added
|
||||
|
|
@ -930,7 +1061,14 @@ void PlayerList::tick()
|
|||
|
||||
if (player != NULL)
|
||||
{
|
||||
#ifdef _WINDOWS64
|
||||
// Keep kicks session-scoped on Windows64. The stub identity maps to slot ids, so
|
||||
// persisting bans can incorrectly block later joiners that reuse a slot.
|
||||
app.DebugPrintf("PlayerList::tick - kicking smallId=%u (no persistent ban on Windows64)\n",
|
||||
(unsigned int)smallId);
|
||||
#else
|
||||
m_bannedXuids.push_back( player->getOnlineXuid() );
|
||||
#endif
|
||||
// 4J Stu - If we have kicked a player, make sure that they have no privileges if they later try to join the world when trust players is off
|
||||
player->enableAllPlayerPrivileges( false );
|
||||
player->connection->setWasKicked();
|
||||
|
|
@ -1003,12 +1141,16 @@ wstring PlayerList::getPlayerNames()
|
|||
|
||||
bool PlayerList::isWhiteListed(const wstring& name)
|
||||
{
|
||||
return true;
|
||||
if (!doWhiteList)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return (m_whitelistNames.find(NormalizePlayerName(name)) != m_whitelistNames.end());
|
||||
}
|
||||
|
||||
bool PlayerList::isOp(const wstring& name)
|
||||
{
|
||||
return false;
|
||||
return (m_operatorNames.find(NormalizePlayerName(name)) != m_operatorNames.end());
|
||||
}
|
||||
|
||||
bool PlayerList::isOp(shared_ptr<ServerPlayer> player)
|
||||
|
|
@ -1177,14 +1319,90 @@ void PlayerList::saveAll(ProgressListener *progressListener, bool bDeleteGuestMa
|
|||
|
||||
void PlayerList::whiteList(const wstring& playerName)
|
||||
{
|
||||
m_whitelistNames.insert(NormalizePlayerName(playerName));
|
||||
SaveNameSetToFile(kWhitelistFile, m_whitelistNames);
|
||||
}
|
||||
|
||||
void PlayerList::blackList(const wstring& playerName)
|
||||
{
|
||||
m_whitelistNames.erase(NormalizePlayerName(playerName));
|
||||
SaveNameSetToFile(kWhitelistFile, m_whitelistNames);
|
||||
}
|
||||
|
||||
void PlayerList::reloadWhitelist()
|
||||
{
|
||||
LoadNameSetFromFile(kWhitelistFile, m_whitelistNames);
|
||||
}
|
||||
|
||||
void PlayerList::setWhitelistEnabled(bool enabled)
|
||||
{
|
||||
doWhiteList = enabled;
|
||||
}
|
||||
|
||||
bool PlayerList::isWhitelistEnabled() const
|
||||
{
|
||||
return doWhiteList;
|
||||
}
|
||||
|
||||
bool PlayerList::addOp(const wstring &playerName)
|
||||
{
|
||||
const size_t oldSize = m_operatorNames.size();
|
||||
m_operatorNames.insert(NormalizePlayerName(playerName));
|
||||
if (m_operatorNames.size() != oldSize)
|
||||
{
|
||||
SaveNameSetToFile(kOpsFile, m_operatorNames);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PlayerList::removeOp(const wstring &playerName)
|
||||
{
|
||||
const size_t erased = m_operatorNames.erase(NormalizePlayerName(playerName));
|
||||
if (erased != 0)
|
||||
{
|
||||
SaveNameSetToFile(kOpsFile, m_operatorNames);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void PlayerList::reloadOps()
|
||||
{
|
||||
LoadNameSetFromFile(kOpsFile, m_operatorNames);
|
||||
}
|
||||
|
||||
bool PlayerList::banName(const wstring &playerName)
|
||||
{
|
||||
const size_t oldSize = m_bannedNames.size();
|
||||
m_bannedNames.insert(NormalizePlayerName(playerName));
|
||||
if (m_bannedNames.size() != oldSize)
|
||||
{
|
||||
SaveNameSetToFile(kBansFile, m_bannedNames);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PlayerList::unbanName(const wstring &playerName)
|
||||
{
|
||||
const size_t erased = m_bannedNames.erase(NormalizePlayerName(playerName));
|
||||
if (erased != 0)
|
||||
{
|
||||
SaveNameSetToFile(kBansFile, m_bannedNames);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void PlayerList::reloadBans()
|
||||
{
|
||||
LoadNameSetFromFile(kBansFile, m_bannedNames);
|
||||
}
|
||||
|
||||
bool PlayerList::isNameBanned(const wstring &name) const
|
||||
{
|
||||
return (m_bannedNames.find(NormalizePlayerName(name)) != m_bannedNames.end());
|
||||
}
|
||||
|
||||
void PlayerList::sendLevelInfo(shared_ptr<ServerPlayer> player, ServerLevel *level)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#pragma once
|
||||
#include <deque>
|
||||
#include <set>
|
||||
#include "..\Minecraft.World\ArrayWithLength.h"
|
||||
|
||||
class ServerPlayer;
|
||||
|
|
@ -34,6 +35,9 @@ private:
|
|||
CRITICAL_SECTION m_kickPlayersCS;
|
||||
deque<BYTE> m_smallIdsToClose;
|
||||
CRITICAL_SECTION m_closePlayersCS;
|
||||
set<wstring> m_whitelistNames;
|
||||
set<wstring> m_operatorNames;
|
||||
set<wstring> m_bannedNames;
|
||||
/* 4J - removed
|
||||
Set<String> bans = new HashSet<String>();
|
||||
Set<String> ipBans = new HashSet<String>();
|
||||
|
|
@ -99,10 +103,19 @@ public:
|
|||
bool sendTo(const wstring& name, shared_ptr<Packet> packet);
|
||||
// 4J Added ProgressListener *progressListener param and bDeleteGuestMaps param
|
||||
void saveAll(ProgressListener *progressListener, bool bDeleteGuestMaps = false);
|
||||
void whiteList(const wstring& playerName);
|
||||
void whiteList(const wstring& playerName);
|
||||
void blackList(const wstring& playerName);
|
||||
// Set<String> getWhiteList(); / 4J removed
|
||||
void reloadWhitelist();
|
||||
void setWhitelistEnabled(bool enabled);
|
||||
bool isWhitelistEnabled() const;
|
||||
bool addOp(const wstring &playerName);
|
||||
bool removeOp(const wstring &playerName);
|
||||
void reloadOps();
|
||||
bool banName(const wstring &playerName);
|
||||
bool unbanName(const wstring &playerName);
|
||||
void reloadBans();
|
||||
bool isNameBanned(const wstring &name) const;
|
||||
void sendLevelInfo(shared_ptr<ServerPlayer> player, ServerLevel *level);
|
||||
void sendAllPlayerInfo(shared_ptr<ServerPlayer> player);
|
||||
int getPlayerCount();
|
||||
|
|
|
|||
|
|
@ -38,6 +38,11 @@ void Screen::keyPressed(wchar_t eventCharacter, int eventKey)
|
|||
}
|
||||
}
|
||||
|
||||
void Screen::HandleKeyPressed(wchar_t eventCharacter, int eventKey)
|
||||
{
|
||||
keyPressed(eventCharacter, eventKey);
|
||||
}
|
||||
|
||||
wstring Screen::getClipboard()
|
||||
{
|
||||
// 4J - removed
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ protected:
|
|||
public:
|
||||
static wstring getClipboard();
|
||||
static void setClipboard(const wstring& str);
|
||||
void HandleKeyPressed(wchar_t eventCharacter, int eventKey);
|
||||
private:
|
||||
Button *clickedButton;
|
||||
|
||||
|
|
@ -51,4 +52,3 @@ public:
|
|||
virtual void confirmResult(bool result, int id);
|
||||
virtual void tabPressed();
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#include "Settings.h"
|
||||
#include "PlayerList.h"
|
||||
#include "MultiPlayerLevel.h"
|
||||
#include "TextEditScreen.h"
|
||||
#include "..\Minecraft.World\Pos.h"
|
||||
#include "..\Minecraft.World\net.minecraft.world.level.h"
|
||||
#include "..\Minecraft.World\net.minecraft.world.level.storage.h"
|
||||
|
|
@ -269,6 +270,24 @@ void ServerPlayer::flushEntitiesToRemove()
|
|||
}
|
||||
|
||||
|
||||
void ServerPlayer::openTextEdit(shared_ptr<SignTileEntity> sign)
|
||||
{
|
||||
if (sign == NULL || connection == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (connection->isLocal())
|
||||
{
|
||||
Minecraft *mc = Minecraft::GetInstance();
|
||||
if (mc != NULL)
|
||||
{
|
||||
app.DebugPrintf("ServerPlayer::openTextEdit - opening TextEditScreen for local player");
|
||||
mc->setScreen(new TextEditScreen(sign));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 4J - have split doTick into 3 bits, so that we can call the doChunkSendingTick separately, but still do the equivalent of what calling a full doTick used to do, by calling this method
|
||||
void ServerPlayer::doTick(bool sendChunks, bool dontDelayChunks/*=false*/, bool ignorePortal/*=false*/)
|
||||
{
|
||||
|
|
@ -445,7 +464,7 @@ void ServerPlayer::doChunkSendingTick(bool dontDelayChunks)
|
|||
for (unsigned int i = 0; i < tes->size(); i++)
|
||||
{
|
||||
// 4J Stu - Added delay param to ensure that these arrive after the BRUPs from above
|
||||
// Fix for #9169 - ART : Sign text is replaced with the words “Awaiting approval”.
|
||||
// Fix for #9169 - ART : Sign text is replaced with the words ?Awaiting approval?.
|
||||
broadcast(tes->at(i), !connection->isLocal() && !dontDelayChunks);
|
||||
}
|
||||
delete tes;
|
||||
|
|
|
|||
|
|
@ -97,6 +97,7 @@ public:
|
|||
virtual bool startCrafting(int x, int y, int z); // 4J added bool return
|
||||
virtual bool startEnchanting(int x, int y, int z); // 4J added bool return
|
||||
virtual bool startRepairing(int x, int y, int z); // 4J added bool return
|
||||
virtual void openTextEdit(shared_ptr<SignTileEntity> sign);
|
||||
virtual bool openContainer(shared_ptr<Container> container); // 4J added bool return
|
||||
virtual bool openFurnace(shared_ptr<FurnaceTileEntity> furnace); // 4J added bool return
|
||||
virtual bool openTrap(shared_ptr<DispenserTileEntity> trap); // 4J added bool return
|
||||
|
|
|
|||
|
|
@ -62,6 +62,10 @@ void TextEditScreen::keyPressed(wchar_t ch, int eventKey)
|
|||
if (eventKey == Keyboard::KEY_DOWN || eventKey == Keyboard::KEY_RETURN) line = (line + 1) & 3;
|
||||
|
||||
wstring temp=sign->GetMessage(line);
|
||||
while (!temp.empty() && temp[temp.length() - 1] == L' ')
|
||||
{
|
||||
temp = temp.substr(0, temp.length() - 1);
|
||||
}
|
||||
if (eventKey == Keyboard::KEY_BACK && temp.length() > 0)
|
||||
{
|
||||
temp = temp.substr(0, temp.length() - 1);
|
||||
|
|
@ -116,4 +120,4 @@ void TextEditScreen::render(int xm, int ym, float a)
|
|||
|
||||
Screen::render(xm, ym, a);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,7 +47,28 @@ std::vector<BYTE> WinsockNetLayer::s_freeSmallIds;
|
|||
bool g_Win64MultiplayerHost = false;
|
||||
bool g_Win64MultiplayerJoin = false;
|
||||
int g_Win64MultiplayerPort = WIN64_NET_DEFAULT_PORT;
|
||||
char g_Win64MultiplayerIP[256] = "127.0.0.1";
|
||||
int g_Win64MultiplayerMaxPlayers = MINECRAFT_NET_MAX_PLAYERS;
|
||||
char g_Win64MultiplayerIP[256] = "0.0.0.0";
|
||||
BYTE WinsockNetLayer::s_maxPlayers = MINECRAFT_NET_MAX_PLAYERS;
|
||||
|
||||
static void ConfigureConnectedSocket(SOCKET sock)
|
||||
{
|
||||
if (sock == INVALID_SOCKET)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int noDelay = 1;
|
||||
setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (const char *)&noDelay, sizeof(noDelay));
|
||||
|
||||
int keepAlive = 1;
|
||||
setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (const char *)&keepAlive, sizeof(keepAlive));
|
||||
|
||||
int recvTimeoutMs = 30000;
|
||||
int sendTimeoutMs = 30000;
|
||||
setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (const char *)&recvTimeoutMs, sizeof(recvTimeoutMs));
|
||||
setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (const char *)&sendTimeoutMs, sizeof(sendTimeoutMs));
|
||||
}
|
||||
|
||||
bool WinsockNetLayer::Initialize()
|
||||
{
|
||||
|
|
@ -145,6 +166,14 @@ bool WinsockNetLayer::HostGame(int port)
|
|||
s_hostSmallId = 0;
|
||||
s_nextSmallId = 1;
|
||||
s_hostGamePort = port;
|
||||
if (g_Win64MultiplayerMaxPlayers >= 1 && g_Win64MultiplayerMaxPlayers <= MINECRAFT_NET_MAX_PLAYERS)
|
||||
{
|
||||
s_maxPlayers = (BYTE)g_Win64MultiplayerMaxPlayers;
|
||||
}
|
||||
else
|
||||
{
|
||||
s_maxPlayers = MINECRAFT_NET_MAX_PLAYERS;
|
||||
}
|
||||
|
||||
EnterCriticalSection(&s_freeSmallIdLock);
|
||||
s_freeSmallIds.clear();
|
||||
|
|
@ -161,7 +190,15 @@ bool WinsockNetLayer::HostGame(int port)
|
|||
char portStr[16];
|
||||
sprintf_s(portStr, "%d", port);
|
||||
|
||||
int iResult = getaddrinfo(NULL, portStr, &hints, &result);
|
||||
const char *bindIp = NULL;
|
||||
if (g_Win64MultiplayerIP[0] != 0 &&
|
||||
strcmp(g_Win64MultiplayerIP, "*") != 0 &&
|
||||
strcmp(g_Win64MultiplayerIP, "0.0.0.0") != 0)
|
||||
{
|
||||
bindIp = g_Win64MultiplayerIP;
|
||||
}
|
||||
|
||||
int iResult = getaddrinfo(bindIp, portStr, &hints, &result);
|
||||
if (iResult != 0)
|
||||
{
|
||||
app.DebugPrintf("getaddrinfo failed: %d\n", iResult);
|
||||
|
|
@ -189,7 +226,8 @@ bool WinsockNetLayer::HostGame(int port)
|
|||
return false;
|
||||
}
|
||||
|
||||
iResult = listen(s_listenSocket, SOMAXCONN);
|
||||
int backlog = (s_maxPlayers > 1) ? (int)s_maxPlayers : 1;
|
||||
iResult = listen(s_listenSocket, backlog);
|
||||
if (iResult == SOCKET_ERROR)
|
||||
{
|
||||
app.DebugPrintf("listen() failed: %d\n", WSAGetLastError());
|
||||
|
|
@ -203,7 +241,10 @@ bool WinsockNetLayer::HostGame(int port)
|
|||
|
||||
s_acceptThread = CreateThread(NULL, 0, AcceptThreadProc, NULL, 0, NULL);
|
||||
|
||||
app.DebugPrintf("Win64 LAN: Hosting on port %d\n", port);
|
||||
app.DebugPrintf("Win64 LAN: Hosting on %s:%d (maxPlayers=%u)\n",
|
||||
(bindIp != NULL) ? bindIp : "0.0.0.0",
|
||||
port,
|
||||
(unsigned int)s_maxPlayers);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -213,6 +254,14 @@ bool WinsockNetLayer::JoinGame(const char *ip, int port)
|
|||
|
||||
s_isHost = false;
|
||||
s_hostSmallId = 0;
|
||||
s_connected = false;
|
||||
s_active = false;
|
||||
|
||||
if (s_hostConnectionSocket != INVALID_SOCKET)
|
||||
{
|
||||
closesocket(s_hostConnectionSocket);
|
||||
s_hostConnectionSocket = INVALID_SOCKET;
|
||||
}
|
||||
|
||||
struct addrinfo hints = {};
|
||||
struct addrinfo *result = NULL;
|
||||
|
|
@ -231,37 +280,54 @@ bool WinsockNetLayer::JoinGame(const char *ip, int port)
|
|||
return false;
|
||||
}
|
||||
|
||||
s_hostConnectionSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
|
||||
if (s_hostConnectionSocket == INVALID_SOCKET)
|
||||
bool connected = false;
|
||||
BYTE assignedSmallId = 0;
|
||||
const int maxAttempts = 12;
|
||||
|
||||
for (int attempt = 0; attempt < maxAttempts; ++attempt)
|
||||
{
|
||||
app.DebugPrintf("socket() failed: %d\n", WSAGetLastError());
|
||||
freeaddrinfo(result);
|
||||
return false;
|
||||
s_hostConnectionSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
|
||||
if (s_hostConnectionSocket == INVALID_SOCKET)
|
||||
{
|
||||
app.DebugPrintf("socket() failed: %d\n", WSAGetLastError());
|
||||
break;
|
||||
}
|
||||
|
||||
ConfigureConnectedSocket(s_hostConnectionSocket);
|
||||
|
||||
iResult = connect(s_hostConnectionSocket, result->ai_addr, (int)result->ai_addrlen);
|
||||
if (iResult == SOCKET_ERROR)
|
||||
{
|
||||
int err = WSAGetLastError();
|
||||
app.DebugPrintf("connect() to %s:%d failed (attempt %d/%d): %d\n", ip, port, attempt + 1, maxAttempts, err);
|
||||
closesocket(s_hostConnectionSocket);
|
||||
s_hostConnectionSocket = INVALID_SOCKET;
|
||||
Sleep(200);
|
||||
continue;
|
||||
}
|
||||
|
||||
BYTE assignBuf[1];
|
||||
int bytesRecv = recv(s_hostConnectionSocket, (char *)assignBuf, 1, 0);
|
||||
if (bytesRecv != 1)
|
||||
{
|
||||
app.DebugPrintf("Failed to receive small ID assignment from host (attempt %d/%d)\n", attempt + 1, maxAttempts);
|
||||
closesocket(s_hostConnectionSocket);
|
||||
s_hostConnectionSocket = INVALID_SOCKET;
|
||||
Sleep(200);
|
||||
continue;
|
||||
}
|
||||
|
||||
assignedSmallId = assignBuf[0];
|
||||
connected = true;
|
||||
break;
|
||||
}
|
||||
|
||||
int noDelay = 1;
|
||||
setsockopt(s_hostConnectionSocket, IPPROTO_TCP, TCP_NODELAY, (const char *)&noDelay, sizeof(noDelay));
|
||||
|
||||
iResult = connect(s_hostConnectionSocket, result->ai_addr, (int)result->ai_addrlen);
|
||||
freeaddrinfo(result);
|
||||
if (iResult == SOCKET_ERROR)
|
||||
{
|
||||
app.DebugPrintf("connect() to %s:%d failed: %d\n", ip, port, WSAGetLastError());
|
||||
closesocket(s_hostConnectionSocket);
|
||||
s_hostConnectionSocket = INVALID_SOCKET;
|
||||
return false;
|
||||
}
|
||||
|
||||
BYTE assignBuf[1];
|
||||
int bytesRecv = recv(s_hostConnectionSocket, (char *)assignBuf, 1, 0);
|
||||
if (bytesRecv != 1)
|
||||
if (!connected)
|
||||
{
|
||||
app.DebugPrintf("Failed to receive small ID assignment from host\n");
|
||||
closesocket(s_hostConnectionSocket);
|
||||
s_hostConnectionSocket = INVALID_SOCKET;
|
||||
return false;
|
||||
}
|
||||
s_localSmallId = assignBuf[0];
|
||||
s_localSmallId = assignedSmallId;
|
||||
|
||||
app.DebugPrintf("Win64 LAN: Connected to %s:%d, assigned smallId=%d\n", ip, port, s_localSmallId);
|
||||
|
||||
|
|
@ -363,16 +429,22 @@ void WinsockNetLayer::HandleDataReceived(BYTE fromSmallId, BYTE toSmallId, unsig
|
|||
INetworkPlayer *pPlayerFrom = g_NetworkManager.GetPlayerBySmallId(fromSmallId);
|
||||
INetworkPlayer *pPlayerTo = g_NetworkManager.GetPlayerBySmallId(toSmallId);
|
||||
|
||||
if (pPlayerFrom == NULL || pPlayerTo == NULL) return;
|
||||
|
||||
if (s_isHost)
|
||||
{
|
||||
if (pPlayerFrom == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
::Socket *pSocket = pPlayerFrom->GetSocket();
|
||||
if (pSocket != NULL)
|
||||
pSocket->pushDataToQueue(data, dataSize, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pPlayerTo == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
::Socket *pSocket = pPlayerTo->GetSocket();
|
||||
if (pSocket != NULL)
|
||||
pSocket->pushDataToQueue(data, dataSize, true);
|
||||
|
|
@ -391,8 +463,7 @@ DWORD WINAPI WinsockNetLayer::AcceptThreadProc(LPVOID param)
|
|||
break;
|
||||
}
|
||||
|
||||
int noDelay = 1;
|
||||
setsockopt(clientSocket, IPPROTO_TCP, TCP_NODELAY, (const char *)&noDelay, sizeof(noDelay));
|
||||
ConfigureConnectedSocket(clientSocket);
|
||||
|
||||
extern QNET_STATE _iQNetStubState;
|
||||
if (_iQNetStubState != QNET_STATE_GAME_PLAY)
|
||||
|
|
@ -409,7 +480,7 @@ DWORD WINAPI WinsockNetLayer::AcceptThreadProc(LPVOID param)
|
|||
assignedSmallId = s_freeSmallIds.back();
|
||||
s_freeSmallIds.pop_back();
|
||||
}
|
||||
else if (s_nextSmallId < MINECRAFT_NET_MAX_PLAYERS)
|
||||
else if (s_nextSmallId < s_maxPlayers)
|
||||
{
|
||||
assignedSmallId = s_nextSmallId++;
|
||||
}
|
||||
|
|
@ -479,7 +550,8 @@ DWORD WINAPI WinsockNetLayer::RecvThreadProc(LPVOID param)
|
|||
BYTE clientSmallId = s_connections[connIdx].smallId;
|
||||
LeaveCriticalSection(&s_connectionsLock);
|
||||
|
||||
BYTE *recvBuf = new BYTE[WIN64_NET_RECV_BUFFER_SIZE];
|
||||
std::vector<BYTE> recvBuf;
|
||||
recvBuf.resize(WIN64_NET_RECV_BUFFER_SIZE);
|
||||
|
||||
while (s_active)
|
||||
{
|
||||
|
|
@ -492,23 +564,30 @@ DWORD WINAPI WinsockNetLayer::RecvThreadProc(LPVOID param)
|
|||
|
||||
int packetSize = (header[0] << 24) | (header[1] << 16) | (header[2] << 8) | header[3];
|
||||
|
||||
if (packetSize <= 0 || packetSize > WIN64_NET_RECV_BUFFER_SIZE)
|
||||
if (packetSize <= 0 || packetSize > WIN64_NET_MAX_PACKET_SIZE)
|
||||
{
|
||||
app.DebugPrintf("Win64 LAN: Invalid packet size %d from client smallId=%d\n", packetSize, clientSmallId);
|
||||
app.DebugPrintf("Win64 LAN: Invalid packet size %d from client smallId=%d (max=%d)\n",
|
||||
packetSize,
|
||||
clientSmallId,
|
||||
(int)WIN64_NET_MAX_PACKET_SIZE);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!RecvExact(sock, recvBuf, packetSize))
|
||||
if ((int)recvBuf.size() < packetSize)
|
||||
{
|
||||
recvBuf.resize(packetSize);
|
||||
app.DebugPrintf("Win64 LAN: Resized host recv buffer to %d bytes for client smallId=%d\n", packetSize, clientSmallId);
|
||||
}
|
||||
|
||||
if (!RecvExact(sock, &recvBuf[0], packetSize))
|
||||
{
|
||||
app.DebugPrintf("Win64 LAN: Client smallId=%d disconnected (body)\n", clientSmallId);
|
||||
break;
|
||||
}
|
||||
|
||||
HandleDataReceived(clientSmallId, s_hostSmallId, recvBuf, packetSize);
|
||||
HandleDataReceived(clientSmallId, s_hostSmallId, &recvBuf[0], packetSize);
|
||||
}
|
||||
|
||||
delete[] recvBuf;
|
||||
|
||||
EnterCriticalSection(&s_connectionsLock);
|
||||
for (size_t i = 0; i < s_connections.size(); i++)
|
||||
{
|
||||
|
|
@ -552,7 +631,8 @@ void WinsockNetLayer::PushFreeSmallId(BYTE smallId)
|
|||
|
||||
DWORD WINAPI WinsockNetLayer::ClientRecvThreadProc(LPVOID param)
|
||||
{
|
||||
BYTE *recvBuf = new BYTE[WIN64_NET_RECV_BUFFER_SIZE];
|
||||
std::vector<BYTE> recvBuf;
|
||||
recvBuf.resize(WIN64_NET_RECV_BUFFER_SIZE);
|
||||
|
||||
while (s_active && s_hostConnectionSocket != INVALID_SOCKET)
|
||||
{
|
||||
|
|
@ -565,28 +645,34 @@ DWORD WINAPI WinsockNetLayer::ClientRecvThreadProc(LPVOID param)
|
|||
|
||||
int packetSize = (header[0] << 24) | (header[1] << 16) | (header[2] << 8) | header[3];
|
||||
|
||||
if (packetSize <= 0 || packetSize > WIN64_NET_RECV_BUFFER_SIZE)
|
||||
if (packetSize <= 0 || packetSize > WIN64_NET_MAX_PACKET_SIZE)
|
||||
{
|
||||
app.DebugPrintf("Win64 LAN: Invalid packet size %d from host\n", packetSize);
|
||||
app.DebugPrintf("Win64 LAN: Invalid packet size %d from host (max=%d)\n",
|
||||
packetSize,
|
||||
(int)WIN64_NET_MAX_PACKET_SIZE);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!RecvExact(s_hostConnectionSocket, recvBuf, packetSize))
|
||||
if ((int)recvBuf.size() < packetSize)
|
||||
{
|
||||
recvBuf.resize(packetSize);
|
||||
app.DebugPrintf("Win64 LAN: Resized client recv buffer to %d bytes\n", packetSize);
|
||||
}
|
||||
|
||||
if (!RecvExact(s_hostConnectionSocket, &recvBuf[0], packetSize))
|
||||
{
|
||||
app.DebugPrintf("Win64 LAN: Disconnected from host (body)\n");
|
||||
break;
|
||||
}
|
||||
|
||||
HandleDataReceived(s_hostSmallId, s_localSmallId, recvBuf, packetSize);
|
||||
HandleDataReceived(s_hostSmallId, s_localSmallId, &recvBuf[0], packetSize);
|
||||
}
|
||||
|
||||
delete[] recvBuf;
|
||||
|
||||
s_connected = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool WinsockNetLayer::StartAdvertising(int gamePort, const wchar_t *hostName, unsigned int gameSettings, unsigned int texPackId, unsigned char subTexId, unsigned short netVer)
|
||||
bool WinsockNetLayer::StartAdvertising(int gamePort, const wchar_t *hostName, unsigned int gameSettings, unsigned int texPackId, unsigned char subTexId, unsigned short netVer, unsigned char maxPlayers)
|
||||
{
|
||||
if (s_advertising) return true;
|
||||
if (!s_initialized) return false;
|
||||
|
|
@ -598,7 +684,7 @@ bool WinsockNetLayer::StartAdvertising(int gamePort, const wchar_t *hostName, un
|
|||
s_advertiseData.gamePort = (WORD)gamePort;
|
||||
wcsncpy_s(s_advertiseData.hostName, 32, hostName, _TRUNCATE);
|
||||
s_advertiseData.playerCount = 1;
|
||||
s_advertiseData.maxPlayers = MINECRAFT_NET_MAX_PLAYERS;
|
||||
s_advertiseData.maxPlayers = (maxPlayers > 0) ? maxPlayers : MINECRAFT_NET_MAX_PLAYERS;
|
||||
s_advertiseData.gameHostSettings = gameSettings;
|
||||
s_advertiseData.texturePackParentId = texPackId;
|
||||
s_advertiseData.subTexturePackId = subTexId;
|
||||
|
|
@ -648,6 +734,13 @@ void WinsockNetLayer::UpdateAdvertisePlayerCount(BYTE count)
|
|||
LeaveCriticalSection(&s_advertiseLock);
|
||||
}
|
||||
|
||||
void WinsockNetLayer::UpdateAdvertiseGameSettings(unsigned int gameSettings)
|
||||
{
|
||||
EnterCriticalSection(&s_advertiseLock);
|
||||
s_advertiseData.gameHostSettings = gameSettings;
|
||||
LeaveCriticalSection(&s_advertiseLock);
|
||||
}
|
||||
|
||||
void WinsockNetLayer::UpdateAdvertiseJoinable(bool joinable)
|
||||
{
|
||||
EnterCriticalSection(&s_advertiseLock);
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
#define WIN64_NET_DEFAULT_PORT 25565
|
||||
#define WIN64_NET_MAX_CLIENTS 7
|
||||
#define WIN64_NET_RECV_BUFFER_SIZE 65536
|
||||
#define WIN64_NET_MAX_PACKET_SIZE (4 * 1024 * 1024)
|
||||
#define WIN64_LAN_DISCOVERY_PORT 25566
|
||||
#define WIN64_LAN_BROADCAST_MAGIC 0x4D434C4E
|
||||
|
||||
|
|
@ -82,8 +83,9 @@ public:
|
|||
static bool PopDisconnectedSmallId(BYTE *outSmallId);
|
||||
static void PushFreeSmallId(BYTE smallId);
|
||||
|
||||
static bool StartAdvertising(int gamePort, const wchar_t *hostName, unsigned int gameSettings, unsigned int texPackId, unsigned char subTexId, unsigned short netVer);
|
||||
static bool StartAdvertising(int gamePort, const wchar_t *hostName, unsigned int gameSettings, unsigned int texPackId, unsigned char subTexId, unsigned short netVer, unsigned char maxPlayers = MINECRAFT_NET_MAX_PLAYERS);
|
||||
static void StopAdvertising();
|
||||
static void UpdateAdvertiseGameSettings(unsigned int gameSettings);
|
||||
static void UpdateAdvertisePlayerCount(BYTE count);
|
||||
static void UpdateAdvertiseJoinable(bool joinable);
|
||||
|
||||
|
|
@ -92,6 +94,7 @@ public:
|
|||
static std::vector<Win64LANSession> GetDiscoveredSessions();
|
||||
|
||||
static int GetHostPort() { return s_hostGamePort; }
|
||||
static BYTE GetMaxPlayers() { return s_maxPlayers; }
|
||||
|
||||
private:
|
||||
static DWORD WINAPI AcceptThreadProc(LPVOID param);
|
||||
|
|
@ -125,6 +128,7 @@ private:
|
|||
static Win64LANBroadcast s_advertiseData;
|
||||
static CRITICAL_SECTION s_advertiseLock;
|
||||
static int s_hostGamePort;
|
||||
static BYTE s_maxPlayers;
|
||||
|
||||
static SOCKET s_discoverySock;
|
||||
static HANDLE s_discoveryThread;
|
||||
|
|
@ -142,6 +146,7 @@ private:
|
|||
extern bool g_Win64MultiplayerHost;
|
||||
extern bool g_Win64MultiplayerJoin;
|
||||
extern int g_Win64MultiplayerPort;
|
||||
extern int g_Win64MultiplayerMaxPlayers;
|
||||
extern char g_Win64MultiplayerIP[256];
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ void CConsoleMinecraftApp::ExitGame()
|
|||
}
|
||||
void CConsoleMinecraftApp::FatalLoadError()
|
||||
{
|
||||
app.DebugPrintf("CConsoleMinecraftApp::FatalLoadError\n");
|
||||
}
|
||||
|
||||
void CConsoleMinecraftApp::CaptureSaveThumbnail()
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
10
Minecraft.Client/dedicated-server.properties
Normal file
10
Minecraft.Client/dedicated-server.properties
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
# LCE Dedicated Server Properties
|
||||
dedicated=true
|
||||
server-name=LCE Dedicated
|
||||
world-name=LCE Dedicated Server
|
||||
bind-address=0.0.0.0
|
||||
server-port=25565
|
||||
max-players=8
|
||||
level-type=flat
|
||||
save-world=false
|
||||
whitelist=false
|
||||
|
|
@ -11,7 +11,21 @@ public:
|
|||
T *data;
|
||||
unsigned int length;
|
||||
arrayWithLength() { data = NULL; length = 0; }
|
||||
arrayWithLength(unsigned int elements, bool bClearArray=true) { assert(elements!=0); data = new T[elements]; if(bClearArray){ memset( data,0,sizeof(T)*elements); } this->length = elements; }
|
||||
arrayWithLength(unsigned int elements, bool bClearArray=true)
|
||||
{
|
||||
if(elements == 0)
|
||||
{
|
||||
// Keep a valid pointer even for empty arrays to avoid null dereferences in
|
||||
// legacy code paths that assume data is always non-null.
|
||||
data = new T[1];
|
||||
if(bClearArray){ memset(data,0,sizeof(T)); }
|
||||
length = 0;
|
||||
return;
|
||||
}
|
||||
data = new T[elements];
|
||||
if(bClearArray){ memset( data,0,sizeof(T)*elements); }
|
||||
this->length = elements;
|
||||
}
|
||||
|
||||
// 4J Stu Added this ctor so I static init arrays in the Item derivation tree
|
||||
arrayWithLength( T data[], unsigned int elements) { this->data = data; this->length = elements; }
|
||||
|
|
|
|||
|
|
@ -182,7 +182,7 @@ public:
|
|||
|
||||
intArray getIntArray(wchar_t * name)
|
||||
{
|
||||
if (tags.find(name) == tags.end()) return intArray(0);
|
||||
if (tags.find(name) == tags.end()) return intArray();
|
||||
return ((IntArrayTag *) tags[name])->data;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -421,26 +421,29 @@ void Packet::writeUtf(const wstring& value, DataOutputStream *dos) // throws IOE
|
|||
|
||||
wstring Packet::readUtf(DataInputStream *dis, int maxLength) // throws IOException TODO 4J JEV, should this declare a throws?
|
||||
{
|
||||
|
||||
short stringLength = dis->readShort();
|
||||
if (stringLength > maxLength)
|
||||
{
|
||||
wstringstream stream;
|
||||
stream << L"Received string length longer than maximum allowed (" << stringLength << " > " << maxLength << ")";
|
||||
assert(false);
|
||||
// throw new IOException( stream.str() );
|
||||
}
|
||||
if (stringLength < 0)
|
||||
{
|
||||
assert(false);
|
||||
// throw new IOException(L"Received string length is less than zero! Weird string!");
|
||||
app.DebugPrintf("Packet::readUtf - invalid negative length %d (max=%d)\n", (int)stringLength, maxLength);
|
||||
return L"";
|
||||
}
|
||||
|
||||
const int sourceLength = (int)stringLength;
|
||||
const int safeLength = sourceLength > maxLength ? maxLength : sourceLength;
|
||||
if (sourceLength > maxLength)
|
||||
{
|
||||
app.DebugPrintf("Packet::readUtf - clamping overlong string (%d > %d)\n", sourceLength, maxLength);
|
||||
}
|
||||
|
||||
wstring builder = L"";
|
||||
for (int i = 0; i < stringLength; i++)
|
||||
builder.reserve(safeLength);
|
||||
for (int i = 0; i < sourceLength; i++)
|
||||
{
|
||||
wchar_t rc = dis->readChar();
|
||||
builder.push_back( rc );
|
||||
if (i < safeLength)
|
||||
{
|
||||
builder.push_back(rc);
|
||||
}
|
||||
}
|
||||
|
||||
return builder;
|
||||
|
|
|
|||
|
|
@ -18,11 +18,20 @@ void SetThreadName( DWORD dwThreadID, LPCSTR szThreadName )
|
|||
info.szName = szThreadName;
|
||||
info.dwThreadID = dwThreadID;
|
||||
info.dwFlags = 0;
|
||||
|
||||
#if defined(_WINDOWS64)
|
||||
// The 0x406D1388 thread-name exception is debugger-only metadata.
|
||||
// Skip raising it when no debugger is attached to avoid standalone exits.
|
||||
if (!IsDebuggerPresent())
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if ( defined _WINDOWS64 | defined _DURANGO )
|
||||
#if ( defined _WINDOWS64 || defined _DURANGO )
|
||||
__try
|
||||
{
|
||||
RaiseException( 0x406D1388, 0, sizeof(info)/sizeof(DWORD), (ULONG_PTR *)&info );
|
||||
RaiseException( 0x406D1388, 0, 4, (ULONG_PTR *)&info );
|
||||
}
|
||||
__except( GetExceptionCode()==0x406D1388 ? EXCEPTION_CONTINUE_EXECUTION : EXCEPTION_EXECUTE_HANDLER )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -68,7 +68,6 @@ Global
|
|||
{F046C3CE-9749-4823-B32B-D9CC10B1A2C8}.ContentPackage|Windows64.Build.0 = ContentPackage|x64
|
||||
{F046C3CE-9749-4823-B32B-D9CC10B1A2C8}.ContentPackage|Xbox 360.ActiveCfg = ContentPackage|x64
|
||||
{F046C3CE-9749-4823-B32B-D9CC10B1A2C8}.Debug|Durango.ActiveCfg = Debug|x64
|
||||
{F046C3CE-9749-4823-B32B-D9CC10B1A2C8}.Debug|Durango.Build.0 = Debug|x64
|
||||
{F046C3CE-9749-4823-B32B-D9CC10B1A2C8}.Debug|ORBIS.ActiveCfg = Debug|x64
|
||||
{F046C3CE-9749-4823-B32B-D9CC10B1A2C8}.Debug|PS3.ActiveCfg = Debug|x64
|
||||
{F046C3CE-9749-4823-B32B-D9CC10B1A2C8}.Debug|PSVita.ActiveCfg = Debug|x64
|
||||
|
|
@ -76,7 +75,6 @@ Global
|
|||
{F046C3CE-9749-4823-B32B-D9CC10B1A2C8}.Debug|Windows64.Build.0 = Debug|x64
|
||||
{F046C3CE-9749-4823-B32B-D9CC10B1A2C8}.Debug|Xbox 360.ActiveCfg = Debug|x64
|
||||
{F046C3CE-9749-4823-B32B-D9CC10B1A2C8}.Release|Durango.ActiveCfg = Release|x64
|
||||
{F046C3CE-9749-4823-B32B-D9CC10B1A2C8}.Release|Durango.Build.0 = Release|x64
|
||||
{F046C3CE-9749-4823-B32B-D9CC10B1A2C8}.Release|ORBIS.ActiveCfg = Release|x64
|
||||
{F046C3CE-9749-4823-B32B-D9CC10B1A2C8}.Release|PS3.ActiveCfg = Release|x64
|
||||
{F046C3CE-9749-4823-B32B-D9CC10B1A2C8}.Release|PSVita.ActiveCfg = Release|x64
|
||||
|
|
@ -108,7 +106,6 @@ Global
|
|||
{1B9A8C38-DD48-448C-AA24-E1A35E0089A3}.ContentPackage|Windows64.ActiveCfg = ContentPackage|x64
|
||||
{1B9A8C38-DD48-448C-AA24-E1A35E0089A3}.ContentPackage|Xbox 360.ActiveCfg = ContentPackage|x64
|
||||
{1B9A8C38-DD48-448C-AA24-E1A35E0089A3}.Debug|Durango.ActiveCfg = Debug|x64
|
||||
{1B9A8C38-DD48-448C-AA24-E1A35E0089A3}.Debug|Durango.Build.0 = Debug|x64
|
||||
{1B9A8C38-DD48-448C-AA24-E1A35E0089A3}.Debug|ORBIS.ActiveCfg = Debug|x64
|
||||
{1B9A8C38-DD48-448C-AA24-E1A35E0089A3}.Debug|PS3.ActiveCfg = Debug|x64
|
||||
{1B9A8C38-DD48-448C-AA24-E1A35E0089A3}.Debug|PSVita.ActiveCfg = Debug|x64
|
||||
|
|
@ -116,7 +113,6 @@ Global
|
|||
{1B9A8C38-DD48-448C-AA24-E1A35E0089A3}.Debug|Windows64.Build.0 = Debug|x64
|
||||
{1B9A8C38-DD48-448C-AA24-E1A35E0089A3}.Debug|Xbox 360.ActiveCfg = Debug|x64
|
||||
{1B9A8C38-DD48-448C-AA24-E1A35E0089A3}.Release|Durango.ActiveCfg = Release|x64
|
||||
{1B9A8C38-DD48-448C-AA24-E1A35E0089A3}.Release|Durango.Build.0 = Release|x64
|
||||
{1B9A8C38-DD48-448C-AA24-E1A35E0089A3}.Release|ORBIS.ActiveCfg = Release|x64
|
||||
{1B9A8C38-DD48-448C-AA24-E1A35E0089A3}.Release|PS3.ActiveCfg = Release|x64
|
||||
{1B9A8C38-DD48-448C-AA24-E1A35E0089A3}.Release|PSVita.ActiveCfg = Release|x64
|
||||
|
|
|
|||
5
proxy-worlds.properties
Normal file
5
proxy-worlds.properties
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
# Bungee-like route table for /server and /send
|
||||
# format: name=host:port|Display Name
|
||||
hub=127.0.0.1:25565|Hub
|
||||
bedwars=127.0.0.1:25566|Bedwars Match
|
||||
practice=127.0.0.1:25567|Practice
|
||||
Loading…
Reference in a new issue