mirror of
https://github.com/4jcraft/4jcraft.git
synced 2026-05-28 00:42:53 +00:00
Address remaining review feedback on buffer reads
This commit is contained in:
parent
883e98bde0
commit
00d65b8487
|
|
@ -38,6 +38,7 @@
|
|||
#include "../Minecraft.World/IO/Streams/InputOutputStream.h"
|
||||
#include "../Minecraft.World/Level/Storage/LevelSettings.h"
|
||||
#include "../Minecraft.Client/Player/User.h"
|
||||
#include <cstring>
|
||||
#include "../Minecraft.World/Level/LevelData.h"
|
||||
#include "../Minecraft.World/Headers/net.minecraft.world.entity.player.h"
|
||||
#include "../Minecraft.Client/Rendering/EntityRenderers/EntityRenderDispatcher.h"
|
||||
|
|
@ -7649,6 +7650,13 @@ unsigned int CMinecraftApp::FromBigEndian(unsigned int uiValue)
|
|||
|
||||
void CMinecraftApp::GetImageTextData(std::uint8_t *imageData, unsigned int imageBytes, unsigned char *seedText, unsigned int &uiHostOptions, bool &bHostOptionsRead, std::uint32_t &uiTexturePack)
|
||||
{
|
||||
auto readPngUInt32 = [](const std::uint8_t *data) -> unsigned int
|
||||
{
|
||||
unsigned int value = 0;
|
||||
std::memcpy(&value, data, sizeof(value));
|
||||
return value;
|
||||
};
|
||||
|
||||
std::uint8_t *ucPtr = imageData;
|
||||
unsigned int uiCount=0;
|
||||
unsigned int uiChunkLen;
|
||||
|
|
@ -7666,11 +7674,9 @@ void CMinecraftApp::GetImageTextData(std::uint8_t *imageData, unsigned int image
|
|||
|
||||
while(uiCount < imageBytes)
|
||||
{
|
||||
uiChunkLen=*(unsigned int *)&ucPtr[uiCount];
|
||||
uiChunkLen=FromBigEndian(uiChunkLen);
|
||||
uiChunkLen = FromBigEndian(readPngUInt32(&ucPtr[uiCount]));
|
||||
uiCount+=sizeof(int);
|
||||
uiChunkType=*(unsigned int *)&ucPtr[uiCount];
|
||||
uiChunkType=FromBigEndian(uiChunkType);
|
||||
uiChunkType = FromBigEndian(readPngUInt32(&ucPtr[uiCount]));
|
||||
uiCount+=sizeof(int);
|
||||
|
||||
if(uiChunkType==PNG_TAG_tEXt) // tEXt
|
||||
|
|
@ -7735,8 +7741,7 @@ void CMinecraftApp::GetImageTextData(std::uint8_t *imageData, unsigned int image
|
|||
}
|
||||
}
|
||||
uiCount+=uiChunkLen;
|
||||
uiCRC=*(unsigned int*)&ucPtr[uiCount];
|
||||
uiCRC=FromBigEndian(uiCRC);
|
||||
uiCRC = FromBigEndian(readPngUInt32(&ucPtr[uiCount]));
|
||||
uiCount+=sizeof(int);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
#include "../../Minecraft.World/Platform/stdafx.h"
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include "DLCManager.h"
|
||||
#include "DLCAudioFile.h"
|
||||
#if defined _XBOX || defined _WINDOWS64
|
||||
|
|
@ -6,6 +9,64 @@
|
|||
#include "../../Minecraft.Client/Platform/Xbox/XML/xmlFilesCallback.h"
|
||||
#endif
|
||||
|
||||
namespace
|
||||
{
|
||||
constexpr std::size_t AUDIO_DLC_WCHAR_BIN_SIZE = 2;
|
||||
|
||||
#if WCHAR_MAX > 0xFFFF
|
||||
static std::wstring ReadAudioDlcWString(const void *data)
|
||||
{
|
||||
const std::uint16_t *chars = static_cast<const std::uint16_t *>(data);
|
||||
const std::uint16_t *end = chars;
|
||||
while(*end != 0)
|
||||
{
|
||||
++end;
|
||||
}
|
||||
|
||||
std::wstring out(static_cast<std::size_t>(end - chars), 0);
|
||||
for(std::size_t i = 0; i < out.size(); ++i)
|
||||
{
|
||||
out[i] = static_cast<wchar_t>(chars[i]);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
#else
|
||||
static std::wstring ReadAudioDlcWString(const void *data)
|
||||
{
|
||||
return std::wstring(static_cast<const wchar_t *>(data));
|
||||
}
|
||||
#endif
|
||||
|
||||
template <typename T>
|
||||
T ReadAudioDlcValue(const std::uint8_t *data, unsigned int offset = 0)
|
||||
{
|
||||
T value;
|
||||
std::memcpy(&value, data + offset, sizeof(value));
|
||||
return value;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void ReadAudioDlcStruct(T *out, const std::uint8_t *data, unsigned int offset = 0)
|
||||
{
|
||||
std::memcpy(out, data + offset, sizeof(*out));
|
||||
}
|
||||
|
||||
inline unsigned int AudioParamAdvance(unsigned int wcharCount)
|
||||
{
|
||||
return static_cast<unsigned int>(sizeof(C4JStorage::DLC_FILE_PARAM) + wcharCount * AUDIO_DLC_WCHAR_BIN_SIZE);
|
||||
}
|
||||
|
||||
inline unsigned int AudioDetailAdvance(unsigned int wcharCount)
|
||||
{
|
||||
return static_cast<unsigned int>(sizeof(C4JStorage::DLC_FILE_DETAILS) + wcharCount * AUDIO_DLC_WCHAR_BIN_SIZE);
|
||||
}
|
||||
|
||||
inline std::wstring ReadAudioParamString(const std::uint8_t *data, unsigned int offset)
|
||||
{
|
||||
return ReadAudioDlcWString(data + offset + offsetof(C4JStorage::DLC_FILE_PARAM, wchData));
|
||||
}
|
||||
}
|
||||
|
||||
DLCAudioFile::DLCAudioFile(const std::wstring &path) : DLCFile(DLCManager::e_DLCType_Audio,path)
|
||||
{
|
||||
m_pbData = NULL;
|
||||
|
|
@ -128,7 +189,7 @@ bool DLCAudioFile::processDLCDataFile(std::uint8_t *pbData, std::uint32_t dataLe
|
|||
// File format defined in the AudioPacker
|
||||
// File format: Version 1
|
||||
|
||||
unsigned int uiVersion=*(unsigned int *)pbData;
|
||||
unsigned int uiVersion = ReadAudioDlcValue<unsigned int>(pbData, uiCurrentByte);
|
||||
uiCurrentByte+=sizeof(int);
|
||||
|
||||
if(uiVersion < CURRENT_AUDIO_VERSION_NUM)
|
||||
|
|
@ -138,60 +199,62 @@ bool DLCAudioFile::processDLCDataFile(std::uint8_t *pbData, std::uint32_t dataLe
|
|||
return false;
|
||||
}
|
||||
|
||||
unsigned int uiParameterTypeCount=*(unsigned int *)&pbData[uiCurrentByte];
|
||||
unsigned int uiParameterTypeCount = ReadAudioDlcValue<unsigned int>(pbData, uiCurrentByte);
|
||||
uiCurrentByte+=sizeof(int);
|
||||
C4JStorage::DLC_FILE_PARAM *pParams = (C4JStorage::DLC_FILE_PARAM *)&pbData[uiCurrentByte];
|
||||
C4JStorage::DLC_FILE_PARAM paramBuf;
|
||||
ReadAudioDlcStruct(¶mBuf, pbData, uiCurrentByte);
|
||||
|
||||
for(unsigned int i=0;i<uiParameterTypeCount;i++)
|
||||
{
|
||||
// Map DLC strings to application strings, then store the DLC index mapping to application index
|
||||
std::wstring parameterName((WCHAR *)pParams->wchData);
|
||||
std::wstring parameterName = ReadAudioParamString(pbData, uiCurrentByte);
|
||||
EAudioParameterType type = getParameterType(parameterName);
|
||||
if( type != e_AudioParamType_Invalid )
|
||||
{
|
||||
parameterMapping[pParams->dwType] = type;
|
||||
parameterMapping[paramBuf.dwType] = type;
|
||||
}
|
||||
uiCurrentByte+= sizeof(C4JStorage::DLC_FILE_PARAM)+(pParams->dwWchCount*sizeof(WCHAR));
|
||||
pParams = (C4JStorage::DLC_FILE_PARAM *)&pbData[uiCurrentByte];
|
||||
uiCurrentByte += AudioParamAdvance(paramBuf.dwWchCount);
|
||||
ReadAudioDlcStruct(¶mBuf, pbData, uiCurrentByte);
|
||||
}
|
||||
unsigned int uiFileCount=*(unsigned int *)&pbData[uiCurrentByte];
|
||||
unsigned int uiFileCount = ReadAudioDlcValue<unsigned int>(pbData, uiCurrentByte);
|
||||
uiCurrentByte+=sizeof(int);
|
||||
C4JStorage::DLC_FILE_DETAILS *pFile = (C4JStorage::DLC_FILE_DETAILS *)&pbData[uiCurrentByte];
|
||||
C4JStorage::DLC_FILE_DETAILS fileBuf;
|
||||
ReadAudioDlcStruct(&fileBuf, pbData, uiCurrentByte);
|
||||
|
||||
unsigned int tempByteOffset = uiCurrentByte;
|
||||
for(unsigned int i=0;i<uiFileCount;i++)
|
||||
{
|
||||
tempByteOffset += sizeof(C4JStorage::DLC_FILE_DETAILS) + pFile->dwWchCount * sizeof(WCHAR);
|
||||
pFile = (C4JStorage::DLC_FILE_DETAILS *)&pbData[tempByteOffset];
|
||||
tempByteOffset += AudioDetailAdvance(fileBuf.dwWchCount);
|
||||
ReadAudioDlcStruct(&fileBuf, pbData, tempByteOffset);
|
||||
}
|
||||
std::uint8_t *pbTemp = reinterpret_cast<std::uint8_t *>(pFile);
|
||||
pFile = (C4JStorage::DLC_FILE_DETAILS *)&pbData[uiCurrentByte];
|
||||
std::uint8_t *pbTemp = &pbData[tempByteOffset];
|
||||
ReadAudioDlcStruct(&fileBuf, pbData, uiCurrentByte);
|
||||
|
||||
for(unsigned int i=0;i<uiFileCount;i++)
|
||||
{
|
||||
EAudioType type = (EAudioType)pFile->dwType;
|
||||
EAudioType type = (EAudioType)fileBuf.dwType;
|
||||
// Params
|
||||
unsigned int uiParameterCount=*(unsigned int *)pbTemp;
|
||||
unsigned int uiParameterCount = ReadAudioDlcValue<unsigned int>(pbTemp);
|
||||
pbTemp+=sizeof(int);
|
||||
pParams = (C4JStorage::DLC_FILE_PARAM *)pbTemp;
|
||||
ReadAudioDlcStruct(¶mBuf, pbTemp);
|
||||
for(unsigned int j=0;j<uiParameterCount;j++)
|
||||
{
|
||||
//EAudioParameterType paramType = e_AudioParamType_Invalid;
|
||||
|
||||
AUTO_VAR(it, parameterMapping.find( pParams->dwType ));
|
||||
AUTO_VAR(it, parameterMapping.find(paramBuf.dwType));
|
||||
|
||||
if(it != parameterMapping.end() )
|
||||
{
|
||||
addParameter(type,(EAudioParameterType)pParams->dwType,(WCHAR *)pParams->wchData);
|
||||
addParameter(type, (EAudioParameterType)paramBuf.dwType, ReadAudioParamString(pbTemp, 0));
|
||||
}
|
||||
pbTemp+=sizeof(C4JStorage::DLC_FILE_PARAM)+(sizeof(WCHAR)*pParams->dwWchCount);
|
||||
pParams = (C4JStorage::DLC_FILE_PARAM *)pbTemp;
|
||||
pbTemp += AudioParamAdvance(paramBuf.dwWchCount);
|
||||
ReadAudioDlcStruct(¶mBuf, pbTemp);
|
||||
}
|
||||
// Move the pointer to the start of the next files data;
|
||||
pbTemp+=pFile->uiFileSize;
|
||||
uiCurrentByte+=sizeof(C4JStorage::DLC_FILE_DETAILS)+pFile->dwWchCount*sizeof(WCHAR);
|
||||
pbTemp += fileBuf.uiFileSize;
|
||||
uiCurrentByte += AudioDetailAdvance(fileBuf.dwWchCount);
|
||||
|
||||
pFile=(C4JStorage::DLC_FILE_DETAILS *)&pbData[uiCurrentByte];
|
||||
ReadAudioDlcStruct(&fileBuf, pbData, uiCurrentByte);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
#include "../../Minecraft.World/Util/PortableFileIO.h"
|
||||
#include "../../Minecraft.Client/Minecraft.h"
|
||||
#include "../../Minecraft.Client/Textures/Packs/TexturePackRepository.h"
|
||||
#include <cstring>
|
||||
#include <limits>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
|
@ -57,6 +58,20 @@ static_assert( sizeof(wchar_t) == 2, "How did we get here? wide char smaller tha
|
|||
|
||||
namespace
|
||||
{
|
||||
template <typename T>
|
||||
T ReadDlcValue(const std::uint8_t *data, unsigned int offset = 0)
|
||||
{
|
||||
T value;
|
||||
std::memcpy(&value, data + offset, sizeof(value));
|
||||
return value;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void ReadDlcStruct(T *out, const std::uint8_t *data, unsigned int offset = 0)
|
||||
{
|
||||
std::memcpy(out, data + offset, sizeof(*out));
|
||||
}
|
||||
|
||||
std::wstring getMountedDlcReadPath(const std::string &path)
|
||||
{
|
||||
std::wstring readPath = convStringToWstring(path);
|
||||
|
|
@ -680,7 +695,7 @@ std::uint32_t DLCManager::retrievePackID(std::uint8_t *pbData, unsigned int dwLe
|
|||
// // unsigned long, p = number of parameters
|
||||
// // p * DLC_FILE_PARAM describing each parameter for this file
|
||||
// // ulFileSize bytes of data blob of the file added
|
||||
unsigned int uiVersion=*(unsigned int *)pbData;
|
||||
unsigned int uiVersion = ReadDlcValue<unsigned int>(pbData, uiCurrentByte);
|
||||
uiCurrentByte+=sizeof(int);
|
||||
|
||||
if(uiVersion < CURRENT_DLC_VERSION_NUM)
|
||||
|
|
@ -689,46 +704,48 @@ std::uint32_t DLCManager::retrievePackID(std::uint8_t *pbData, unsigned int dwLe
|
|||
return 0;
|
||||
}
|
||||
pack->SetDataPointer(pbData);
|
||||
unsigned int uiParameterCount=*(unsigned int *)&pbData[uiCurrentByte];
|
||||
unsigned int uiParameterCount = ReadDlcValue<unsigned int>(pbData, uiCurrentByte);
|
||||
uiCurrentByte+=sizeof(int);
|
||||
C4JStorage::DLC_FILE_PARAM *pParams = (C4JStorage::DLC_FILE_PARAM *)&pbData[uiCurrentByte];
|
||||
C4JStorage::DLC_FILE_PARAM paramBuf;
|
||||
ReadDlcStruct(¶mBuf, pbData, uiCurrentByte);
|
||||
for(unsigned int i=0;i<uiParameterCount;i++)
|
||||
{
|
||||
// Map DLC strings to application strings, then store the DLC index mapping to application index
|
||||
std::wstring parameterName = DLC_WSTRING(pParams->wchData);
|
||||
std::wstring parameterName = DLC_PARAM_WSTR(pbData, uiCurrentByte);
|
||||
DLCManager::EDLCParameterType type = DLCManager::getParameterType(parameterName);
|
||||
if( type != DLCManager::e_DLCParamType_Invalid )
|
||||
{
|
||||
parameterMapping[pParams->dwType] = type;
|
||||
parameterMapping[paramBuf.dwType] = type;
|
||||
}
|
||||
uiCurrentByte+= DLC_PARAM_ADV(pParams->dwWchCount);
|
||||
pParams = (C4JStorage::DLC_FILE_PARAM *)&pbData[uiCurrentByte];
|
||||
uiCurrentByte += DLC_PARAM_ADV(paramBuf.dwWchCount);
|
||||
ReadDlcStruct(¶mBuf, pbData, uiCurrentByte);
|
||||
}
|
||||
|
||||
unsigned int uiFileCount=*(unsigned int *)&pbData[uiCurrentByte];
|
||||
unsigned int uiFileCount = ReadDlcValue<unsigned int>(pbData, uiCurrentByte);
|
||||
uiCurrentByte+=sizeof(int);
|
||||
C4JStorage::DLC_FILE_DETAILS *pFile = (C4JStorage::DLC_FILE_DETAILS *)&pbData[uiCurrentByte];
|
||||
C4JStorage::DLC_FILE_DETAILS fileBuf;
|
||||
ReadDlcStruct(&fileBuf, pbData, uiCurrentByte);
|
||||
|
||||
unsigned int dwTemp=uiCurrentByte;
|
||||
for(unsigned int i=0;i<uiFileCount;i++)
|
||||
{
|
||||
dwTemp+=DLC_DETAIL_ADV(pFile->dwWchCount);
|
||||
pFile = (C4JStorage::DLC_FILE_DETAILS *)&pbData[dwTemp];
|
||||
dwTemp += DLC_DETAIL_ADV(fileBuf.dwWchCount);
|
||||
ReadDlcStruct(&fileBuf, pbData, dwTemp);
|
||||
}
|
||||
std::uint8_t *pbTemp = reinterpret_cast<std::uint8_t *>(pFile);
|
||||
pFile = (C4JStorage::DLC_FILE_DETAILS *)&pbData[uiCurrentByte];
|
||||
std::uint8_t *pbTemp = &pbData[dwTemp];
|
||||
ReadDlcStruct(&fileBuf, pbData, uiCurrentByte);
|
||||
|
||||
for(unsigned int i=0;i<uiFileCount;i++)
|
||||
{
|
||||
DLCManager::EDLCType type = (DLCManager::EDLCType)pFile->dwType;
|
||||
DLCManager::EDLCType type = (DLCManager::EDLCType)fileBuf.dwType;
|
||||
|
||||
// Params
|
||||
uiParameterCount=*(unsigned int *)pbTemp;
|
||||
uiParameterCount = ReadDlcValue<unsigned int>(pbTemp);
|
||||
pbTemp+=sizeof(int);
|
||||
pParams = (C4JStorage::DLC_FILE_PARAM *)pbTemp;
|
||||
ReadDlcStruct(¶mBuf, pbTemp);
|
||||
for(unsigned int j=0;j<uiParameterCount;j++)
|
||||
{
|
||||
AUTO_VAR(it, parameterMapping.find( pParams->dwType ));
|
||||
AUTO_VAR(it, parameterMapping.find(paramBuf.dwType));
|
||||
|
||||
if(it != parameterMapping.end() )
|
||||
{
|
||||
|
|
@ -736,7 +753,7 @@ std::uint32_t DLCManager::retrievePackID(std::uint8_t *pbData, unsigned int dwLe
|
|||
{
|
||||
if(it->second==e_DLCParamType_PackId)
|
||||
{
|
||||
std::wstring wsTemp = DLC_WSTRING(pParams->wchData);
|
||||
std::wstring wsTemp = DLC_PARAM_WSTR(pbTemp, 0);
|
||||
std::wstringstream ss;
|
||||
// 4J Stu - numbered using decimal to make it easier for artists/people to number manually
|
||||
ss << std::dec << wsTemp.c_str();
|
||||
|
|
@ -746,16 +763,16 @@ std::uint32_t DLCManager::retrievePackID(std::uint8_t *pbData, unsigned int dwLe
|
|||
}
|
||||
}
|
||||
}
|
||||
pbTemp+=DLC_PARAM_ADV(pParams->dwWchCount);
|
||||
pParams = (C4JStorage::DLC_FILE_PARAM *)pbTemp;
|
||||
pbTemp += DLC_PARAM_ADV(paramBuf.dwWchCount);
|
||||
ReadDlcStruct(¶mBuf, pbTemp);
|
||||
}
|
||||
|
||||
if(bPackIDSet) break;
|
||||
// Move the pointer to the start of the next files data;
|
||||
pbTemp+=pFile->uiFileSize;
|
||||
uiCurrentByte+=DLC_DETAIL_ADV(pFile->dwWchCount);
|
||||
pbTemp += fileBuf.uiFileSize;
|
||||
uiCurrentByte += DLC_DETAIL_ADV(fileBuf.dwWchCount);
|
||||
|
||||
pFile=(C4JStorage::DLC_FILE_DETAILS *)&pbData[uiCurrentByte];
|
||||
ReadDlcStruct(&fileBuf, pbData, uiCurrentByte);
|
||||
}
|
||||
|
||||
parameterMapping.clear();
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ void AddPlayerPacket::read(DataInputStream *dis) //throws IOException
|
|||
m_skinId = static_cast<std::uint32_t>(dis->readInt());
|
||||
m_capeId = static_cast<std::uint32_t>(dis->readInt());
|
||||
INT privileges = dis->readInt();
|
||||
m_uiGamePrivileges = *(unsigned int *)&privileges;
|
||||
m_uiGamePrivileges = static_cast<unsigned int>(privileges);
|
||||
MemSect(1);
|
||||
unpack = SynchedEntityData::unpack(dis);
|
||||
MemSect(0);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
#include "../../Platform/stdafx.h"
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include "../../IO/Streams/InputOutputStream.h"
|
||||
#include "../../Headers/net.minecraft.world.entity.h"
|
||||
|
|
@ -32,17 +31,14 @@ TextureAndGeometryChangePacket::TextureAndGeometryChangePacket(std::shared_ptr<E
|
|||
void TextureAndGeometryChangePacket::read(DataInputStream *dis) //throws IOException
|
||||
{
|
||||
id = dis->readInt();
|
||||
int skinId = dis->readInt();
|
||||
std::memcpy(&dwSkinID, &skinId, sizeof(dwSkinID));
|
||||
dwSkinID = static_cast<std::uint32_t>(dis->readInt());
|
||||
path = dis->readUTF();
|
||||
}
|
||||
|
||||
void TextureAndGeometryChangePacket::write(DataOutputStream *dos) //throws IOException
|
||||
{
|
||||
dos->writeInt(id);
|
||||
int skinId = 0;
|
||||
std::memcpy(&skinId, &dwSkinID, sizeof(dwSkinID));
|
||||
dos->writeInt(skinId);
|
||||
dos->writeInt(static_cast<int>(dwSkinID));
|
||||
dos->writeUTF(path);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
#include "../../Platform/stdafx.h"
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include "../../IO/Streams/InputOutputStream.h"
|
||||
#include "PacketListener.h"
|
||||
|
|
@ -123,8 +122,7 @@ void TextureAndGeometryPacket::handle(PacketListener *listener)
|
|||
void TextureAndGeometryPacket::read(DataInputStream *dis) //throws IOException
|
||||
{
|
||||
textureName = dis->readUTF();
|
||||
int skinId = dis->readInt();
|
||||
std::memcpy(&dwSkinID, &skinId, sizeof(dwSkinID));
|
||||
dwSkinID = static_cast<std::uint32_t>(dis->readInt());
|
||||
dwTextureBytes = (std::uint32_t)dis->readShort();
|
||||
|
||||
if(dwTextureBytes>0)
|
||||
|
|
@ -162,9 +160,7 @@ void TextureAndGeometryPacket::read(DataInputStream *dis) //throws IOException
|
|||
void TextureAndGeometryPacket::write(DataOutputStream *dos) //throws IOException
|
||||
{
|
||||
dos->writeUTF(textureName);
|
||||
int skinId = 0;
|
||||
std::memcpy(&skinId, &dwSkinID, sizeof(dwSkinID));
|
||||
dos->writeInt(skinId);
|
||||
dos->writeInt(static_cast<int>(dwSkinID));
|
||||
dos->writeShort((short)dwTextureBytes);
|
||||
for(std::uint32_t i=0;i<dwTextureBytes;i++)
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in a new issue