Merge remote-tracking branch 'origin/for_alayan'

This commit is contained in:
Benau 2019-01-26 16:18:47 +08:00
commit e869fbfd9e
20 changed files with 237 additions and 57 deletions

View File

@ -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();

View File

@ -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

View File

@ -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();

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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();
}
}

View File

@ -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;
}

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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)