Skip to content

Commit c93c7e2

Browse files
committed
Fix SendLuaFile
1 parent e0e1b2b commit c93c7e2

File tree

1 file changed

+47
-41
lines changed

1 file changed

+47
-41
lines changed

source/server/datapack.cpp

Lines changed: 47 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include "datapack.hpp"
2+
#include "protocol.hpp"
23

34
#include <GarrysMod/Lua/Helpers.hpp>
45
#include <GarrysMod/FunctionPointers.hpp>
@@ -10,7 +11,10 @@
1011
#include <iclient.h>
1112
#include <eiface.h>
1213
#include <LzmaLib.h>
13-
#include <7zCrc.h>
14+
#include <Sha256.h>
15+
16+
#include <vector>
17+
#include <array>
1418

1519
class GModDataPack;
1620

@@ -100,24 +104,30 @@ namespace DataPack
100104
int GModDataPackProxy::lua_receiving_client = -1;
101105
const char GModDataPackProxy::lua_file_hook_name[] = "SendLuaFileToClient";
102106

103-
static size_t Compress( const std::string &input, std::vector<uint8_t> &output, size_t offset )
107+
inline size_t MaximumCompressedSize( const std::string &input )
108+
{
109+
const size_t input_size = input.size( ) + 1;
110+
return input_size + input_size / 3 + 128;
111+
}
112+
113+
static std::vector<uint8_t> Compress( const std::string &input )
104114
{
105115
// The data is written:
106116
// 5 bytes: props
107117
// 8 bytes: uncompressed size
108118
// the rest: the actual data
109-
size_t iInputLength = input.size( ) + 1;
119+
const size_t iInputLength = input.size( ) + 1;
110120
size_t props_size = LZMA_PROPS_SIZE;
111121
size_t iDestSize = iInputLength + iInputLength / 3 + 128;
112122

113-
output.resize( offset + iDestSize + LZMA_PROPS_SIZE + 8 );
123+
std::vector<uint8_t> output( iDestSize + LZMA_PROPS_SIZE + 8, 0 );
114124

115125
const uint8_t *pInputData = reinterpret_cast<const uint8_t *>( input.c_str( ) );
116-
uint8_t *pPropStart = reinterpret_cast<uint8_t *>( &output[offset] );
126+
uint8_t *pPropStart = output.data( );
117127
uint8_t *pSizeStart = pPropStart + LZMA_PROPS_SIZE;
118128
uint8_t *pBodyStart = pSizeStart + 8;
119129

120-
int res = LzmaCompress(
130+
const int res = LzmaCompress(
121131
pBodyStart, &iDestSize, // Dest out
122132
pInputData, iInputLength, // Input in
123133
pPropStart, &props_size, // Props out
@@ -131,10 +141,10 @@ namespace DataPack
131141
);
132142

133143
if( props_size != LZMA_PROPS_SIZE )
134-
return 0;
144+
return { };
135145

136146
if( res != SZ_OK )
137-
return 0;
147+
return { };
138148

139149
// Write our 8 byte LE size
140150
pSizeStart[0] = iInputLength & 0xFF;
@@ -146,55 +156,53 @@ namespace DataPack
146156
pSizeStart[6] = 0;
147157
pSizeStart[7] = 0;
148158

149-
output.resize( offset + iDestSize + LZMA_PROPS_SIZE + 8 );
150-
return iDestSize + LZMA_PROPS_SIZE + 8;
159+
output.resize( iDestSize + LZMA_PROPS_SIZE + 8 );
160+
return output;
151161
}
152162

153163
inline void SendLuaFile( int client, int fileID, const std::string &substitute, bool autorefresh )
154164
{
155-
std::vector<uint8_t> data;
165+
const char *path = client_lua_files->GetString( fileID );
166+
167+
// Type 1b + SHA256 32b + compressed substitute Xb + alignment 4b
168+
int min_buffer_size = 1 + 32 + MaximumCompressedSize( substitute ) + 4;
156169

157-
const char *path = nullptr;
158-
size_t pathlen = 0;
159170
if( autorefresh )
160171
{
161-
path = client_lua_files->GetString( fileID );
162-
pathlen = std::strlen( path ) + 1;
163-
data.resize( 1 + pathlen + 4 + 4 );
172+
if( path == nullptr )
173+
return;
174+
175+
// (File path + NUL) Xb + (SHA256 + compressed substitute) size 4b
176+
min_buffer_size += std::strlen( path ) + 1 + 4;
164177
}
165178
else
166-
data.resize( 1 + 2 + 4 );
179+
// File ID 2b
180+
min_buffer_size += 2;
167181

168-
size_t offset = 0;
182+
std::vector<uint8_t> buffer( min_buffer_size, 0 );
183+
bf_write writer( "sourcenet SendLuaFile writer", buffer.data( ), buffer.size( ) );
169184

170-
uint8_t msgType = autorefresh ? 1 : 4; // message type
171-
std::memcpy( &data[offset], &msgType, 1 );
172-
++offset;
185+
writer.WriteByte( autorefresh ? 1 : 4 );
173186

174187
if( autorefresh )
175-
{
176-
std::memcpy( &data[offset], path, pathlen );
177-
offset += pathlen;
178-
}
188+
writer.WriteString( path );
179189
else
180-
{
181-
std::memcpy( &data[offset], &fileID, 2 );
182-
offset += 2;
183-
}
190+
writer.WriteWord( fileID );
184191

192+
const std::vector<uint8_t> compressed_buffer = Compress( substitute );
185193
if( autorefresh )
186-
{
187-
size_t compressedLen = Compress( substitute, data, offset + 8 ) + 4;
188-
std::memcpy( &data[offset], &compressedLen, 4 );
189-
offset += 4;
190-
}
191-
else
192-
Compress( substitute, data, offset + 4 );
194+
writer.WriteUBitLong( 32 + compressed_buffer.size( ), 32 );
193195

194-
uint32_t crc32 = CrcCalc( &substitute[0], substitute.size( ) + 1 );
195-
std::memcpy( &data[offset], &crc32, 4 );
196+
CSha256 sha256;
197+
Sha256_Init( &sha256 );
198+
Sha256_Update( &sha256, reinterpret_cast<const uint8_t *>( substitute.c_str( ) ), substitute.size( ) + 1 );
199+
std::array<uint8_t, 32> sha256_buffer { };
200+
Sha256_Final( &sha256, sha256_buffer.data( ) );
201+
writer.WriteBytes( sha256_buffer.data( ), sha256_buffer.size( ) );
196202

197-
global::engine_server->GMOD_SendToClient( client, &data[0], static_cast<int>( 8 * data.size( ) ) );
203+
writer.WriteBytes( compressed_buffer.data( ), static_cast<int>( compressed_buffer.size( ) ) );
204+
205+
global::engine_server->GMOD_SendToClient( client, writer.GetData( ), writer.GetNumBitsWritten( ) );
198206
}
199207

200208
LUA_FUNCTION_STATIC( SendLuaFile )
@@ -250,8 +258,6 @@ namespace DataPack
250258

251259
void Initialize( GarrysMod::Lua::ILuaBase *LUA )
252260
{
253-
CrcGenerateTable( );
254-
255261
LUA->PushCFunction( GModDataPackProxy::EnableLuaFileValidation );
256262
LUA->SetField( GarrysMod::Lua::INDEX_GLOBAL, "EnableLuaFileValidation" );
257263

0 commit comments

Comments
 (0)