From 469e0bbbcac29fcfaaa1c443d680d85cd961af37 Mon Sep 17 00:00:00 2001 From: Eduardo Bart Date: Sat, 12 May 2012 09:30:51 -0300 Subject: [PATCH] make dat reader more compatible with malformed dats --- src/otclient/core/thingstype.cpp | 49 +++++++++++++++++++++++--------- src/otclient/core/thingstype.h | 2 +- src/otclient/ui/uiitem.cpp | 7 ++++- 3 files changed, 43 insertions(+), 15 deletions(-) diff --git a/src/otclient/core/thingstype.cpp b/src/otclient/core/thingstype.cpp index 75a2bacb..a611def4 100644 --- a/src/otclient/core/thingstype.cpp +++ b/src/otclient/core/thingstype.cpp @@ -47,8 +47,12 @@ bool ThingsType::load(const std::string& file) for(int i = 0; i < LastCategory; ++i) { m_things[i].resize(numThings[i]); - for(int id = 0; id < numThings[i]; ++id) - parseThingType(fin, m_things[i][id]); + for(int id = 0; id < numThings[i]; ++id) { + if(!parseThingType(fin, m_things[i][id])) { + logError("corrupt or dat file"); + return false; + } + } } m_loaded = true; @@ -61,18 +65,24 @@ void ThingsType::unload() m_things[i].clear(); } -void ThingsType::parseThingType(const FileStreamPtr& fin, ThingType& thingType) +bool ThingsType::parseThingType(const FileStreamPtr& fin, ThingType& thingType) { - while(true) { + bool done = false; + for(int i=0;igetU8(); if(property == ThingType::LastPropertyValue) { + done = true; break; } thingType.m_properties[property] = true; - if(property == ThingType::IsGround) - thingType.m_parameters[ThingType::GroundSpeed] = fin->getU16(); + if(property == ThingType::IsGround) { + int speed = fin->getU16(); + if(speed == 0) + speed = 100; + thingType.m_parameters[ThingType::GroundSpeed] = speed; + } else if(property == ThingType::IsWritable || property == ThingType::IsWritableOnce) thingType.m_parameters[ThingType::MaxTextLenght] = fin->getU16(); else if(property == ThingType::HasLight) { @@ -107,23 +117,36 @@ void ThingsType::parseThingType(const FileStreamPtr& fin, ThingType& thingType) #endif } + if(!done) + return false; + int totalSprites = 1; for(int i = 0; i < ThingType::LastDimension; ++i) { - if(i == ThingType::ExactSize && thingType.m_dimensions[ThingType::Width] <= 1 && thingType.m_dimensions[ThingType::Height] <= 1) { - thingType.m_dimensions[i] = 32; - continue; + int value; + if(i == ThingType::ExactSize) { + if(thingType.m_dimensions[ThingType::Width] <= 1 && thingType.m_dimensions[ThingType::Height] <= 1) + value = 32; + else + value = std::min((int)fin->getU8(), std::max(thingType.m_dimensions[ThingType::Width] * 32, thingType.m_dimensions[ThingType::Height] * 32)); + } else { + value = fin->getU8(); + if(value == 0) + return false; + totalSprites *= value; } - thingType.m_dimensions[i] = fin->getU8(); - - if(i != ThingType::ExactSize) - totalSprites *= thingType.m_dimensions[i]; + thingType.m_dimensions[i] = value; } + if(totalSprites > 4096) + return false; + thingType.m_spritesIndex.resize(totalSprites); thingType.m_sprites.resize(totalSprites); for(int i = 0; i < totalSprites; i++) thingType.m_spritesIndex[i] = fin->getU16(); + + return true; } ThingType *ThingsType::getThingType(uint16 id, Categories category) diff --git a/src/otclient/core/thingstype.h b/src/otclient/core/thingstype.h index 7186e1d1..e459b7e9 100644 --- a/src/otclient/core/thingstype.h +++ b/src/otclient/core/thingstype.h @@ -42,7 +42,7 @@ public: bool load(const std::string& file); void unload(); - void parseThingType(const FileStreamPtr& fin, ThingType& thingType); + bool parseThingType(const FileStreamPtr& fin, ThingType& thingType); ThingType *getEmptyThingType() { return &m_emptyThingType; } ThingType *getThingType(uint16 id, Categories category); diff --git a/src/otclient/ui/uiitem.cpp b/src/otclient/ui/uiitem.cpp index df553148..ce636a0d 100644 --- a/src/otclient/ui/uiitem.cpp +++ b/src/otclient/ui/uiitem.cpp @@ -37,7 +37,12 @@ void UIItem::drawSelf() if(m_item) { Rect drawRect = getClippingRect(); Point dest = drawRect.topLeft(); - float scaleFactor = std::min(drawRect.width() / (float)m_item->getExactSize(), drawRect.height() / (float)m_item->getExactSize()); + + int exactSize = m_item->getExactSize(); + if(exactSize == 0) + return; + + float scaleFactor = std::min(drawRect.width() / (float)exactSize, drawRect.height() / (float)exactSize); dest += m_item->getDisplacement() * scaleFactor; g_painter->setColor(Color::white);