Merge remote-tracking branch 'origin/for_alayan'
This commit is contained in:
commit
e869fbfd9e
@ -426,8 +426,11 @@ void CGUISTKListBox::selectNew(s32 ypos, bool onlyHover)
|
||||
s32 oldSelected = Selected;
|
||||
|
||||
Selected = getItemAt(AbsoluteRect.UpperLeftCorner.X, ypos);
|
||||
if (Selected < 0 && !Items.empty())
|
||||
Selected = 0;
|
||||
if (Selected == -1 || Items.empty())
|
||||
{
|
||||
Selected = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
recalculateScrollPos();
|
||||
|
||||
|
@ -235,9 +235,18 @@ unsigned int ItemManager::insertItem(Item *item)
|
||||
m_all_items[index] = item;
|
||||
}
|
||||
item->setItemId(index);
|
||||
|
||||
insertItemInQuad(item);
|
||||
// Now insert into the appropriate quad list, if there is a quad list
|
||||
// (i.e. race mode has a quad graph).
|
||||
return index;
|
||||
} // insertItem
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Insert into the appropriate quad list, if there is a quad list
|
||||
* (i.e. race mode has a quad graph).
|
||||
*/
|
||||
void ItemManager::insertItemInQuad(Item *item)
|
||||
{
|
||||
if(m_items_in_quads)
|
||||
{
|
||||
int graph_node = item->getGraphNode();
|
||||
@ -249,8 +258,7 @@ unsigned int ItemManager::insertItem(Item *item)
|
||||
else // otherwise store it in the 'outside' index
|
||||
(*m_items_in_quads)[m_items_in_quads->size()-1].push_back(item);
|
||||
} // if m_items_in_quads
|
||||
return index;
|
||||
} // insertItem
|
||||
} // insertItemInQuad
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Creates a new item at the location of the kart (e.g. kart drops a
|
||||
@ -303,7 +311,10 @@ Item* ItemManager::dropNewItem(ItemState::ItemType type,
|
||||
|
||||
Item* item = new Item(type, pos, normal, m_item_mesh[mesh_type],
|
||||
m_item_lowres_mesh[mesh_type], /*prev_owner*/kart);
|
||||
insertItem(item);
|
||||
|
||||
// restoreState in NetworkItemManager will handle the insert item
|
||||
if (!server_xyz)
|
||||
insertItem(item);
|
||||
if(m_switch_ticks>=0)
|
||||
{
|
||||
ItemState::ItemType new_type = m_switch_to[item->getType()];
|
||||
@ -522,6 +533,18 @@ void ItemManager::updateGraphics(float dt)
|
||||
void ItemManager::deleteItem(ItemState *item)
|
||||
{
|
||||
// First check if the item needs to be removed from the items-in-quad list
|
||||
deleteItemInQuad(item);
|
||||
int index = item->getItemId();
|
||||
m_all_items[index] = NULL;
|
||||
delete item;
|
||||
} // delete item
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Removes an items from the items-in-quad list only
|
||||
* \param The item to delete.
|
||||
*/
|
||||
void ItemManager::deleteItemInQuad(ItemState* item)
|
||||
{
|
||||
if(m_items_in_quads)
|
||||
{
|
||||
int sector = item->getGraphNode();
|
||||
@ -533,11 +556,7 @@ void ItemManager::deleteItem(ItemState *item)
|
||||
assert(it!=items.end());
|
||||
items.erase(it);
|
||||
} // if m_items_in_quads
|
||||
|
||||
int index = item->getItemId();
|
||||
m_all_items[index] = NULL;
|
||||
delete item;
|
||||
} // delete item
|
||||
} // deleteItemInQuad
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Switches all items: boxes become bananas and vice versa for a certain
|
||||
|
@ -125,7 +125,8 @@ protected:
|
||||
virtual unsigned int insertItem(Item *item);
|
||||
void switchItemsInternal(std::vector < ItemState*> &all_items);
|
||||
void setSwitchItems(const std::vector<int> &switch_items);
|
||||
|
||||
void insertItemInQuad(Item *item);
|
||||
void deleteItemInQuad(ItemState *item);
|
||||
ItemManager();
|
||||
public:
|
||||
virtual ~ItemManager();
|
||||
|
@ -492,12 +492,15 @@ void NetworkItemManager::restoreState(BareNetworkString *buffer, int count)
|
||||
// the client, but not yet confirmed). So
|
||||
unsigned int max_index = std::max(m_confirmed_state.size(),
|
||||
m_all_items.size() );
|
||||
m_all_items.resize(max_index, NULL);
|
||||
|
||||
for(unsigned int i=0; i<max_index; i++)
|
||||
{
|
||||
ItemState *item = i < m_all_items.size() ? m_all_items[i] : NULL;
|
||||
ItemState *item = m_all_items[i];
|
||||
const ItemState *is = i < m_confirmed_state.size()
|
||||
? m_confirmed_state[i] : NULL;
|
||||
// For every *(ItemState*)item = *is, all deactivated ticks, item id
|
||||
// ... will be copied from item state to item
|
||||
if (is && item)
|
||||
{
|
||||
*(ItemState*)item = *is;
|
||||
@ -510,31 +513,19 @@ void NetworkItemManager::restoreState(BareNetworkString *buffer, int count)
|
||||
Vec3 normal = is->getNormal();
|
||||
Item *item_new = dropNewItem(is->getType(), is->getPreviousOwner(),
|
||||
&xyz, &normal );
|
||||
if (i != item_new->getItemId())
|
||||
{
|
||||
// The newly created item on the client has been given a
|
||||
// different index than the one given by the server. This
|
||||
// indicates that this client has either a different item
|
||||
// at the index that the server sent (i.e. client predicted
|
||||
// an item, which the server has not confirmed), or the
|
||||
// client found an empty slot that the server did not have
|
||||
// (so an earlier index was found).
|
||||
if(i < m_all_items.size() && m_all_items[i])
|
||||
deleteItem(m_all_items[i]);
|
||||
// Move item_new from its position to the index given
|
||||
// by the server
|
||||
m_all_items[item_new->getItemId()] = NULL;
|
||||
m_all_items[i] = item_new;
|
||||
item_new->setItemId(i);
|
||||
}
|
||||
item_new->setDeactivatedTicks(is->getDeactivatedTicks());
|
||||
*((ItemState*)m_all_items[i]) = *is;
|
||||
*((ItemState*)item_new) = *is;
|
||||
m_all_items[i] = item_new;
|
||||
insertItemInQuad(item_new);
|
||||
}
|
||||
else if (!is && item)
|
||||
{
|
||||
deleteItem(m_all_items[i]);
|
||||
deleteItemInQuad(item);
|
||||
delete item;
|
||||
m_all_items[i] = NULL;
|
||||
}
|
||||
} // for i < max_index
|
||||
// Clean up the rest
|
||||
m_all_items.resize(m_confirmed_state.size());
|
||||
|
||||
// Now set the clock back to the 'rewindto' time:
|
||||
world->setTicksForRewind(rewind_to_time);
|
||||
|
@ -33,7 +33,9 @@
|
||||
#include "physics/physics.hpp"
|
||||
#include "network/network_config.hpp"
|
||||
#include "network/network_string.hpp"
|
||||
#include "network/protocols/game_events_protocol.hpp"
|
||||
#include "network/server_config.hpp"
|
||||
#include "network/stk_host.hpp"
|
||||
#include "race/history.hpp"
|
||||
#include "states_screens/race_gui_base.hpp"
|
||||
#include "tracks/check_manager.hpp"
|
||||
@ -1156,3 +1158,66 @@ void LinearWorld::restoreCompleteState(const BareNetworkString& b)
|
||||
for (unsigned i = 0; i < cc; i++)
|
||||
CheckManager::get()->getCheckStructure(i)->restoreCompleteState(b);
|
||||
} // restoreCompleteState
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Called in server whenever a kart cross a check line, it send server
|
||||
* all karts lap count, last triggered checkline and check structure status
|
||||
* to all players in game (including spectators so that the lap count is
|
||||
* correct)
|
||||
*/
|
||||
void LinearWorld::updateCheckLinesServer()
|
||||
{
|
||||
if (!NetworkConfig::get()->isNetworking() ||
|
||||
NetworkConfig::get()->isClient())
|
||||
return;
|
||||
|
||||
NetworkString cl(PROTOCOL_GAME_EVENTS);
|
||||
cl.setSynchronous(true);
|
||||
cl.addUInt8(GameEventsProtocol::GE_CHECK_LINE);
|
||||
|
||||
for (KartInfo& ki : m_kart_info)
|
||||
{
|
||||
int8_t finished_laps = (int8_t)ki.m_finished_laps;
|
||||
cl.addUInt8(finished_laps);
|
||||
}
|
||||
|
||||
for (TrackSector* ts : m_kart_track_sector)
|
||||
{
|
||||
int8_t ltcl = (int8_t)ts->getLastTriggeredCheckline();
|
||||
cl.addUInt8(ltcl);
|
||||
}
|
||||
|
||||
const uint8_t cc = (uint8_t)CheckManager::get()->getCheckStructureCount();
|
||||
cl.addUInt8(cc);
|
||||
for (unsigned i = 0; i < cc; i++)
|
||||
CheckManager::get()->getCheckStructure(i)->saveIsActive(&cl);
|
||||
|
||||
STKHost::get()->sendPacketToAllPeers(&cl, true);
|
||||
} // updateCheckLinesServer
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/* Synchronize with server from the above data. */
|
||||
void LinearWorld::updateCheckLinesClient(const BareNetworkString& b)
|
||||
{
|
||||
for (KartInfo& ki : m_kart_info)
|
||||
{
|
||||
int8_t finished_laps = b.getUInt8();
|
||||
ki.m_finished_laps = finished_laps;
|
||||
}
|
||||
|
||||
for (TrackSector* ts : m_kart_track_sector)
|
||||
{
|
||||
int8_t ltcl = b.getUInt8();
|
||||
ts->setLastTriggeredCheckline(ltcl);
|
||||
}
|
||||
|
||||
const unsigned cc = b.getUInt8();
|
||||
if (cc != CheckManager::get()->getCheckStructureCount())
|
||||
{
|
||||
throw std::invalid_argument(
|
||||
"Server has different check structures size.");
|
||||
}
|
||||
for (unsigned i = 0; i < cc; i++)
|
||||
CheckManager::get()->getCheckStructure(i)->restoreIsActive(b);
|
||||
|
||||
} // updateCheckLinesClient
|
||||
|
@ -220,6 +220,10 @@ public:
|
||||
virtual void saveCompleteState(BareNetworkString* bns) OVERRIDE;
|
||||
// ------------------------------------------------------------------------
|
||||
virtual void restoreCompleteState(const BareNetworkString& b) OVERRIDE;
|
||||
// ------------------------------------------------------------------------
|
||||
void updateCheckLinesServer();
|
||||
// ------------------------------------------------------------------------
|
||||
void updateCheckLinesClient(const BareNetworkString& b);
|
||||
}; // LinearWorld
|
||||
|
||||
#endif
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include "karts/abstract_kart.hpp"
|
||||
#include "karts/controller/player_controller.hpp"
|
||||
#include "modes/capture_the_flag.hpp"
|
||||
#include "modes/linear_world.hpp"
|
||||
#include "modes/soccer_world.hpp"
|
||||
#include "network/event.hpp"
|
||||
#include "network/game_setup.hpp"
|
||||
@ -52,6 +53,7 @@ bool GameEventsProtocol::notifyEvent(Event* event)
|
||||
CaptureTheFlag* ctf = dynamic_cast<CaptureTheFlag*>(World::getWorld());
|
||||
FreeForAll* ffa = dynamic_cast<FreeForAll*>(World::getWorld());
|
||||
SoccerWorld* sw = dynamic_cast<SoccerWorld*>(World::getWorld());
|
||||
LinearWorld* lw = dynamic_cast<LinearWorld*>(World::getWorld());
|
||||
switch (type)
|
||||
{
|
||||
case GE_KART_FINISHED_RACE:
|
||||
@ -126,6 +128,14 @@ bool GameEventsProtocol::notifyEvent(Event* event)
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GE_CHECK_LINE:
|
||||
{
|
||||
if (!lw)
|
||||
throw std::invalid_argument("No linear world");
|
||||
if (NetworkConfig::get()->isClient())
|
||||
lw->updateCheckLinesClient(data);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
Log::warn("GameEventsProtocol", "Unkown message type.");
|
||||
break;
|
||||
|
@ -17,6 +17,7 @@ public:
|
||||
GE_CTF_SCORED = 4,
|
||||
GE_RESET_BALL = 5,
|
||||
GE_PLAYER_GOAL = 6,
|
||||
GE_CHECK_LINE = 7
|
||||
}; // GameEventType
|
||||
private:
|
||||
int m_last_finished_position;
|
||||
|
@ -982,7 +982,7 @@ void ServerLobby::update(int ticks)
|
||||
{
|
||||
for (unsigned i = 0; i < race_manager->getNumPlayers(); i++)
|
||||
{
|
||||
const RemoteKartInfo& rki = race_manager->getKartInfo(i);
|
||||
RemoteKartInfo& rki = race_manager->getKartInfo(i);
|
||||
std::shared_ptr<NetworkPlayerProfile> player =
|
||||
rki.getNetworkPlayerProfile().lock();
|
||||
if (player)
|
||||
@ -1003,7 +1003,6 @@ void ServerLobby::update(int ticks)
|
||||
Log::info("ServerLobby", "%s hasn't live-joined within"
|
||||
" 60 seconds, remove it.",
|
||||
peer->getAddress().toString().c_str());
|
||||
RemoteKartInfo& rki = race_manager->getKartInfo(i);
|
||||
rki.makeReserved();
|
||||
continue;
|
||||
}
|
||||
@ -1012,9 +1011,10 @@ void ServerLobby::update(int ticks)
|
||||
{
|
||||
if (w && w->getKart(i)->hasFinishedRace())
|
||||
continue;
|
||||
Log::info("ServerLobby", "%s has been idle for more than"
|
||||
Log::info("ServerLobby", "%s %s has been idle for more than"
|
||||
" %d seconds, kick.",
|
||||
peer->getAddress().toString().c_str(), sec);
|
||||
peer->getAddress().toString().c_str(),
|
||||
StringUtils::wideToUtf8(rki.getPlayerName()).c_str(), sec);
|
||||
peer->kick();
|
||||
}
|
||||
}
|
||||
|
@ -64,8 +64,7 @@ void ServersManager::deallocate()
|
||||
// ----------------------------------------------------------------------------
|
||||
ServersManager::ServersManager()
|
||||
{
|
||||
m_last_load_time.store(0);
|
||||
m_list_updated = false;
|
||||
reset();
|
||||
} // ServersManager
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -237,6 +236,7 @@ void ServersManager::setLanServers(const std::map<irr::core::stringw,
|
||||
{
|
||||
m_servers.clear();
|
||||
for (auto i : servers) m_servers.emplace_back(i.second);
|
||||
m_last_load_time.store(StkTime::getRealTimeMs());
|
||||
m_list_updated = true;
|
||||
|
||||
}
|
||||
|
@ -81,6 +81,11 @@ public:
|
||||
bool listUpdated() const { return m_list_updated; }
|
||||
// ------------------------------------------------------------------------
|
||||
const std::vector<TransportAddress>& getBroadcastAddresses();
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
void reset()
|
||||
{
|
||||
m_last_load_time.store(0);
|
||||
m_list_updated = false;
|
||||
}
|
||||
}; // class ServersManager
|
||||
#endif // HEADER_SERVERS_MANAGER_HPP
|
||||
|
@ -774,13 +774,22 @@ void STKHost::mainLoop()
|
||||
if (p.second->isValidated() &&
|
||||
p.second->getConnectedTime() > 5.0f && ap > max_ping)
|
||||
{
|
||||
if (ServerConfig::m_kick_high_ping_players &&
|
||||
!p.second->isDisconnected())
|
||||
std::string player_name;
|
||||
if (!p.second->getPlayerProfiles().empty())
|
||||
{
|
||||
Log::info("STKHost", "%s with ping %d is higher"
|
||||
" than %d ms, kick.",
|
||||
player_name = StringUtils::wideToUtf8
|
||||
(p.second->getPlayerProfiles()[0]->getName());
|
||||
}
|
||||
const bool peer_not_in_game =
|
||||
sl->getCurrentState() <= ServerLobby::SELECTING
|
||||
|| p.second->isWaitingForGame();
|
||||
if (ServerConfig::m_kick_high_ping_players &&
|
||||
!p.second->isDisconnected() && peer_not_in_game)
|
||||
{
|
||||
Log::info("STKHost", "%s %s with ping %d is higher"
|
||||
" than %d ms when not in game, kick.",
|
||||
p.second->getAddress().toString().c_str(),
|
||||
ap, max_ping);
|
||||
player_name.c_str(), ap, max_ping);
|
||||
p.second->setWarnedForHighPing(true);
|
||||
p.second->setDisconnected(true);
|
||||
std::lock_guard<std::mutex> lock(m_enet_cmd_mutex);
|
||||
@ -790,10 +799,10 @@ void STKHost::mainLoop()
|
||||
}
|
||||
else if (!p.second->hasWarnedForHighPing())
|
||||
{
|
||||
Log::info("STKHost", "%s with ping %d is higher"
|
||||
Log::info("STKHost", "%s %s with ping %d is higher"
|
||||
" than %d ms.",
|
||||
p.second->getAddress().toString().c_str(),
|
||||
ap, max_ping);
|
||||
player_name.c_str(), ap, max_ping);
|
||||
p.second->setWarnedForHighPing(true);
|
||||
NetworkString msg(PROTOCOL_LOBBY_ROOM);
|
||||
msg.setSynchronous(true);
|
||||
|
@ -165,6 +165,7 @@ void ServerSelection::init()
|
||||
m_server_list_widget->setIcons(m_icon_bank, row_height);
|
||||
m_sort_desc = false;
|
||||
/** Triggers the loading of the server list in the servers manager. */
|
||||
ServersManager::get()->reset();
|
||||
refresh(true);
|
||||
} // init
|
||||
|
||||
|
@ -20,6 +20,7 @@
|
||||
#define HEADER_CHECK_LAP_HPP
|
||||
|
||||
#include "tracks/check_structure.hpp"
|
||||
#include "utils/cpp2011.hpp"
|
||||
|
||||
class XMLNode;
|
||||
class CheckManager;
|
||||
@ -40,8 +41,9 @@ public:
|
||||
CheckLap(const XMLNode &node, unsigned int index);
|
||||
virtual ~CheckLap() {};
|
||||
virtual bool isTriggered(const Vec3 &old_pos, const Vec3 &new_pos,
|
||||
int indx);
|
||||
virtual void reset(const Track &track);
|
||||
int indx) OVERRIDE;
|
||||
virtual void reset(const Track &track) OVERRIDE;
|
||||
virtual bool triggeringCheckline() const OVERRIDE { return true; }
|
||||
}; // CheckLine
|
||||
|
||||
#endif
|
||||
|
@ -26,6 +26,7 @@
|
||||
using namespace irr;
|
||||
|
||||
#include "tracks/check_structure.hpp"
|
||||
#include "utils/cpp2011.hpp"
|
||||
|
||||
class XMLNode;
|
||||
class CheckManager;
|
||||
@ -88,11 +89,11 @@ public:
|
||||
CheckLine(const XMLNode &node, unsigned int index);
|
||||
virtual ~CheckLine();
|
||||
virtual bool isTriggered(const Vec3 &old_pos, const Vec3 &new_pos,
|
||||
int indx);
|
||||
virtual void reset(const Track &track);
|
||||
virtual void resetAfterKartMove(unsigned int kart_index);
|
||||
virtual void changeDebugColor(bool is_active);
|
||||
virtual bool triggeringCheckline() const { return true; }
|
||||
int indx) OVERRIDE;
|
||||
virtual void reset(const Track &track) OVERRIDE;
|
||||
virtual void resetAfterKartMove(unsigned int kart_index) OVERRIDE;
|
||||
virtual void changeDebugColor(bool is_active) OVERRIDE;
|
||||
virtual bool triggeringCheckline() const OVERRIDE { return true; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the actual line data for this checkpoint. */
|
||||
const core::line2df &getLine2D() const {return m_line;}
|
||||
@ -102,9 +103,9 @@ public:
|
||||
* be too heigh to otherwise trigger he cannon). */
|
||||
void setIgnoreHeight(bool b) { m_ignore_height = b; }
|
||||
// ------------------------------------------------------------------------
|
||||
virtual void saveCompleteState(BareNetworkString* bns);
|
||||
virtual void saveCompleteState(BareNetworkString* bns) OVERRIDE;
|
||||
// ------------------------------------------------------------------------
|
||||
virtual void restoreCompleteState(const BareNetworkString& b);
|
||||
virtual void restoreCompleteState(const BareNetworkString& b) OVERRIDE;
|
||||
}; // CheckLine
|
||||
|
||||
#endif
|
||||
|
@ -101,6 +101,7 @@ void CheckStructure::reset(const Track &track)
|
||||
void CheckStructure::update(float dt)
|
||||
{
|
||||
World *world = World::getWorld();
|
||||
LinearWorld* lw = dynamic_cast<LinearWorld*>(World::getWorld());
|
||||
for(unsigned int i=0; i<world->getNumKarts(); i++)
|
||||
{
|
||||
const Vec3 &xyz = world->getKart(i)->getFrontXYZ();
|
||||
@ -114,6 +115,8 @@ void CheckStructure::update(float dt)
|
||||
m_index, world->getKart(i)->getIdent().c_str(),
|
||||
World::getWorld()->getTime());
|
||||
trigger(i);
|
||||
if (triggeringCheckline() && lw)
|
||||
lw->updateCheckLinesServer();
|
||||
}
|
||||
m_previous_position[i] = xyz;
|
||||
} // for i<getNumKarts
|
||||
@ -252,3 +255,23 @@ void CheckStructure::restoreCompleteState(const BareNetworkString& b)
|
||||
m_is_active.push_back(is_active);
|
||||
}
|
||||
} // restoreCompleteState
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void CheckStructure::saveIsActive(BareNetworkString* bns)
|
||||
{
|
||||
World* world = World::getWorld();
|
||||
for (unsigned int i = 0; i < world->getNumKarts(); i++)
|
||||
bns->addUInt8(m_is_active[i] ? 1 : 0);
|
||||
} // saveIsActive
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void CheckStructure::restoreIsActive(const BareNetworkString& b)
|
||||
{
|
||||
m_is_active.clear();
|
||||
World* world = World::getWorld();
|
||||
for (unsigned int i = 0; i < world->getNumKarts(); i++)
|
||||
{
|
||||
bool is_active = b.getUInt8() == 1;
|
||||
m_is_active.push_back(is_active);
|
||||
}
|
||||
} // restoreIsActive
|
||||
|
@ -131,9 +131,15 @@ public:
|
||||
m_check_structures_to_change_state.push_back(i);
|
||||
} // addSuccessor
|
||||
// ------------------------------------------------------------------------
|
||||
virtual bool triggeringCheckline() const { return false; }
|
||||
// ------------------------------------------------------------------------
|
||||
virtual void saveCompleteState(BareNetworkString* bns);
|
||||
// ------------------------------------------------------------------------
|
||||
virtual void restoreCompleteState(const BareNetworkString& b);
|
||||
// ------------------------------------------------------------------------
|
||||
void saveIsActive(BareNetworkString* bns);
|
||||
// ------------------------------------------------------------------------
|
||||
void restoreIsActive(const BareNetworkString& b);
|
||||
}; // CheckStructure
|
||||
|
||||
#endif
|
||||
|
@ -90,6 +90,9 @@ public:
|
||||
// ------------------------------------------------------------------------
|
||||
void setLastTriggeredCheckline(int i) { m_last_triggered_checkline = i; }
|
||||
// ------------------------------------------------------------------------
|
||||
int getLastTriggeredCheckline() const
|
||||
{ return m_last_triggered_checkline; }
|
||||
// ------------------------------------------------------------------------
|
||||
int getLastValidGraphNode() const { return m_last_valid_graph_node; }
|
||||
// ------------------------------------------------------------------------
|
||||
void saveState(BareNetworkString* buffer) const;
|
||||
|
@ -19,8 +19,10 @@
|
||||
#include "utils/log.hpp"
|
||||
|
||||
#include "config/user_config.hpp"
|
||||
#include "network/network_config.hpp"
|
||||
|
||||
#include <cstdio>
|
||||
#include <ctime>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef ANDROID
|
||||
@ -154,7 +156,21 @@ void Log::printMessage(int level, const char *component, const char *format,
|
||||
remaining = MAX_LENGTH - index > 0 ? MAX_LENGTH - index : 0;
|
||||
}
|
||||
|
||||
index += snprintf (line + index, remaining, "[%s] %s: ", names[level], component);
|
||||
#ifndef ANDROID
|
||||
if (NetworkConfig::get()->isNetworking() &&
|
||||
NetworkConfig::get()->isServer())
|
||||
{
|
||||
std::time_t result = std::time(nullptr);
|
||||
index += snprintf (line + index, remaining,
|
||||
"%.24s [%s] %s: ", std::asctime(std::localtime(&result)),
|
||||
names[level], component);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
index += snprintf (line + index, remaining,
|
||||
"[%s] %s: ", names[level], component);
|
||||
}
|
||||
remaining = MAX_LENGTH - index > 0 ? MAX_LENGTH - index : 0;
|
||||
index += vsnprintf(line + index, remaining, format, args);
|
||||
remaining = MAX_LENGTH - index > 0 ? MAX_LENGTH - index : 0;
|
||||
|
@ -1092,6 +1092,25 @@ namespace StringUtils
|
||||
|
||||
// Step 7
|
||||
push_text:
|
||||
|
||||
// Calculate break index depending on max text length if there is no
|
||||
// breakable character
|
||||
if (break_index == 0)
|
||||
{
|
||||
for (unsigned int i = 0; i < work_copy.size(); i++)
|
||||
{
|
||||
std::wstring text = work_copy.substr(0, i+1);
|
||||
unsigned int width = font->getDimension(text.c_str()).Width;
|
||||
|
||||
if (width > max_width)
|
||||
break;
|
||||
|
||||
break_index++;
|
||||
}
|
||||
|
||||
break_index = std::max(0, (int)break_index - 1);
|
||||
}
|
||||
|
||||
// To include the char at break_index, we need a length of break_index+1
|
||||
std::wstring text_line = work_copy.substr(0,break_index+1);
|
||||
output.push_back(text_line);
|
||||
@ -1106,6 +1125,7 @@ namespace StringUtils
|
||||
{
|
||||
work_copy = work_copy.substr(break_index+1); // All the string except the pushed back part
|
||||
index = 0;
|
||||
break_index = 0;
|
||||
}
|
||||
} // While(true) - active until the whole string has been broken and copied
|
||||
if (right_to_left)
|
||||
|
Loading…
Reference in New Issue
Block a user