mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-09 17:48:19 +00:00
Compare commits
3 commits
a0b6a51282
...
70ed41b37f
Author | SHA1 | Date | |
---|---|---|---|
70ed41b37f | |||
7208b9a67b | |||
389efa0c27 |
|
@ -2707,6 +2707,7 @@ if(TOOLS)
|
|||
src/tools/${TOOL}.cpp
|
||||
${EXTRA_TOOL_SRC}
|
||||
$<TARGET_OBJECTS:engine-shared>
|
||||
$<TARGET_OBJECTS:game-shared>
|
||||
)
|
||||
target_include_directories(${TOOL} SYSTEM PRIVATE ${TOOL_INCLUDE_DIRS})
|
||||
target_link_libraries(${TOOL} ${TOOL_LIBS})
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
# Cammodude
|
||||
#modified by:
|
||||
# Cammodude 2024-09-03 22:19:06
|
||||
# Cammodude 2024-10-03 18:04:16
|
||||
##### /authors #####
|
||||
|
||||
##### translated strings #####
|
||||
|
@ -83,7 +84,7 @@ Console
|
|||
== Konsool
|
||||
|
||||
Controls
|
||||
== Kontrollit
|
||||
== Kontrollid
|
||||
|
||||
Count players only
|
||||
== Loe ainult mängijaid
|
||||
|
@ -317,7 +318,7 @@ Reset filter
|
|||
== Lähtesta filter
|
||||
|
||||
Score
|
||||
== Seis
|
||||
== Skoor
|
||||
|
||||
Score limit
|
||||
== Punktilimiit
|
||||
|
@ -365,7 +366,7 @@ Spectate next
|
|||
== Jälgi järgmist
|
||||
|
||||
Spectate previous
|
||||
== Järgi eelmist
|
||||
== Jälgi eelmist
|
||||
|
||||
Spectator mode
|
||||
== Pealtvaataja režiim
|
||||
|
@ -521,7 +522,7 @@ Replay feature is disabled!
|
|||
== Korduse funktsioon on keelatud!
|
||||
|
||||
The width of texture %s is not divisible by %d, or the height is not divisible by %d, which might cause visual bugs.
|
||||
== Tekstuuri %s laius ei jagu %d -ga või kõrgus ei jagu %d -ga, mis võib põhjustada visuaalseid vigu.
|
||||
== Tekstuuri %s laius ei jagu %d-ga või kõrgus ei jagu %d-ga, mis võib põhjustada visuaalseid vigu.
|
||||
|
||||
Warning
|
||||
== Hoiatus
|
||||
|
@ -1707,10 +1708,10 @@ Entities
|
|||
== Üksused
|
||||
|
||||
Door Laser Outline Color
|
||||
== Ukse laseri Kontuuri Värv
|
||||
== Ukse Laseri Kontuuri Värv
|
||||
|
||||
Door Laser Inner Color
|
||||
== Ukse laseri Sisene Värv
|
||||
== Ukse Laseri Sisene Värv
|
||||
|
||||
Freeze Laser Outline Color
|
||||
== Külmutava Laseri Kontuuri Värv
|
||||
|
|
|
@ -4037,100 +4037,6 @@ const char *str_next_token(const char *str, const char *delim, char *buffer, int
|
|||
return tok + len;
|
||||
}
|
||||
|
||||
void str_to_int32(int *ints, size_t num_ints, const char *str)
|
||||
{
|
||||
dbg_assert(num_ints > 0, "str_to_int32: num_ints invalid");
|
||||
|
||||
// Clear all integers, which also ensures null-termination,
|
||||
// as the last byte is never written to.
|
||||
for(size_t i = 0; i < num_ints; i++)
|
||||
{
|
||||
ints[i] = 0;
|
||||
}
|
||||
|
||||
size_t byte_index = 0;
|
||||
const size_t total_bytes = num_ints * sizeof(int) - 1; // -1 for null-termination
|
||||
auto &&write_byte = [ints, &byte_index](int b) mutable {
|
||||
ints[byte_index / sizeof(int)] |= b << ((sizeof(int) - byte_index % sizeof(int) - 1) * 8);
|
||||
byte_index++;
|
||||
};
|
||||
|
||||
// Write each UTF-8 codepoint individually
|
||||
while(true)
|
||||
{
|
||||
const int codepoint = str_utf8_decode(&str);
|
||||
dbg_assert(codepoint != -1, "str_to_int32: invalid UTF-8 in string");
|
||||
if(codepoint == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
char encoded[4];
|
||||
const size_t encoded_count = str_utf8_encode(encoded, codepoint);
|
||||
dbg_assert(encoded_count <= total_bytes - byte_index, "str_to_int32: string truncated");
|
||||
for(size_t i = 0; i < encoded_count; i++)
|
||||
{
|
||||
write_byte(encoded[i] + 128);
|
||||
}
|
||||
}
|
||||
|
||||
// Write padding
|
||||
while(byte_index < total_bytes)
|
||||
{
|
||||
write_byte(128);
|
||||
}
|
||||
}
|
||||
|
||||
void int32_to_str(const int *ints, size_t num_ints, char *str, size_t str_size)
|
||||
{
|
||||
dbg_assert(num_ints > 0, "int32_to_str: num_ints invalid");
|
||||
dbg_assert(str_size >= num_ints * sizeof(int), "int32_to_str: str_size invalid");
|
||||
|
||||
// Unpack string without validation
|
||||
size_t str_index = 0;
|
||||
for(size_t int_index = 0; int_index < num_ints; int_index++)
|
||||
{
|
||||
const int current_int = ints[int_index];
|
||||
str[str_index] = ((current_int >> 24) & 0xff) - 128;
|
||||
str_index++;
|
||||
str[str_index] = ((current_int >> 16) & 0xff) - 128;
|
||||
str_index++;
|
||||
str[str_index] = ((current_int >> 8) & 0xff) - 128;
|
||||
str_index++;
|
||||
str[str_index] = (current_int & 0xff) - 128;
|
||||
str_index++;
|
||||
}
|
||||
// Ensure null-termination
|
||||
str[str_index - 1] = '\0';
|
||||
|
||||
// Validate
|
||||
const char *check_str = str;
|
||||
int str_check_index = 0;
|
||||
while(true)
|
||||
{
|
||||
const char *prev_check_str = check_str;
|
||||
const int codepoint = str_utf8_decode(&check_str);
|
||||
if(codepoint == 0)
|
||||
{
|
||||
// Check for (early) null-termination.
|
||||
str[str_check_index] = '\0';
|
||||
break;
|
||||
}
|
||||
const size_t codepoint_size = check_str - prev_check_str;
|
||||
if(codepoint == -1)
|
||||
{
|
||||
// Replace invalid codepoints with question mark characters instead of the Unicode
|
||||
// replacement character, because the replacement character is 3 bytes long, so the
|
||||
// string with added replacement characters may not fit into the buffer.
|
||||
for(size_t i = 0; i < codepoint_size; i++)
|
||||
{
|
||||
str[str_check_index + i] = '?';
|
||||
}
|
||||
}
|
||||
str_check_index += codepoint_size;
|
||||
}
|
||||
}
|
||||
|
||||
static_assert(sizeof(unsigned) == 4, "unsigned must be 4 bytes in size");
|
||||
static_assert(sizeof(unsigned) == sizeof(int), "unsigned and int must have the same size");
|
||||
|
||||
|
|
|
@ -2418,9 +2418,6 @@ const char *str_next_token(const char *str, const char *delim, char *buffer, int
|
|||
*/
|
||||
int str_in_list(const char *list, const char *delim, const char *needle);
|
||||
|
||||
void str_to_int32(int *ints, size_t num_ints, const char *str);
|
||||
void int32_to_str(const int *ints, size_t num_ints, char *str, size_t str_size);
|
||||
|
||||
/**
|
||||
* Packs 4 big endian bytes into an unsigned.
|
||||
*
|
||||
|
|
|
@ -20,7 +20,7 @@ CGhost::CGhost() :
|
|||
|
||||
void CGhost::GetGhostSkin(CGhostSkin *pSkin, const char *pSkinName, int UseCustomColor, int ColorBody, int ColorFeet)
|
||||
{
|
||||
str_to_int32(&pSkin->m_Skin0, 6, pSkinName);
|
||||
StrToInts(&pSkin->m_Skin0, 6, pSkinName);
|
||||
pSkin->m_UseCustomColor = UseCustomColor;
|
||||
pSkin->m_ColorBody = ColorBody;
|
||||
pSkin->m_ColorFeet = ColorFeet;
|
||||
|
@ -386,7 +386,7 @@ void CGhost::OnRender()
|
|||
void CGhost::InitRenderInfos(CGhostItem *pGhost)
|
||||
{
|
||||
char aSkinName[24];
|
||||
int32_to_str(&pGhost->m_Skin.m_Skin0, 6, aSkinName, std::size(aSkinName));
|
||||
IntsToStr(&pGhost->m_Skin.m_Skin0, 6, aSkinName, std::size(aSkinName));
|
||||
CTeeRenderInfo *pRenderInfo = &pGhost->m_RenderInfo;
|
||||
|
||||
const CSkin *pSkin = m_pClient->m_Skins.Find(aSkinName);
|
||||
|
@ -690,7 +690,7 @@ void CGhost::OnRefreshSkins()
|
|||
if(Ghost.Empty())
|
||||
return;
|
||||
char aSkinName[24];
|
||||
int32_to_str(&Ghost.m_Skin.m_Skin0, 6, aSkinName, std::size(aSkinName));
|
||||
IntsToStr(&Ghost.m_Skin.m_Skin0, 6, aSkinName, std::size(aSkinName));
|
||||
CTeeRenderInfo *pRenderInfo = &Ghost.m_RenderInfo;
|
||||
if(aSkinName[0] != '\0')
|
||||
{
|
||||
|
|
|
@ -1383,10 +1383,13 @@ void CGameClient::OnNewSnapshot()
|
|||
{
|
||||
CClientData *pClient = &m_aClients[ClientID];
|
||||
|
||||
int32_to_str(&pInfo->m_Name0, 4, pClient->m_aName, std::size(pClient->m_aName));
|
||||
int32_to_str(&pInfo->m_Clan0, 3, pClient->m_aClan, std::size(pClient->m_aClan));
|
||||
if(!IntsToStr(&pInfo->m_Name0, 4, pClient->m_aName, std::size(pClient->m_aName)))
|
||||
{
|
||||
str_copy(pClient->m_aName, "nameless tee");
|
||||
}
|
||||
IntsToStr(&pInfo->m_Clan0, 3, pClient->m_aClan, std::size(pClient->m_aClan));
|
||||
pClient->m_Country = pInfo->m_Country;
|
||||
int32_to_str(&pInfo->m_Skin0, 6, pClient->m_aSkinName, std::size(pClient->m_aSkinName));
|
||||
IntsToStr(&pInfo->m_Skin0, 6, pClient->m_aSkinName, std::size(pClient->m_aSkinName));
|
||||
|
||||
pClient->m_UseCustomColor = pInfo->m_UseCustomColor;
|
||||
pClient->m_ColorBody = pInfo->m_ColorBody;
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include <engine/sound.h>
|
||||
#include <engine/storage.h>
|
||||
|
||||
#include <game/gamecore.h>
|
||||
#include <game/mapitems_ex.h>
|
||||
|
||||
#include "image.h"
|
||||
|
@ -173,7 +174,7 @@ bool CEditorMap::Save(const char *pFileName)
|
|||
GItem.m_NumLayers = 0;
|
||||
|
||||
// save group name
|
||||
str_to_int32(GItem.m_aName, std::size(GItem.m_aName), pGroup->m_aName);
|
||||
StrToInts(GItem.m_aName, std::size(GItem.m_aName), pGroup->m_aName);
|
||||
|
||||
for(const std::shared_ptr<CLayer> &pLayer : pGroup->m_vpLayers)
|
||||
{
|
||||
|
@ -242,7 +243,7 @@ bool CEditorMap::Save(const char *pFileName)
|
|||
Item.m_Data = Writer.AddData((size_t)pLayerTiles->m_Width * pLayerTiles->m_Height * sizeof(CTile), pLayerTiles->m_pTiles);
|
||||
|
||||
// save layer name
|
||||
str_to_int32(Item.m_aName, std::size(Item.m_aName), pLayerTiles->m_aName);
|
||||
StrToInts(Item.m_aName, std::size(Item.m_aName), pLayerTiles->m_aName);
|
||||
|
||||
Writer.AddItem(MAPITEMTYPE_LAYER, LayerCount, sizeof(Item), &Item);
|
||||
|
||||
|
@ -284,7 +285,7 @@ bool CEditorMap::Save(const char *pFileName)
|
|||
Item.m_Data = Writer.AddDataSwapped(pLayerQuads->m_vQuads.size() * sizeof(CQuad), pLayerQuads->m_vQuads.data());
|
||||
|
||||
// save layer name
|
||||
str_to_int32(Item.m_aName, std::size(Item.m_aName), pLayerQuads->m_aName);
|
||||
StrToInts(Item.m_aName, std::size(Item.m_aName), pLayerQuads->m_aName);
|
||||
|
||||
Writer.AddItem(MAPITEMTYPE_LAYER, LayerCount, sizeof(Item), &Item);
|
||||
|
||||
|
@ -310,7 +311,7 @@ bool CEditorMap::Save(const char *pFileName)
|
|||
Item.m_Data = Writer.AddDataSwapped(pLayerSounds->m_vSources.size() * sizeof(CSoundSource), pLayerSounds->m_vSources.data());
|
||||
|
||||
// save layer name
|
||||
str_to_int32(Item.m_aName, std::size(Item.m_aName), pLayerSounds->m_aName);
|
||||
StrToInts(Item.m_aName, std::size(Item.m_aName), pLayerSounds->m_aName);
|
||||
|
||||
Writer.AddItem(MAPITEMTYPE_LAYER, LayerCount, sizeof(Item), &Item);
|
||||
GItem.m_NumLayers++;
|
||||
|
@ -334,7 +335,7 @@ bool CEditorMap::Save(const char *pFileName)
|
|||
Item.m_StartPoint = PointCount;
|
||||
Item.m_NumPoints = m_vpEnvelopes[e]->m_vPoints.size();
|
||||
Item.m_Synchronized = m_vpEnvelopes[e]->m_Synchronized;
|
||||
str_to_int32(Item.m_aName, std::size(Item.m_aName), m_vpEnvelopes[e]->m_aName);
|
||||
StrToInts(Item.m_aName, std::size(Item.m_aName), m_vpEnvelopes[e]->m_aName);
|
||||
|
||||
Writer.AddItem(MAPITEMTYPE_ENVELOPE, e, sizeof(Item), &Item);
|
||||
PointCount += Item.m_NumPoints;
|
||||
|
@ -623,7 +624,7 @@ bool CEditorMap::Load(const char *pFileName, int StorageType, const std::functio
|
|||
|
||||
// load group name
|
||||
if(pGItem->m_Version >= 3)
|
||||
int32_to_str(pGItem->m_aName, std::size(pGItem->m_aName), pGroup->m_aName, std::size(pGroup->m_aName));
|
||||
IntsToStr(pGItem->m_aName, std::size(pGItem->m_aName), pGroup->m_aName, std::size(pGroup->m_aName));
|
||||
|
||||
for(int l = 0; l < pGItem->m_NumLayers; l++)
|
||||
{
|
||||
|
@ -699,7 +700,7 @@ bool CEditorMap::Load(const char *pFileName, int StorageType, const std::functio
|
|||
|
||||
// load layer name
|
||||
if(pTilemapItem->m_Version >= 3)
|
||||
int32_to_str(pTilemapItem->m_aName, std::size(pTilemapItem->m_aName), pTiles->m_aName, std::size(pTiles->m_aName));
|
||||
IntsToStr(pTilemapItem->m_aName, std::size(pTilemapItem->m_aName), pTiles->m_aName, std::size(pTiles->m_aName));
|
||||
|
||||
if(pTiles->m_Tele)
|
||||
{
|
||||
|
@ -825,7 +826,7 @@ bool CEditorMap::Load(const char *pFileName, int StorageType, const std::functio
|
|||
|
||||
// load layer name
|
||||
if(pQuadsItem->m_Version >= 2)
|
||||
int32_to_str(pQuadsItem->m_aName, std::size(pQuadsItem->m_aName), pQuads->m_aName, std::size(pQuads->m_aName));
|
||||
IntsToStr(pQuadsItem->m_aName, std::size(pQuadsItem->m_aName), pQuads->m_aName, std::size(pQuads->m_aName));
|
||||
|
||||
void *pData = DataFile.GetDataSwapped(pQuadsItem->m_Data);
|
||||
pGroup->AddLayer(pQuads);
|
||||
|
@ -848,7 +849,7 @@ bool CEditorMap::Load(const char *pFileName, int StorageType, const std::functio
|
|||
pSounds->m_Sound = -1;
|
||||
|
||||
// load layer name
|
||||
int32_to_str(pSoundsItem->m_aName, std::size(pSoundsItem->m_aName), pSounds->m_aName, std::size(pSounds->m_aName));
|
||||
IntsToStr(pSoundsItem->m_aName, std::size(pSoundsItem->m_aName), pSounds->m_aName, std::size(pSounds->m_aName));
|
||||
|
||||
// load data
|
||||
void *pData = DataFile.GetDataSwapped(pSoundsItem->m_Data);
|
||||
|
@ -873,7 +874,7 @@ bool CEditorMap::Load(const char *pFileName, int StorageType, const std::functio
|
|||
pSounds->m_Sound = -1;
|
||||
|
||||
// load layer name
|
||||
int32_to_str(pSoundsItem->m_aName, std::size(pSoundsItem->m_aName), pSounds->m_aName, std::size(pSounds->m_aName));
|
||||
IntsToStr(pSoundsItem->m_aName, std::size(pSoundsItem->m_aName), pSounds->m_aName, std::size(pSounds->m_aName));
|
||||
|
||||
// load data
|
||||
CSoundSource_DEPRECATED *pData = (CSoundSource_DEPRECATED *)DataFile.GetDataSwapped(pSoundsItem->m_Data);
|
||||
|
@ -940,7 +941,7 @@ bool CEditorMap::Load(const char *pFileName, int StorageType, const std::functio
|
|||
mem_copy(&pEnv->m_vPoints[p].m_Bezier, pPointBezier, sizeof(CEnvPointBezier));
|
||||
}
|
||||
if(pItem->m_aName[0] != -1) // compatibility with old maps
|
||||
int32_to_str(pItem->m_aName, std::size(pItem->m_aName), pEnv->m_aName, std::size(pEnv->m_aName));
|
||||
IntsToStr(pItem->m_aName, std::size(pItem->m_aName), pEnv->m_aName, std::size(pEnv->m_aName));
|
||||
m_vpEnvelopes.push_back(pEnv);
|
||||
if(pItem->m_Version >= CMapItemEnvelope_v2::CURRENT_VERSION)
|
||||
pEnv->m_Synchronized = pItem->m_Synchronized;
|
||||
|
|
|
@ -63,6 +63,57 @@ float CTuningParams::GetWeaponFireDelay(int Weapon) const
|
|||
}
|
||||
}
|
||||
|
||||
void StrToInts(int *pInts, size_t NumInts, const char *pStr)
|
||||
{
|
||||
dbg_assert(NumInts > 0, "StrToInts: NumInts invalid");
|
||||
const size_t StrSize = str_length(pStr) + 1;
|
||||
dbg_assert(StrSize <= NumInts * sizeof(int), "StrToInts: string truncated");
|
||||
|
||||
for(size_t i = 0; i < NumInts; i++)
|
||||
{
|
||||
// Copy to temporary buffer to ensure we don't read past the end of the input string
|
||||
char aBuf[sizeof(int)] = {0, 0, 0, 0};
|
||||
for(size_t c = 0; c < sizeof(int) && i * sizeof(int) + c < StrSize; c++)
|
||||
{
|
||||
aBuf[c] = pStr[i * sizeof(int) + c];
|
||||
}
|
||||
pInts[i] = ((aBuf[0] + 128) << 24) | ((aBuf[1] + 128) << 16) | ((aBuf[2] + 128) << 8) | (aBuf[3] + 128);
|
||||
}
|
||||
// Last byte is always zero and unused in this format
|
||||
pInts[NumInts - 1] &= 0xFFFFFF00;
|
||||
}
|
||||
|
||||
bool IntsToStr(const int *pInts, size_t NumInts, char *pStr, size_t StrSize)
|
||||
{
|
||||
dbg_assert(NumInts > 0, "IntsToStr: NumInts invalid");
|
||||
dbg_assert(StrSize >= NumInts * sizeof(int), "IntsToStr: StrSize invalid");
|
||||
|
||||
// Unpack string without validation
|
||||
size_t StrIndex = 0;
|
||||
for(size_t IntIndex = 0; IntIndex < NumInts; IntIndex++)
|
||||
{
|
||||
const int CurrentInt = pInts[IntIndex];
|
||||
pStr[StrIndex] = ((CurrentInt >> 24) & 0xff) - 128;
|
||||
StrIndex++;
|
||||
pStr[StrIndex] = ((CurrentInt >> 16) & 0xff) - 128;
|
||||
StrIndex++;
|
||||
pStr[StrIndex] = ((CurrentInt >> 8) & 0xff) - 128;
|
||||
StrIndex++;
|
||||
pStr[StrIndex] = (CurrentInt & 0xff) - 128;
|
||||
StrIndex++;
|
||||
}
|
||||
// Ensure null-termination
|
||||
pStr[StrIndex - 1] = '\0';
|
||||
|
||||
// Ensure valid UTF-8
|
||||
if(str_utf8_check(pStr))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
pStr[0] = '\0';
|
||||
return false;
|
||||
}
|
||||
|
||||
float VelocityRamp(float Value, float Start, float Range, float Curvature)
|
||||
{
|
||||
if(Value < Start)
|
||||
|
|
|
@ -65,6 +65,10 @@ public:
|
|||
float GetWeaponFireDelay(int Weapon) const;
|
||||
};
|
||||
|
||||
// Do not use these function unless for legacy code!
|
||||
void StrToInts(int *pInts, size_t NumInts, const char *pStr);
|
||||
bool IntsToStr(const int *pInts, size_t NumInts, char *pStr, size_t StrSize);
|
||||
|
||||
inline vec2 CalcPos(vec2 Pos, vec2 Velocity, float Curvature, float Speed, float Time)
|
||||
{
|
||||
vec2 n;
|
||||
|
|
|
@ -315,10 +315,10 @@ void CPlayer::Snap(int SnappingClient)
|
|||
if(!pClientInfo)
|
||||
return;
|
||||
|
||||
str_to_int32(&pClientInfo->m_Name0, 4, Server()->ClientName(m_ClientID));
|
||||
str_to_int32(&pClientInfo->m_Clan0, 3, Server()->ClientClan(m_ClientID));
|
||||
StrToInts(&pClientInfo->m_Name0, 4, Server()->ClientName(m_ClientID));
|
||||
StrToInts(&pClientInfo->m_Clan0, 3, Server()->ClientClan(m_ClientID));
|
||||
pClientInfo->m_Country = Server()->ClientCountry(m_ClientID);
|
||||
str_to_int32(&pClientInfo->m_Skin0, 6, m_TeeInfos.m_aSkinName);
|
||||
StrToInts(&pClientInfo->m_Skin0, 6, m_TeeInfos.m_aSkinName);
|
||||
pClientInfo->m_UseCustomColor = m_TeeInfos.m_UseCustomColor;
|
||||
pClientInfo->m_ColorBody = m_TeeInfos.m_ColorBody;
|
||||
pClientInfo->m_ColorFeet = m_TeeInfos.m_ColorFeet;
|
||||
|
@ -465,9 +465,9 @@ void CPlayer::FakeSnap()
|
|||
if(!pClientInfo)
|
||||
return;
|
||||
|
||||
str_to_int32(&pClientInfo->m_Name0, 4, " ");
|
||||
str_to_int32(&pClientInfo->m_Clan0, 3, "");
|
||||
str_to_int32(&pClientInfo->m_Skin0, 6, "default");
|
||||
StrToInts(&pClientInfo->m_Name0, 4, " ");
|
||||
StrToInts(&pClientInfo->m_Clan0, 3, "");
|
||||
StrToInts(&pClientInfo->m_Skin0, 6, "default");
|
||||
|
||||
if(m_Paused != PAUSE_PAUSED)
|
||||
return;
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
#include <base/system.h>
|
||||
|
||||
#include <game/gamecore.h>
|
||||
|
||||
TEST(Str, Dist)
|
||||
{
|
||||
EXPECT_EQ(str_utf8_dist("aaa", "aaa"), 0);
|
||||
|
@ -1083,98 +1085,98 @@ TEST(Str, CountChar)
|
|||
EXPECT_EQ(str_countchr(pStr, 'y'), 0);
|
||||
}
|
||||
|
||||
TEST(Str, StrToInt32)
|
||||
TEST(Str, StrToInts)
|
||||
{
|
||||
int aInts[8];
|
||||
|
||||
str_to_int32(aInts, 1, "a");
|
||||
StrToInts(aInts, 1, "a");
|
||||
EXPECT_EQ(aInts[0], 0xE1808000);
|
||||
|
||||
str_to_int32(aInts, 1, "ab");
|
||||
StrToInts(aInts, 1, "ab");
|
||||
EXPECT_EQ(aInts[0], 0xE1E28000);
|
||||
|
||||
str_to_int32(aInts, 1, "abc");
|
||||
StrToInts(aInts, 1, "abc");
|
||||
EXPECT_EQ(aInts[0], 0xE1E2E300);
|
||||
|
||||
str_to_int32(aInts, 2, "abcd");
|
||||
StrToInts(aInts, 2, "abcd");
|
||||
EXPECT_EQ(aInts[0], 0xE1E2E3E4);
|
||||
EXPECT_EQ(aInts[1], 0x80808000);
|
||||
|
||||
str_to_int32(aInts, 2, "abcde");
|
||||
StrToInts(aInts, 2, "abcde");
|
||||
EXPECT_EQ(aInts[0], 0xE1E2E3E4);
|
||||
EXPECT_EQ(aInts[1], 0xE5808000);
|
||||
|
||||
str_to_int32(aInts, 2, "abcdef");
|
||||
StrToInts(aInts, 2, "abcdef");
|
||||
EXPECT_EQ(aInts[0], 0xE1E2E3E4);
|
||||
EXPECT_EQ(aInts[1], 0xE5E68000);
|
||||
|
||||
str_to_int32(aInts, 2, "abcdefg");
|
||||
StrToInts(aInts, 2, "abcdefg");
|
||||
EXPECT_EQ(aInts[0], 0xE1E2E3E4);
|
||||
EXPECT_EQ(aInts[1], 0xE5E6E700);
|
||||
|
||||
str_to_int32(aInts, 2, "öüä");
|
||||
StrToInts(aInts, 2, "öüä");
|
||||
EXPECT_EQ(aInts[0], 0x4336433C);
|
||||
EXPECT_EQ(aInts[1], 0x43248000);
|
||||
|
||||
str_to_int32(aInts, 3, "aβい🐘");
|
||||
StrToInts(aInts, 3, "aβい🐘");
|
||||
EXPECT_EQ(aInts[0], 0xE14E3263);
|
||||
EXPECT_EQ(aInts[1], 0x0104701F);
|
||||
EXPECT_EQ(aInts[2], 0x10188000);
|
||||
|
||||
// long padding
|
||||
str_to_int32(aInts, 4, "abc");
|
||||
StrToInts(aInts, 4, "abc");
|
||||
EXPECT_EQ(aInts[0], 0xE1E2E380);
|
||||
EXPECT_EQ(aInts[1], 0x80808080);
|
||||
EXPECT_EQ(aInts[2], 0x80808080);
|
||||
EXPECT_EQ(aInts[3], 0x80808000);
|
||||
}
|
||||
|
||||
TEST(Str, Int32ToStr)
|
||||
TEST(Str, IntsToStr)
|
||||
{
|
||||
int aInts[8];
|
||||
char aStr[sizeof(aInts)];
|
||||
|
||||
aInts[0] = 0xE1808000;
|
||||
int32_to_str(aInts, 1, aStr, std::size(aStr));
|
||||
EXPECT_TRUE(IntsToStr(aInts, 1, aStr, std::size(aStr)));
|
||||
EXPECT_STREQ(aStr, "a");
|
||||
|
||||
aInts[0] = 0xE1E28000;
|
||||
int32_to_str(aInts, 1, aStr, std::size(aStr));
|
||||
EXPECT_TRUE(IntsToStr(aInts, 1, aStr, std::size(aStr)));
|
||||
EXPECT_STREQ(aStr, "ab");
|
||||
|
||||
aInts[0] = 0xE1E2E300;
|
||||
int32_to_str(aInts, 1, aStr, std::size(aStr));
|
||||
EXPECT_TRUE(IntsToStr(aInts, 1, aStr, std::size(aStr)));
|
||||
EXPECT_STREQ(aStr, "abc");
|
||||
|
||||
aInts[0] = 0xE1E2E3E4;
|
||||
aInts[1] = 0x80808000;
|
||||
int32_to_str(aInts, 2, aStr, std::size(aStr));
|
||||
EXPECT_TRUE(IntsToStr(aInts, 2, aStr, std::size(aStr)));
|
||||
EXPECT_STREQ(aStr, "abcd");
|
||||
|
||||
aInts[0] = 0xE1E2E3E4;
|
||||
aInts[1] = 0xE5808000;
|
||||
int32_to_str(aInts, 2, aStr, std::size(aStr));
|
||||
EXPECT_TRUE(IntsToStr(aInts, 2, aStr, std::size(aStr)));
|
||||
EXPECT_STREQ(aStr, "abcde");
|
||||
|
||||
aInts[0] = 0xE1E2E3E4;
|
||||
aInts[1] = 0xE5E68000;
|
||||
int32_to_str(aInts, 2, aStr, std::size(aStr));
|
||||
EXPECT_TRUE(IntsToStr(aInts, 2, aStr, std::size(aStr)));
|
||||
EXPECT_STREQ(aStr, "abcdef");
|
||||
|
||||
aInts[0] = 0xE1E2E3E4;
|
||||
aInts[1] = 0xE5E6E700;
|
||||
int32_to_str(aInts, 2, aStr, std::size(aStr));
|
||||
EXPECT_TRUE(IntsToStr(aInts, 2, aStr, std::size(aStr)));
|
||||
EXPECT_STREQ(aStr, "abcdefg");
|
||||
|
||||
aInts[0] = 0x4336433C;
|
||||
aInts[1] = 0x43248000;
|
||||
int32_to_str(aInts, 2, aStr, std::size(aStr));
|
||||
EXPECT_TRUE(IntsToStr(aInts, 2, aStr, std::size(aStr)));
|
||||
EXPECT_STREQ(aStr, "öüä");
|
||||
|
||||
aInts[0] = 0xE14E3263;
|
||||
aInts[1] = 0x0104701F;
|
||||
aInts[2] = 0x10188000;
|
||||
int32_to_str(aInts, 3, aStr, std::size(aStr));
|
||||
EXPECT_TRUE(IntsToStr(aInts, 3, aStr, std::size(aStr)));
|
||||
EXPECT_STREQ(aStr, "aβい🐘");
|
||||
|
||||
// long padding
|
||||
|
@ -1182,7 +1184,7 @@ TEST(Str, Int32ToStr)
|
|||
aInts[1] = 0x80808080;
|
||||
aInts[2] = 0x80808080;
|
||||
aInts[3] = 0x80808000;
|
||||
int32_to_str(aInts, 4, aStr, std::size(aStr));
|
||||
EXPECT_TRUE(IntsToStr(aInts, 4, aStr, std::size(aStr)));
|
||||
EXPECT_STREQ(aStr, "abc");
|
||||
|
||||
// early null character (0x80)
|
||||
|
@ -1190,34 +1192,34 @@ TEST(Str, Int32ToStr)
|
|||
aInts[1] = 0xE1E2E3E4;
|
||||
aInts[2] = 0xE1E2E3E4;
|
||||
aInts[3] = 0xE1E2E300;
|
||||
int32_to_str(aInts, 4, aStr, std::size(aStr));
|
||||
EXPECT_TRUE(IntsToStr(aInts, 4, aStr, std::size(aStr)));
|
||||
EXPECT_STREQ(aStr, "abc");
|
||||
|
||||
// invalid UTF-8
|
||||
aInts[0] = 0xE17FE200;
|
||||
int32_to_str(aInts, 1, aStr, std::size(aStr));
|
||||
EXPECT_STREQ(aStr, "a?b");
|
||||
EXPECT_FALSE(IntsToStr(aInts, 1, aStr, std::size(aStr)));
|
||||
EXPECT_STREQ(aStr, "");
|
||||
|
||||
// invalid UTF-8 (0x00 in string data, which is translated to '\x80')
|
||||
aInts[0] = 0xE100E200;
|
||||
int32_to_str(aInts, 1, aStr, std::size(aStr));
|
||||
EXPECT_STREQ(aStr, "a?b");
|
||||
EXPECT_FALSE(IntsToStr(aInts, 1, aStr, std::size(aStr)));
|
||||
EXPECT_STREQ(aStr, "");
|
||||
|
||||
// invalid UTF-8
|
||||
aInts[0] = 0xE1E2E36F;
|
||||
aInts[1] = 0x3F40E4E5;
|
||||
aInts[2] = 0xE67FE700;
|
||||
int32_to_str(aInts, 3, aStr, std::size(aStr));
|
||||
EXPECT_STREQ(aStr, "abc???def?g");
|
||||
EXPECT_FALSE(IntsToStr(aInts, 3, aStr, std::size(aStr)));
|
||||
EXPECT_STREQ(aStr, "");
|
||||
|
||||
// invalid UTF-8 and missing null-terminator
|
||||
aInts[0] = 0x7F7F7F7F;
|
||||
int32_to_str(aInts, 1, aStr, std::size(aStr));
|
||||
EXPECT_STREQ(aStr, "???");
|
||||
EXPECT_FALSE(IntsToStr(aInts, 1, aStr, std::size(aStr)));
|
||||
EXPECT_STREQ(aStr, "");
|
||||
|
||||
// missing null-terminator at the end is ignored
|
||||
aInts[0] = 0xE1E2E3E4;
|
||||
int32_to_str(aInts, 1, aStr, std::size(aStr));
|
||||
EXPECT_TRUE(IntsToStr(aInts, 1, aStr, std::size(aStr)));
|
||||
EXPECT_STREQ(aStr, "abc");
|
||||
|
||||
// basic fuzzing: no input integer should result in invalid UTF-8 in the string
|
||||
|
@ -1227,14 +1229,11 @@ TEST(Str, Int32ToStr)
|
|||
aInts[0] = 0xE1 << 24 | i;
|
||||
aInts[1] = i << 8 | 0xE2;
|
||||
aInts[2] = 0xE3 << 24 | i;
|
||||
int32_to_str(aInts, 3, aStr, std::size(aStr));
|
||||
// the valid codespoints should always appear at the expected positions
|
||||
ASSERT_EQ(aStr[0], 'a');
|
||||
ASSERT_EQ(aStr[7], 'b');
|
||||
ASSERT_EQ(aStr[8], 'c');
|
||||
const bool ConversionResult = IntsToStr(aInts, 3, aStr, std::size(aStr));
|
||||
// ensure null-termination before calling str_utf8_check
|
||||
ASSERT_EQ(aStr[11], '\0');
|
||||
ASSERT_TRUE(mem_has_null(aStr, std::size(aStr)));
|
||||
ASSERT_TRUE(str_utf8_check(aStr));
|
||||
ASSERT_TRUE(ConversionResult || aStr[0] == '\0');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
#include <engine/shared/snapshot.h>
|
||||
#include <engine/storage.h>
|
||||
|
||||
#include <game/gamecore.h>
|
||||
|
||||
static const char *TOOL_NAME = "demo_extract_chat";
|
||||
|
||||
class CClientSnapshotHandler
|
||||
|
@ -102,7 +104,7 @@ public:
|
|||
if(ClientID < MAX_CLIENTS)
|
||||
{
|
||||
CClientData *pClient = &m_aClients[ClientID];
|
||||
int32_to_str(&pInfo->m_Name0, 4, pClient->m_aName, sizeof(pClient->m_aName));
|
||||
IntsToStr(&pInfo->m_Name0, 4, pClient->m_aName, sizeof(pClient->m_aName));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include <engine/graphics.h>
|
||||
#include <engine/shared/datafile.h>
|
||||
#include <engine/storage.h>
|
||||
#include <game/gamecore.h>
|
||||
#include <game/mapitems.h>
|
||||
/*
|
||||
Usage: map_convert_07 <source map filepath> <dest map filepath>
|
||||
|
@ -95,7 +96,7 @@ bool CheckImageDimensions(void *pLayerItem, int LayerType, const char *pFilename
|
|||
return true;
|
||||
|
||||
char aTileLayerName[12];
|
||||
int32_to_str(pTMap->m_aName, std::size(pTMap->m_aName), aTileLayerName, std::size(aTileLayerName));
|
||||
IntsToStr(pTMap->m_aName, std::size(pTMap->m_aName), aTileLayerName, std::size(aTileLayerName));
|
||||
|
||||
const char *pName = g_DataReader.GetDataString(pImgItem->m_ImageName);
|
||||
dbg_msg("map_convert_07", "%s: Tile layer \"%s\" uses image \"%s\" with width %d, height %d, which is not divisible by 16. This is not supported in Teeworlds 0.7. Please scale the image and replace it manually.", pFilename, aTileLayerName, pName == nullptr ? "(error)" : pName, pImgItem->m_Width, pImgItem->m_Height);
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include <base/system.h>
|
||||
#include <engine/shared/datafile.h>
|
||||
#include <engine/storage.h>
|
||||
#include <game/gamecore.h>
|
||||
#include <game/mapitems.h>
|
||||
|
||||
bool Process(IStorage *pStorage, const char **pMapNames)
|
||||
|
@ -64,7 +65,7 @@ bool Process(IStorage *pStorage, const char **pMapNames)
|
|||
for(int i = 0; i < 2; ++i)
|
||||
{
|
||||
apTilemap[i] = (CMapItemLayerTilemap *)apItem[i];
|
||||
int32_to_str(apTilemap[i]->m_aName, std::size(apTilemap[i]->m_aName), aaName[i], std::size(aaName[i]));
|
||||
IntsToStr(apTilemap[i]->m_aName, std::size(apTilemap[i]->m_aName), aaName[i], std::size(aaName[i]));
|
||||
}
|
||||
|
||||
if(str_comp(aaName[0], aaName[1]) != 0 || apTilemap[0]->m_Width != apTilemap[1]->m_Width || apTilemap[0]->m_Height != apTilemap[1]->m_Height)
|
||||
|
|
Loading…
Reference in a new issue