Allow server AI starting in a same process with client
This commit is contained in:
parent
92a11c075a
commit
e0f494abcd
@ -36,7 +36,9 @@ NetworkAIController::NetworkAIController(AbstractKart *kart,
|
|||||||
{
|
{
|
||||||
m_ai_controller = ai;
|
m_ai_controller = ai;
|
||||||
m_ai_controls = new KartControl;
|
m_ai_controls = new KartControl;
|
||||||
Camera::createCamera(kart, local_player_id);
|
// We only need camera for real AI instance for debugging view
|
||||||
|
if (NetworkConfig::get()->isNetworkAIInstance())
|
||||||
|
Camera::createCamera(kart, local_player_id);
|
||||||
ai->setControls(m_ai_controls);
|
ai->setControls(m_ai_controls);
|
||||||
} // NetworkAIController
|
} // NetworkAIController
|
||||||
|
|
||||||
@ -47,6 +49,12 @@ NetworkAIController::~NetworkAIController()
|
|||||||
delete m_ai_controls;
|
delete m_ai_controls;
|
||||||
} // ~NetworkAIController
|
} // ~NetworkAIController
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
bool NetworkAIController::isLocalPlayerController() const
|
||||||
|
{
|
||||||
|
return NetworkConfig::get()->isNetworkAIInstance();
|
||||||
|
} // isLocalPlayerController
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
void NetworkAIController::update(int ticks)
|
void NetworkAIController::update(int ticks)
|
||||||
{
|
{
|
||||||
|
@ -38,6 +38,9 @@ public:
|
|||||||
virtual ~NetworkAIController();
|
virtual ~NetworkAIController();
|
||||||
virtual void update(int ticks) OVERRIDE;
|
virtual void update(int ticks) OVERRIDE;
|
||||||
virtual void reset() OVERRIDE;
|
virtual void reset() OVERRIDE;
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
virtual bool isLocalPlayerController() const OVERRIDE;
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
static void setAIFrequency(int freq) { m_ai_frequency = freq; }
|
static void setAIFrequency(int freq) { m_ai_frequency = freq; }
|
||||||
}; // class NetworkAIController
|
}; // class NetworkAIController
|
||||||
|
|
||||||
|
21
src/main.cpp
21
src/main.cpp
@ -1355,11 +1355,7 @@ int handleCmdLine(bool has_server_config, bool has_parent_process)
|
|||||||
|
|
||||||
int ai_num = 0;
|
int ai_num = 0;
|
||||||
if (CommandLine::has("--server-ai", &ai_num))
|
if (CommandLine::has("--server-ai", &ai_num))
|
||||||
{
|
NetworkConfig::get()->setNumFixedAI(ai_num);
|
||||||
Log::info("main", "Add %d server ai(s) server configurable will be "
|
|
||||||
"disabled.", ai_num);
|
|
||||||
ServerConfig::m_server_configurable = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string addr;
|
std::string addr;
|
||||||
bool has_addr = CommandLine::has("--connect-now", &addr);
|
bool has_addr = CommandLine::has("--connect-now", &addr);
|
||||||
@ -1444,21 +1440,6 @@ int handleCmdLine(bool has_server_config, bool has_parent_process)
|
|||||||
Log::info("main", "Creating a LAN server '%s'.",
|
Log::info("main", "Creating a LAN server '%s'.",
|
||||||
server_name.c_str());
|
server_name.c_str());
|
||||||
}
|
}
|
||||||
if (ai_num > 0)
|
|
||||||
{
|
|
||||||
std::string cmd =
|
|
||||||
std::string("--stdout=server_ai.log --no-graphics"
|
|
||||||
" --network-ai-freq=10 --connect-now=127.0.0.1:") +
|
|
||||||
StringUtils::toString(STKHost::get()->getPrivatePort()) +
|
|
||||||
" --no-console-log --disable-polling --network-ai="
|
|
||||||
+ StringUtils::toString(ai_num);
|
|
||||||
if (!server_password.empty())
|
|
||||||
cmd += " --server-password=" + server_password;
|
|
||||||
STKHost::get()->setSeparateProcess(
|
|
||||||
new SeparateProcess(
|
|
||||||
SeparateProcess::getCurrentExecutableLocation(), cmd,
|
|
||||||
false/*create_pipe*/, "childprocess_ai"/*childprocess_name*/));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CommandLine::has("--auto-connect"))
|
if (CommandLine::has("--auto-connect"))
|
||||||
|
@ -35,6 +35,7 @@
|
|||||||
#include "network/network_player_profile.hpp"
|
#include "network/network_player_profile.hpp"
|
||||||
#include "network/network_string.hpp"
|
#include "network/network_string.hpp"
|
||||||
#include "network/protocols/game_events_protocol.hpp"
|
#include "network/protocols/game_events_protocol.hpp"
|
||||||
|
#include "network/protocols/server_lobby.hpp"
|
||||||
#include "network/server_config.hpp"
|
#include "network/server_config.hpp"
|
||||||
#include "network/stk_host.hpp"
|
#include "network/stk_host.hpp"
|
||||||
#include "network/stk_peer.hpp"
|
#include "network/stk_peer.hpp"
|
||||||
@ -172,7 +173,8 @@ void LinearWorld::reset(bool restart)
|
|||||||
*/
|
*/
|
||||||
void LinearWorld::update(int ticks)
|
void LinearWorld::update(int ticks)
|
||||||
{
|
{
|
||||||
if (NetworkConfig::get()->isServer() && getPhase() == RACE_PHASE)
|
auto sl = LobbyProtocol::get<ServerLobby>();
|
||||||
|
if (sl && getPhase() == RACE_PHASE)
|
||||||
{
|
{
|
||||||
bool all_players_finished = true;
|
bool all_players_finished = true;
|
||||||
bool has_ai = false;
|
bool has_ai = false;
|
||||||
@ -185,7 +187,7 @@ void LinearWorld::update(int ticks)
|
|||||||
if (npp)
|
if (npp)
|
||||||
{
|
{
|
||||||
auto peer = npp->getPeer();
|
auto peer = npp->getPeer();
|
||||||
if (peer && peer->isAIPeer())
|
if ((peer && peer->isAIPeer()) || sl->isAIProfile(npp))
|
||||||
has_ai = true;
|
has_ai = true;
|
||||||
else if (!getKart(i)->hasFinishedRace())
|
else if (!getKart(i)->hasFinishedRace())
|
||||||
all_players_finished = false;
|
all_players_finished = false;
|
||||||
|
@ -468,7 +468,16 @@ std::shared_ptr<AbstractKart> World::createKart
|
|||||||
{
|
{
|
||||||
case RaceManager::KT_PLAYER:
|
case RaceManager::KT_PLAYER:
|
||||||
{
|
{
|
||||||
if (NetworkConfig::get()->isNetworkAIInstance())
|
int local_player_count = -1;
|
||||||
|
if (NetworkConfig::get()->isClient())
|
||||||
|
{
|
||||||
|
local_player_count =
|
||||||
|
(int)NetworkConfig::get()->getNetworkPlayers().size();
|
||||||
|
}
|
||||||
|
// local_player_id >= local_player_count for fixed AI defined in create
|
||||||
|
// server screen
|
||||||
|
if (NetworkConfig::get()->isNetworkAIInstance() ||
|
||||||
|
local_player_id >= local_player_count)
|
||||||
{
|
{
|
||||||
AIBaseController* ai = NULL;
|
AIBaseController* ai = NULL;
|
||||||
if (race_manager->isBattleMode())
|
if (race_manager->isBattleMode())
|
||||||
@ -495,8 +504,6 @@ std::shared_ptr<AbstractKart> World::createKart
|
|||||||
case RaceManager::KT_NETWORK_PLAYER:
|
case RaceManager::KT_NETWORK_PLAYER:
|
||||||
{
|
{
|
||||||
controller = new NetworkPlayerController(new_kart.get());
|
controller = new NetworkPlayerController(new_kart.get());
|
||||||
if (!online_name.empty())
|
|
||||||
new_kart->setOnScreenText(online_name.c_str());
|
|
||||||
m_num_players++;
|
m_num_players++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -511,6 +518,8 @@ std::shared_ptr<AbstractKart> World::createKart
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!controller->isLocalPlayerController() && !online_name.empty())
|
||||||
|
new_kart->setOnScreenText(online_name.c_str());
|
||||||
new_kart->setController(controller);
|
new_kart->setController(controller);
|
||||||
race_manager->setKartColor(index, ri->getHue());
|
race_manager->setKartColor(index, ri->getHue());
|
||||||
return new_kart;
|
return new_kart;
|
||||||
|
@ -73,6 +73,7 @@ NetworkConfig::NetworkConfig()
|
|||||||
m_network_ai_instance = false;
|
m_network_ai_instance = false;
|
||||||
m_state_frequency = 10;
|
m_state_frequency = 10;
|
||||||
m_nat64_prefix_data.fill(-1);
|
m_nat64_prefix_data.fill(-1);
|
||||||
|
m_num_fixed_ai = 0;
|
||||||
} // NetworkConfig
|
} // NetworkConfig
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
@ -85,6 +85,11 @@ private:
|
|||||||
* AI. (usually used together with ai-handling in server config) */
|
* AI. (usually used together with ai-handling in server config) */
|
||||||
bool m_network_ai_instance;
|
bool m_network_ai_instance;
|
||||||
|
|
||||||
|
/** No. of fixed AI in all-in-one graphical client server, the player
|
||||||
|
* connecting with 127.* or ::1/128 will be in charged of controlling the
|
||||||
|
* AI. */
|
||||||
|
unsigned m_num_fixed_ai;
|
||||||
|
|
||||||
/** The LAN port on which a client is waiting for a server connection. */
|
/** The LAN port on which a client is waiting for a server connection. */
|
||||||
uint16_t m_client_port;
|
uint16_t m_client_port;
|
||||||
|
|
||||||
@ -273,6 +278,10 @@ public:
|
|||||||
{ return m_nat64_prefix_data; }
|
{ return m_nat64_prefix_data; }
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
void initClientPort();
|
void initClientPort();
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
void setNumFixedAI(unsigned num) { m_num_fixed_ai = num; }
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
unsigned getNumFixedAI() const { return m_num_fixed_ai; }
|
||||||
}; // class NetworkConfig
|
}; // class NetworkConfig
|
||||||
|
|
||||||
#endif // HEADER_NETWORK_CONFIG
|
#endif // HEADER_NETWORK_CONFIG
|
||||||
|
@ -802,7 +802,8 @@ void ClientLobby::updatePlayerList(Event* event)
|
|||||||
lp.m_user_name = _("%s (handicapped)", lp.m_user_name);
|
lp.m_user_name = _("%s (handicapped)", lp.m_user_name);
|
||||||
}
|
}
|
||||||
lp.m_kart_team = (KartTeam)data.getUInt8();
|
lp.m_kart_team = (KartTeam)data.getUInt8();
|
||||||
if (lp.m_host_id == STKHost::get()->getMyHostId())
|
// No handicap for AI peer
|
||||||
|
if (!ai && lp.m_host_id == STKHost::get()->getMyHostId())
|
||||||
{
|
{
|
||||||
if (is_peer_server_owner)
|
if (is_peer_server_owner)
|
||||||
client_server_owner = true;
|
client_server_owner = true;
|
||||||
|
@ -50,6 +50,7 @@ struct LobbyPlayer
|
|||||||
std::string m_country_code;
|
std::string m_country_code;
|
||||||
/* Icon id for spectator in NetworkingLobby::loadedFromFile is 5. */
|
/* Icon id for spectator in NetworkingLobby::loadedFromFile is 5. */
|
||||||
bool isSpectator() const { return m_icon_id == 5; }
|
bool isSpectator() const { return m_icon_id == 5; }
|
||||||
|
bool isAI() const { return m_icon_id == 6; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class ClientLobby : public LobbyProtocol
|
class ClientLobby : public LobbyProtocol
|
||||||
|
@ -99,6 +99,12 @@ void LobbyProtocol::configRemoteKart(
|
|||||||
// Set number of global and local players.
|
// Set number of global and local players.
|
||||||
race_manager->setNumPlayers((int)players.size(), local_player_size);
|
race_manager->setNumPlayers((int)players.size(), local_player_size);
|
||||||
|
|
||||||
|
int local_player_count = -1;
|
||||||
|
if (NetworkConfig::get()->isClient())
|
||||||
|
{
|
||||||
|
local_player_count =
|
||||||
|
(int)NetworkConfig::get()->getNetworkPlayers().size();
|
||||||
|
}
|
||||||
// Create the kart information for the race manager:
|
// Create the kart information for the race manager:
|
||||||
// -------------------------------------------------
|
// -------------------------------------------------
|
||||||
for (unsigned int i = 0; i < players.size(); i++)
|
for (unsigned int i = 0; i < players.size(); i++)
|
||||||
@ -110,7 +116,10 @@ void LobbyProtocol::configRemoteKart(
|
|||||||
// on the server, and all non-local players on a client (the local
|
// on the server, and all non-local players on a client (the local
|
||||||
// karts are created in the ClientLobby).
|
// karts are created in the ClientLobby).
|
||||||
int local_player_id = profile->getLocalPlayerId();
|
int local_player_id = profile->getLocalPlayerId();
|
||||||
if (!is_local)
|
|
||||||
|
// local_player_id >= local_player_count for fixed AI defined in create
|
||||||
|
// server screen
|
||||||
|
if (!is_local || local_player_id >= local_player_count)
|
||||||
{
|
{
|
||||||
// No device or player profile is needed for remote kart.
|
// No device or player profile is needed for remote kart.
|
||||||
local_player_id =
|
local_player_id =
|
||||||
|
@ -57,6 +57,7 @@
|
|||||||
#include "utils/random_generator.hpp"
|
#include "utils/random_generator.hpp"
|
||||||
#include "utils/string_utils.hpp"
|
#include "utils/string_utils.hpp"
|
||||||
#include "utils/time.hpp"
|
#include "utils/time.hpp"
|
||||||
|
#include "utils/translation.hpp"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
@ -670,6 +671,8 @@ void ServerLobby::setup()
|
|||||||
for (auto player : ai->getPlayerProfiles())
|
for (auto player : ai->getPlayerProfiles())
|
||||||
player->setKartName("");
|
player->setKartName("");
|
||||||
}
|
}
|
||||||
|
for (auto ai : m_ai_profiles)
|
||||||
|
ai->setKartName("");
|
||||||
|
|
||||||
StateManager::get()->resetActivePlayers();
|
StateManager::get()->resetActivePlayers();
|
||||||
// We use maximum 16bit unsigned limit
|
// We use maximum 16bit unsigned limit
|
||||||
@ -1512,15 +1515,23 @@ void ServerLobby::asynchronousUpdate()
|
|||||||
ItemManager::updateRandomSeed(m_item_seed);
|
ItemManager::updateRandomSeed(m_item_seed);
|
||||||
m_game_setup->setRace(winner_vote);
|
m_game_setup->setRace(winner_vote);
|
||||||
auto players = STKHost::get()->getPlayersForNewGame();
|
auto players = STKHost::get()->getPlayersForNewGame();
|
||||||
auto ai = m_ai_peer.lock();
|
auto ai_instance = m_ai_peer.lock();
|
||||||
if (supportsAI() && ai)
|
if (supportsAI())
|
||||||
{
|
{
|
||||||
auto ai_profiles = ai->getPlayerProfiles();
|
if (ai_instance)
|
||||||
if (m_ai_count > 0)
|
|
||||||
{
|
{
|
||||||
ai_profiles.resize(m_ai_count);
|
auto ai_profiles = ai_instance->getPlayerProfiles();
|
||||||
players.insert(players.end(), ai_profiles.begin(),
|
if (m_ai_count > 0)
|
||||||
ai_profiles.end());
|
{
|
||||||
|
ai_profiles.resize(m_ai_count);
|
||||||
|
players.insert(players.end(), ai_profiles.begin(),
|
||||||
|
ai_profiles.end());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!m_ai_profiles.empty())
|
||||||
|
{
|
||||||
|
players.insert(players.end(), m_ai_profiles.begin(),
|
||||||
|
m_ai_profiles.end());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_game_setup->sortPlayersForGrandPrix(players);
|
m_game_setup->sortPlayersForGrandPrix(players);
|
||||||
@ -3303,7 +3314,7 @@ void ServerLobby::connectionRequested(Event* event)
|
|||||||
|
|
||||||
unsigned total_players = 0;
|
unsigned total_players = 0;
|
||||||
STKHost::get()->updatePlayers(NULL, NULL, &total_players);
|
STKHost::get()->updatePlayers(NULL, NULL, &total_players);
|
||||||
if (total_players + player_count >
|
if (total_players + player_count + m_ai_profiles.size() >
|
||||||
(unsigned)ServerConfig::m_server_max_players)
|
(unsigned)ServerConfig::m_server_max_players)
|
||||||
{
|
{
|
||||||
NetworkString *message = getNetworkString(2);
|
NetworkString *message = getNetworkString(2);
|
||||||
@ -3506,6 +3517,29 @@ void ServerLobby::handleUnencryptedConnection(std::shared_ptr<STKPeer> peer,
|
|||||||
.addUInt8(m_player_reports_table_exists ? 1 : 0);
|
.addUInt8(m_player_reports_table_exists ? 1 : 0);
|
||||||
|
|
||||||
peer->setSpectator(false);
|
peer->setSpectator(false);
|
||||||
|
|
||||||
|
// The 127.* or ::1/128 will be in charged for controlling AI
|
||||||
|
if (m_ai_profiles.empty() && peer->getAddress().isLoopback())
|
||||||
|
{
|
||||||
|
unsigned ai_add = NetworkConfig::get()->getNumFixedAI();
|
||||||
|
// We need to reserve at least 1 slot for new player
|
||||||
|
if (player_count + ai_add + 1 > ServerConfig::m_server_max_players)
|
||||||
|
ai_add = ServerConfig::m_server_max_players - player_count - 1;
|
||||||
|
for (unsigned i = 0; i < ai_add; i++)
|
||||||
|
{
|
||||||
|
#ifdef SERVER_ONLY
|
||||||
|
core::stringw name = L"Bot";
|
||||||
|
#else
|
||||||
|
core::stringw name = _("Bot");
|
||||||
|
#endif
|
||||||
|
if (i > 0)
|
||||||
|
name += core::stringw(" ") + StringUtils::toWString(i);
|
||||||
|
m_ai_profiles.insert(std::make_shared<NetworkPlayerProfile>
|
||||||
|
(peer, name, peer->getHostId(), 0.0f, 0, HANDICAP_NONE,
|
||||||
|
player_count + i, KART_TEAM_NONE, ""));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (game_started)
|
if (game_started)
|
||||||
{
|
{
|
||||||
peer->setWaitingForGame(true);
|
peer->setWaitingForGame(true);
|
||||||
@ -3538,6 +3572,7 @@ void ServerLobby::handleUnencryptedConnection(std::shared_ptr<STKPeer> peer,
|
|||||||
getRankingForPlayer(peer->getPlayerProfiles()[0]);
|
getRankingForPlayer(peer->getPlayerProfiles()[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ENABLE_SQLITE3
|
#ifdef ENABLE_SQLITE3
|
||||||
if (m_server_stats_table.empty() || peer->isAIPeer())
|
if (m_server_stats_table.empty() || peer->isAIPeer())
|
||||||
return;
|
return;
|
||||||
@ -3624,28 +3659,36 @@ void ServerLobby::updatePlayerList(bool update_when_reset_server)
|
|||||||
|
|
||||||
auto all_profiles = STKHost::get()->getAllPlayerProfiles();
|
auto all_profiles = STKHost::get()->getAllPlayerProfiles();
|
||||||
// N - 1 AI
|
// N - 1 AI
|
||||||
auto ai = m_ai_peer.lock();
|
auto ai_instance = m_ai_peer.lock();
|
||||||
if (supportsAI() && ai)
|
if (supportsAI())
|
||||||
{
|
{
|
||||||
auto ai_profiles = ai->getPlayerProfiles();
|
if (ai_instance)
|
||||||
if (m_state.load() == WAITING_FOR_START_GAME ||
|
|
||||||
update_when_reset_server)
|
|
||||||
{
|
{
|
||||||
if (all_profiles.size() > ai_profiles.size())
|
auto ai_profiles = ai_instance->getPlayerProfiles();
|
||||||
ai_profiles.clear();
|
if (m_state.load() == WAITING_FOR_START_GAME ||
|
||||||
else if (!all_profiles.empty())
|
update_when_reset_server)
|
||||||
{
|
{
|
||||||
ai_profiles.resize(
|
if (all_profiles.size() > ai_profiles.size())
|
||||||
ai_profiles.size() - all_profiles.size() + 1);
|
ai_profiles.clear();
|
||||||
|
else if (!all_profiles.empty())
|
||||||
|
{
|
||||||
|
ai_profiles.resize(
|
||||||
|
ai_profiles.size() - all_profiles.size() + 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Use fixed number of AI calculated when started game
|
||||||
|
ai_profiles.resize(m_ai_count);
|
||||||
|
}
|
||||||
|
all_profiles.insert(all_profiles.end(), ai_profiles.begin(),
|
||||||
|
ai_profiles.end());
|
||||||
}
|
}
|
||||||
else
|
else if (!m_ai_profiles.empty())
|
||||||
{
|
{
|
||||||
// Use fixed number of AI calculated when started game
|
all_profiles.insert(all_profiles.end(), m_ai_profiles.begin(),
|
||||||
ai_profiles.resize(m_ai_count);
|
m_ai_profiles.end());
|
||||||
}
|
}
|
||||||
all_profiles.insert(all_profiles.end(), ai_profiles.begin(),
|
|
||||||
ai_profiles.end());
|
|
||||||
}
|
}
|
||||||
m_lobby_players.store((int)all_profiles.size());
|
m_lobby_players.store((int)all_profiles.size());
|
||||||
|
|
||||||
@ -3676,7 +3719,7 @@ void ServerLobby::updatePlayerList(bool update_when_reset_server)
|
|||||||
m_peers_ready.find(p) != m_peers_ready.end() &&
|
m_peers_ready.find(p) != m_peers_ready.end() &&
|
||||||
m_peers_ready.at(p))
|
m_peers_ready.at(p))
|
||||||
boolean_combine |= (1 << 3);
|
boolean_combine |= (1 << 3);
|
||||||
if (p && p->isAIPeer())
|
if ((p && p->isAIPeer()) || isAIProfile(profile))
|
||||||
boolean_combine |= (1 << 4);
|
boolean_combine |= (1 << 4);
|
||||||
pl->addUInt8(boolean_combine);
|
pl->addUInt8(boolean_combine);
|
||||||
pl->addUInt8(profile->getHandicap());
|
pl->addUInt8(profile->getHandicap());
|
||||||
|
@ -127,8 +127,14 @@ private:
|
|||||||
* (disconnected). */
|
* (disconnected). */
|
||||||
std::weak_ptr<STKPeer> m_server_owner;
|
std::weak_ptr<STKPeer> m_server_owner;
|
||||||
|
|
||||||
|
/** AI peer which holds the list of reserved AI for dedicated server. */
|
||||||
std::weak_ptr<STKPeer> m_ai_peer;
|
std::weak_ptr<STKPeer> m_ai_peer;
|
||||||
|
|
||||||
|
/** AI profiles for all-in-one graphical client server, this will be a
|
||||||
|
* fixed count thorough the live time of server, which its value is
|
||||||
|
* configured in NetworkConfig. */
|
||||||
|
std::set<std::shared_ptr<NetworkPlayerProfile> > m_ai_profiles;
|
||||||
|
|
||||||
std::atomic<uint32_t> m_server_owner_id;
|
std::atomic<uint32_t> m_server_owner_id;
|
||||||
|
|
||||||
/** Official karts and tracks available in server. */
|
/** Official karts and tracks available in server. */
|
||||||
@ -379,6 +385,8 @@ public:
|
|||||||
void saveIPBanTable(const SocketAddress& addr);
|
void saveIPBanTable(const SocketAddress& addr);
|
||||||
void listBanTable();
|
void listBanTable();
|
||||||
void initServerStatsTable();
|
void initServerStatsTable();
|
||||||
|
bool isAIProfile(const std::shared_ptr<NetworkPlayerProfile>& npp) const
|
||||||
|
{ return m_ai_profiles.find(npp) != m_ai_profiles.end(); }
|
||||||
}; // class ServerLobby
|
}; // class ServerLobby
|
||||||
|
|
||||||
#endif // SERVER_LOBBY_HPP
|
#endif // SERVER_LOBBY_HPP
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#include "audio/sfx_manager.hpp"
|
#include "audio/sfx_manager.hpp"
|
||||||
#include "config/player_manager.hpp"
|
#include "config/player_manager.hpp"
|
||||||
#include "config/user_config.hpp"
|
#include "config/user_config.hpp"
|
||||||
|
#include "karts/controller/network_ai_controller.hpp"
|
||||||
#include "network/network_config.hpp"
|
#include "network/network_config.hpp"
|
||||||
#include "network/server.hpp"
|
#include "network/server.hpp"
|
||||||
#include "network/server_config.hpp"
|
#include "network/server_config.hpp"
|
||||||
@ -391,7 +392,10 @@ void CreateServerScreen::createServer()
|
|||||||
if (m_supports_ai)
|
if (m_supports_ai)
|
||||||
{
|
{
|
||||||
if (esi > 0)
|
if (esi > 0)
|
||||||
|
{
|
||||||
server_cfg << " --server-ai=" << esi;
|
server_cfg << " --server-ai=" << esi;
|
||||||
|
NetworkAIController::setAIFrequency(10);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -632,15 +632,16 @@ void NetworkingLobby::eventCallback(Widget* widget, const std::string& name,
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
LobbyPlayer& lp =
|
||||||
|
m_player_names.at(m_player_list->getSelectionInternalName());
|
||||||
|
// For client server AI it doesn't make any sense to open the dialog
|
||||||
|
// There is no way to kick or add handicap to them
|
||||||
|
if (STKHost::get()->isClientServer() > 0 && lp.isAI())
|
||||||
|
return;
|
||||||
new NetworkPlayerDialog(host_online_local_ids[0],
|
new NetworkPlayerDialog(host_online_local_ids[0],
|
||||||
host_online_local_ids[1], host_online_local_ids[2],
|
host_online_local_ids[1], host_online_local_ids[2],
|
||||||
m_player_names.at(
|
lp.m_user_name, lp.m_country_code, m_allow_change_team,
|
||||||
m_player_list->getSelectionInternalName()).m_user_name,
|
lp.m_handicap);
|
||||||
m_player_names.at(
|
|
||||||
m_player_list->getSelectionInternalName()).m_country_code,
|
|
||||||
m_allow_change_team,
|
|
||||||
m_player_names.at(
|
|
||||||
m_player_list->getSelectionInternalName()).m_handicap);
|
|
||||||
} // click on a user
|
} // click on a user
|
||||||
else if (name == m_send_button->m_properties[PROP_ID])
|
else if (name == m_send_button->m_properties[PROP_ID])
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user