Fix empty chat lines not contributing to height of box behind recent chat.

This commit is contained in:
UnknownShadow200 2017-09-19 11:02:45 +10:00
parent e787c45147
commit 0b3cbfac7a
7 changed files with 189 additions and 142 deletions

View File

@ -92,12 +92,14 @@ namespace ClassicalSharp.Gui.Widgets {
}
public int GetUsedHeight() {
int sum = 0;
for (int i = 0; i < Textures.Length; i++) {
if (!Textures[i].IsValid) continue;
sum += Textures[i].Height;
int height = 0, i = 0;
for (i = 0; i < Textures.Length; i++) {
if (Textures[i].IsValid) break;
}
return sum;
for (; i < Textures.Length; i++) {
height += Textures[i].Height;
}
return height;
}
void UpdateDimensions() {

View File

@ -194,7 +194,7 @@
<ClInclude Include="Event.h" />
<ClInclude Include="Events.h" />
<ClInclude Include="FrustumCulling.h" />
<ClInclude Include="GZipHeader.h" />
<ClInclude Include="Deflate.h" />
<ClInclude Include="IModel.h" />
<ClInclude Include="Intersection.h" />
<ClInclude Include="IsometricDrawer.h" />
@ -262,7 +262,7 @@
<ClCompile Include="MapGenerator.c" />
<ClCompile Include="FrustumCulling.c" />
<ClCompile Include="GameStructs.c" />
<ClCompile Include="GZipHeader.c" />
<ClCompile Include="Deflate.c" />
<ClCompile Include="IModel.c" />
<ClCompile Include="Intersection.c" />
<ClCompile Include="IsometricDrawer.c" />

View File

@ -273,9 +273,6 @@
<ClInclude Include="Constants.h">
<Filter>Header Files\Defines</Filter>
</ClInclude>
<ClInclude Include="GZipHeader.h">
<Filter>Header Files\IO</Filter>
</ClInclude>
<ClInclude Include="Random.h">
<Filter>Header Files\Math</Filter>
</ClInclude>
@ -351,6 +348,9 @@
<ClInclude Include="Picking.h">
<Filter>Header Files\Math</Filter>
</ClInclude>
<ClInclude Include="Deflate.h">
<Filter>Header Files\IO</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Noise.c">
@ -437,9 +437,6 @@
<ClCompile Include="Respawn.c">
<Filter>Source Files\Entities</Filter>
</ClCompile>
<ClCompile Include="GZipHeader.c">
<Filter>Source Files\IO</Filter>
</ClCompile>
<ClCompile Include="Random.c">
<Filter>Source Files\Math</Filter>
</ClCompile>
@ -530,5 +527,8 @@
<ClCompile Include="DateTime.c">
<Filter>Source Files\Utils</Filter>
</ClCompile>
<ClCompile Include="Deflate.c">
<Filter>Source Files\IO</Filter>
</ClCompile>
</ItemGroup>
</Project>

142
src/Client/Deflate.c Normal file
View File

@ -0,0 +1,142 @@
#include "Deflate.h"
#include "ErrorHandler.h"
#define GZipState_Header1 0
#define GZipState_Header2 1
#define GZipState_CompressionMethod 2
#define GZipState_Flags 3
#define GZipState_LastModifiedTime 4
#define GZipState_CompressionFlags 5
#define GZipState_OperatingSystem 6
#define GZipState_HeaderChecksum 7
#define GZipState_Filename 8
#define GZipState_Comment 9
#define GZipState_Done 10
#define ZLibState_CompressionMethod 0
#define ZLibState_Flags 1
#define ZLibState_Done 2
bool Header_ReadByte(Stream* s, UInt8* state, Int32* value) {
*value = s->TryReadByte();
if (*value == -1) return false;
(*state)++;
return true;
}
void GZipHeader_Init(GZipHeader* header) {
header->State = GZipState_Header1;
header->Done = false;
header->Flags = 0;
header->PartsRead = 0;
}
void GZipHeader_Read(Stream* s, GZipHeader* header) {
Int32 temp;
switch (header->State) {
case GZipState_Header1:
if (!Header_ReadByte(s, &header->State, &temp)) return;
if (temp != 0x1F) {
ErrorHandler_Fail("Byte 1 of GZIP header must be 1F");
}
case GZipState_Header2:
if (!Header_ReadByte(s, &header->State, &temp)) return;
if (temp != 0x8B) {
ErrorHandler_Fail("Byte 2 of GZIP header must be 8B");
}
case GZipState_CompressionMethod:
if (!Header_ReadByte(s, &header->State, &temp)) return;
if (temp != 0x08) {
ErrorHandler_Fail("Only DEFLATE compression supported");
}
case GZipState_Flags:
if (!Header_ReadByte(s, &header->State, &header->Flags)) return;
if ((header->Flags & 0x04) != 0) {
ErrorHandler_Fail("Unsupported GZIP header flags");
}
case GZipState_LastModifiedTime:
for (; header->PartsRead < 4; header->PartsRead++) {
temp = s->TryReadByte();
if (temp == -1) return;
}
header->State++;
header->PartsRead = 0;
case GZipState_CompressionFlags:
if (!Header_ReadByte(s, &header->State, &temp)) return;
case GZipState_OperatingSystem:
if (!Header_ReadByte(s, &header->State, &temp)) return;
case GZipState_Filename:
if ((header->Flags & 0x08) != 0) {
for (; ;) {
temp = s->TryReadByte();
if (temp == -1) return;
if (temp == 0) break;
}
}
header->State++;
case GZipState_Comment:
if ((header->Flags & 0x10) != 0) {
for (; ;) {
temp = s->TryReadByte();
if (temp == -1) return;
if (temp == 0) break;
}
}
header->State++;
case GZipState_HeaderChecksum:
if ((header->Flags & 0x02) != 0) {
for (; header->PartsRead < 2; header->PartsRead++) {
temp = s->TryReadByte();
if (temp == -1) return;
}
}
header->State++;
header->PartsRead = 0;
header->Done = true;
}
}
void ZLibHeader_Init(ZLibHeader* header) {
header->State = ZLibState_CompressionMethod;
header->Done = false;
header->LZ77WindowSize = 0;
}
void ZLibHeader_Read(Stream* s, ZLibHeader* header) {
Int32 temp;
switch (header->State) {
case ZLibState_CompressionMethod:
if (!Header_ReadByte(s, &header->State, &temp)) return;
if ((temp & 0x0F) != 0x08) {
ErrorHandler_Fail("Only DEFLATE compression supported");
}
Int32 log2Size = (temp >> 4) + 8;
header->LZ77WindowSize = 1L << log2Size;
if (header->LZ77WindowSize > 32768) {
ErrorHandler_Fail("LZ77 window size must be 32KB or less");
}
case ZLibState_Flags:
if (!Header_ReadByte(s, &header->State, &temp)) return;
if ((temp & 0x20) != 0) {
ErrorHandler_Fail("Unsupported ZLIB header flags");
}
header->Done = true;
}
}

32
src/Client/Deflate.h Normal file
View File

@ -0,0 +1,32 @@
#ifndef CS_DEFLATE_H
#define CS_DEFLATE_H
#include "Typedefs.h"
#include "Stream.h"
/* Decodes data compressed using DEFLATE.
Copyright 2017 ClassicalSharp | Licensed under BSD-3
*/
typedef struct GZipHeader_ {
UInt8 State;
bool Done;
UInt8 PartsRead;
Int32 Flags;
} GZipHeader;
/* Initalises state of GZIP header. */
void GZipHeader_Init(GZipHeader* header);
/* Reads part of the GZIP header. header.Done is set to true on completion of reading the header. */
void GZipHeader_Read(Stream* s, GZipHeader* header);
typedef struct ZLibHeader_ {
UInt8 State;
bool Done;
Int32 LZ77WindowSize;
} ZLibHeader;
/* Initalises state of ZLIB header. */
void ZLibHeader_Init(ZLibHeader* header);
/* Reads part of the ZLIB header. header.Done is set to true on completion of reading the header. */
void ZLibHeader_Read(Stream* s, ZLibHeader* header);
#endif

View File

@ -1,94 +0,0 @@
#include "GZipHeader.h"
#include "ErrorHandler.h"
void GZipHeader_Init(GZipHeader* header) {
header->State = GZipState_Header1;
header->Done = false;
header->Flags = 0;
header->PartsRead = 0;
}
bool GZipHeader_ReadByte(Stream* s, GZipHeader* header, Int32* value) {
*value = s->TryReadByte();
if (*value == -1) return false;
header->State++;
return true;
}
bool GZipHeader_ReadAndCheckByte(Stream* s, GZipHeader* header, UInt8 expected) {
Int32 value;
if (!GZipHeader_ReadByte(s, header, &value)) return false;
if (value != expected) {
ErrorHandler_Fail("Unexpected constant in GZIP header");
}
return true;
}
void GZipHeader_Read(Stream* s, GZipHeader* header) {
Int32 temp;
switch (header->State) {
case GZipState_Header1:
if (!GZipHeader_ReadAndCheckByte(s, header, 0x1F)) return;
case GZipState_Header2:
if (!GZipHeader_ReadAndCheckByte(s, header, 0x8B)) return;
case GZipState_CompressionMethod:
if (!GZipHeader_ReadAndCheckByte(s, header, 0x08)) return;
case GZipState_Flags:
if (!GZipHeader_ReadByte(s, header, &header->Flags)) return;
if ((header->Flags & 0x04) != 0) {
ErrorHandler_Fail("Unsupported GZIP header flags");
}
case GZipState_LastModifiedTime:
for (; header->PartsRead < 4; header->PartsRead++) {
temp = s->TryReadByte();
if (temp == -1) return;
}
header->PartsRead = 0;
header->State++;
case GZipState_CompressionFlags:
if (!GZipHeader_ReadByte(s, header, &temp)) return;
case GZipState_OperatingSystem:
if (!GZipHeader_ReadByte(s, header, &temp)) return;
case GZipState_Filename:
if ((header->Flags & 0x08) != 0) {
for (; ;) {
temp = s->TryReadByte();
if (temp == -1) return;
if (temp == 0) break;
}
}
header->State++;
case GZipState_Comment:
if ((header->Flags & 0x10) != 0) {
for (; ;) {
temp = s->TryReadByte();
if (temp == -1) return;
if (temp == 0) break;
}
}
header->State++;
case GZipState_HeaderChecksum:
if ((header->Flags & 0x02) != 0) {
for (; header->PartsRead < 2; header->PartsRead++) {
temp = s->TryReadByte();
if (temp == -1) return;
}
}
header->PartsRead = 0;
header->State++;
header->Done = true;
}
}

View File

@ -1,35 +0,0 @@
#ifndef CS_GZIPHEADERREADER_H
#define CS_GZIPHEADERREADER_H
#include "Typedefs.h"
#include "Stream.h"
/* Skips the GZip header in a stream.
Copyright 2017 ClassicalSharp | Licensed under BSD-3
*/
typedef Int32 GZipState;
#define GZipState_Header1 0
#define GZipState_Header2 1
#define GZipState_CompressionMethod 2
#define GZipState_Flags 3
#define GZipState_LastModifiedTime 4
#define GZipState_CompressionFlags 5
#define GZipState_OperatingSystem 6
#define GZipState_HeaderChecksum 7
#define GZipState_Filename 8
#define GZipState_Comment 9
#define GZipState_Done 10
typedef struct GZipHeader_ {
/* State header reader is up to.*/
GZipState State;
/* Whether header has finished being read. */
bool Done;
Int32 Flags;
Int32 PartsRead;
} GZipHeader;
/* Initalises state of GZIP header. */
void GZipHeader_Init(GZipHeader* header);
/* Reads part of the GZIP header. header.Done is set to true on completion. */
void GZipHeader_Read(Stream* s, GZipHeader* header);
#endif