Allow using AI in lan racing game
This commit is contained in:
parent
c801191d80
commit
a26f67bf16
21
src/main.cpp
21
src/main.cpp
@ -251,6 +251,7 @@
|
||||
#include "utils/log.hpp"
|
||||
#include "utils/mini_glm.hpp"
|
||||
#include "utils/profiler.hpp"
|
||||
#include "utils/separate_process.hpp"
|
||||
#include "utils/string_utils.hpp"
|
||||
#include "utils/translation.hpp"
|
||||
|
||||
@ -1326,6 +1327,14 @@ int handleCmdLine(bool has_server_config, bool has_parent_process)
|
||||
}
|
||||
}
|
||||
|
||||
int ai_num = 0;
|
||||
if (CommandLine::has("--server-ai", &ai_num))
|
||||
{
|
||||
Log::info("main", "Add %d server ai(s) server configurable will be "
|
||||
"disabled.", ai_num);
|
||||
ServerConfig::m_server_configurable = false;
|
||||
}
|
||||
|
||||
std::string ipv4;
|
||||
std::string ipv6;
|
||||
bool has_ipv4 = CommandLine::has("--connect-now", &ipv4);
|
||||
@ -1407,6 +1416,18 @@ int handleCmdLine(bool has_server_config, bool has_parent_process)
|
||||
Log::info("main", "Creating a LAN server '%s'.",
|
||||
server_name.c_str());
|
||||
}
|
||||
if (ai_num > 0)
|
||||
{
|
||||
STKHost::get()->setSeparateProcess(
|
||||
new SeparateProcess(
|
||||
SeparateProcess::getCurrentExecutableLocation(),
|
||||
std::string("--stdout=server_ai.log --no-graphics"
|
||||
" --auto-connect --connect-now=127.0.0.1:") +
|
||||
StringUtils::toString(STKHost::get()->getPrivatePort()) +
|
||||
" --no-console-log --network-ai="
|
||||
+ StringUtils::toString(ai_num), false/*create_pipe*/,
|
||||
"childprocess_ai"/*childprocess_name*/));
|
||||
}
|
||||
}
|
||||
|
||||
if (CommandLine::has("--auto-connect"))
|
||||
|
@ -361,10 +361,12 @@ void ClientLobby::update(int ticks)
|
||||
case LINKED:
|
||||
{
|
||||
NetworkConfig::get()->clearServerCapabilities();
|
||||
std::string ua = StringUtils::getUserAgentString();
|
||||
if (NetworkConfig::get()->isNetworkAITester())
|
||||
ua = "AI";
|
||||
NetworkString* ns = getNetworkString();
|
||||
ns->addUInt8(LE_CONNECTION_REQUESTED)
|
||||
.addUInt32(ServerConfig::m_server_version)
|
||||
.encodeString(StringUtils::getUserAgentString())
|
||||
.addUInt32(ServerConfig::m_server_version).encodeString(ua)
|
||||
.addUInt16((uint16_t)stk_config->m_network_capabilities.size());
|
||||
for (const std::string& cap : stk_config->m_network_capabilities)
|
||||
ns->encodeString(cap);
|
||||
@ -391,7 +393,10 @@ void ClientLobby::update(int ticks)
|
||||
|
||||
bool encryption = false;
|
||||
uint32_t id = PlayerManager::getCurrentOnlineId();
|
||||
|
||||
bool lan_ai = !m_server->supportsEncryption() &&
|
||||
NetworkConfig::get()->isNetworkAITester();
|
||||
if (lan_ai)
|
||||
id = 0;
|
||||
BareNetworkString* rest = new BareNetworkString();
|
||||
if (m_server->supportsEncryption() && id != 0)
|
||||
{
|
||||
@ -410,11 +415,22 @@ void ClientLobby::update(int ticks)
|
||||
|
||||
rest->encodeString(ServerConfig::m_private_server_password)
|
||||
.addUInt8(player_count);
|
||||
for (auto& p : NetworkConfig::get()->getNetworkPlayers())
|
||||
for (unsigned i = 0;
|
||||
i < NetworkConfig::get()->getNetworkPlayers().size(); i++)
|
||||
{
|
||||
core::stringw name;
|
||||
auto& p = NetworkConfig::get()->getNetworkPlayers()[i];
|
||||
PlayerProfile* player = std::get<1>(p);
|
||||
rest->encodeString(player->getName()).
|
||||
core::stringw name = player->getName();
|
||||
if (lan_ai)
|
||||
{
|
||||
// I18N: Shown in lobby to indicate it's a bot in LAN game
|
||||
name = _("Bot");
|
||||
if (i > 0)
|
||||
{
|
||||
name += core::stringw(" ") + StringUtils::toWString(i);
|
||||
}
|
||||
}
|
||||
rest->encodeString(name).
|
||||
addFloat(player->getDefaultKartColor());
|
||||
// Per-player handicap
|
||||
rest->addUInt8(std::get<2>(p));
|
||||
|
@ -3201,7 +3201,7 @@ void ServerLobby::updateServerOwner()
|
||||
for (auto peer: peers)
|
||||
{
|
||||
// Only 127.0.0.1 can be server owner in case of graphics-client-server
|
||||
if (peer->isValidated() &&
|
||||
if (peer->isValidated() && peer->getUserVersion() != "AI" &&
|
||||
(NetworkConfig::get()->getServerIdFile().empty() ||
|
||||
peer->getAddress().getIP() == 0x7f000001))
|
||||
{
|
||||
|
@ -1639,3 +1639,17 @@ void STKHost::updatePlayers(unsigned* ingame, unsigned* waiting,
|
||||
if (total)
|
||||
*total = total_players;
|
||||
} // updatePlayers
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** True if this is a client and server in graphics mode made by server
|
||||
* creation screen. */
|
||||
bool STKHost::isClientServer() const
|
||||
{
|
||||
return NetworkConfig::get()->isClient() && m_separate_process != NULL;
|
||||
} // isClientServer
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
bool STKHost::hasServerAI() const
|
||||
{
|
||||
return NetworkConfig::get()->isServer() && m_separate_process != NULL;
|
||||
} // hasServerAI
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include <enet/enet.h>
|
||||
|
||||
#include <atomic>
|
||||
#include <cassert>
|
||||
#include <list>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
@ -340,9 +341,15 @@ public:
|
||||
// ------------------------------------------------------------------------
|
||||
void sendToServer(NetworkString *data, bool reliable = true);
|
||||
// ------------------------------------------------------------------------
|
||||
/** True if this is a client and server in graphics mode made by server
|
||||
* creation screen. */
|
||||
bool isClientServer() const { return m_separate_process != NULL; }
|
||||
bool isClientServer() const;
|
||||
// ------------------------------------------------------------------------
|
||||
bool hasServerAI() const;
|
||||
// ------------------------------------------------------------------------
|
||||
void setSeparateProcess(SeparateProcess* p)
|
||||
{
|
||||
assert(m_separate_process == NULL);
|
||||
m_separate_process = p;
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
void initClientNetwork(ENetEvent& event, Network* new_network);
|
||||
// ------------------------------------------------------------------------
|
||||
|
@ -86,6 +86,7 @@ void CreateServerScreen::loadedFromFile()
|
||||
void CreateServerScreen::init()
|
||||
{
|
||||
Screen::init();
|
||||
m_supports_ai = NetworkConfig::get()->isLAN();
|
||||
m_info_widget->setText("", false);
|
||||
LabelWidget *title = getWidget<LabelWidget>("title");
|
||||
|
||||
@ -142,7 +143,14 @@ void CreateServerScreen::eventCallback(Widget* widget, const std::string& name,
|
||||
updateMoreOption(selection);
|
||||
m_prev_mode = selection;
|
||||
}
|
||||
|
||||
else if (name == m_max_players_widget->m_properties[PROP_ID] &&
|
||||
m_supports_ai)
|
||||
{
|
||||
m_prev_value = m_more_options_spinner->getValue();
|
||||
const int selection =
|
||||
m_game_mode_widget->getSelection(PLAYER_ID_GAME_MASTER);
|
||||
updateMoreOption(selection);
|
||||
}
|
||||
} // eventCallback
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -154,17 +162,39 @@ void CreateServerScreen::updateMoreOption(int game_mode)
|
||||
case 1:
|
||||
{
|
||||
m_more_options_text->setVisible(true);
|
||||
//I18N: In the create server screen
|
||||
m_more_options_text->setText(_("No. of grand prix track(s)"),
|
||||
false);
|
||||
m_more_options_spinner->setVisible(true);
|
||||
m_more_options_spinner->clearLabels();
|
||||
m_more_options_spinner->addLabel(_("Disabled"));
|
||||
for (int i = 1; i <= 20; i++)
|
||||
if (m_supports_ai)
|
||||
{
|
||||
m_more_options_spinner->addLabel(StringUtils::toWString(i));
|
||||
m_more_options_text->setText(_("Number of AI karts"),
|
||||
false);
|
||||
for (int i = 0; i <= m_max_players_widget->getValue() - 2; i++)
|
||||
{
|
||||
m_more_options_spinner->addLabel(
|
||||
StringUtils::toWString(i));
|
||||
}
|
||||
if (m_prev_value > m_max_players_widget->getValue() - 2)
|
||||
{
|
||||
m_more_options_spinner->setValue(
|
||||
m_max_players_widget->getValue() - 2);
|
||||
}
|
||||
else
|
||||
m_more_options_spinner->setValue(m_prev_value);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
//I18N: In the create server screen
|
||||
m_more_options_text->setText(_("No. of grand prix track(s)"),
|
||||
false);
|
||||
m_more_options_spinner->addLabel(_("Disabled"));
|
||||
for (int i = 1; i <= 20; i++)
|
||||
{
|
||||
m_more_options_spinner->addLabel(
|
||||
StringUtils::toWString(i));
|
||||
}
|
||||
m_more_options_spinner->setValue(m_prev_value);
|
||||
}
|
||||
m_more_options_spinner->setValue(m_prev_value);
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
@ -360,9 +390,17 @@ void CreateServerScreen::createServer()
|
||||
}
|
||||
else
|
||||
{
|
||||
// Grand prix track count
|
||||
if (esi > 0)
|
||||
server_cfg << " --network-gp=" << esi;
|
||||
if (m_supports_ai)
|
||||
{
|
||||
if (esi > 0)
|
||||
server_cfg << " --server-ai=" << esi;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Grand prix track count
|
||||
if (esi > 0)
|
||||
server_cfg << " --network-gp=" << esi;
|
||||
}
|
||||
}
|
||||
m_prev_mode = gamemode_widget->getSelection(PLAYER_ID_GAME_MASTER);
|
||||
m_prev_value = esi;
|
||||
|
@ -34,6 +34,8 @@ class CreateServerScreen : public GUIEngine::Screen,
|
||||
private:
|
||||
int m_prev_mode, m_prev_value;
|
||||
|
||||
bool m_supports_ai;
|
||||
|
||||
friend class GUIEngine::ScreenSingleton<CreateServerScreen>;
|
||||
|
||||
CreateServerScreen();
|
||||
|
@ -79,14 +79,15 @@ std::string SeparateProcess::getCurrentExecutableLocation()
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
SeparateProcess::SeparateProcess(const std::string& exe,
|
||||
const std::string& argument, bool create_pipe)
|
||||
const std::string& argument, bool create_pipe,
|
||||
const std::string& childprocess_name)
|
||||
{
|
||||
#ifdef ANDROID
|
||||
m_child_handle = NULL;
|
||||
m_child_abort_proc = NULL;
|
||||
#endif
|
||||
|
||||
if (!createChildProcess(exe, argument, create_pipe))
|
||||
if (!createChildProcess(exe, argument, create_pipe, childprocess_name))
|
||||
{
|
||||
Log::error("SeparateProcess", "Failed to run %s %s",
|
||||
exe.c_str(), argument.c_str());
|
||||
@ -184,7 +185,8 @@ SeparateProcess::~SeparateProcess()
|
||||
#if defined(WIN32)
|
||||
bool SeparateProcess::createChildProcess(const std::string& exe,
|
||||
const std::string& argument,
|
||||
bool create_pipe)
|
||||
bool create_pipe,
|
||||
const std::string& childprocess_name)
|
||||
{
|
||||
// Based on: https://msdn.microsoft.com/en-us/library/windows/desktop/ms682499(v=vs.85).aspx
|
||||
SECURITY_ATTRIBUTES sec_attr;
|
||||
@ -281,7 +283,8 @@ bool SeparateProcess::createChildProcess(const std::string& exe,
|
||||
|
||||
bool SeparateProcess::createChildProcess(const std::string& exe,
|
||||
const std::string& argument,
|
||||
bool create_pipe)
|
||||
bool create_pipe,
|
||||
const std::string& childprocess_name)
|
||||
{
|
||||
if (create_pipe)
|
||||
{
|
||||
@ -323,9 +326,10 @@ bool SeparateProcess::createChildProcess(const std::string& exe,
|
||||
}
|
||||
|
||||
Log::info("SeparateProcess", "Data dir found in: %s", data_path.c_str());
|
||||
|
||||
std::string child_path = data_path + "/files/libchildprocess.so";
|
||||
|
||||
|
||||
std::string child_path = data_path + "/files/lib" +
|
||||
childprocess_name + ".so";
|
||||
|
||||
if (access(child_path.c_str(), R_OK) != 0)
|
||||
{
|
||||
Log::info("SeparateProcess", "Creating libchildprocess.so");
|
||||
@ -408,7 +412,8 @@ bool SeparateProcess::createChildProcess(const std::string& exe,
|
||||
|
||||
bool SeparateProcess::createChildProcess(const std::string& exe,
|
||||
const std::string& argument,
|
||||
bool create_pipe)
|
||||
bool create_pipe,
|
||||
const std::string& childprocess_name)
|
||||
{
|
||||
const int PIPE_READ=0;
|
||||
const int PIPE_WRITE=1;
|
||||
|
@ -51,7 +51,8 @@ private:
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
bool createChildProcess(const std::string& exe,
|
||||
const std::string& argument, bool create_pipe);
|
||||
const std::string& argument, bool create_pipe,
|
||||
const std::string& childprocess_name);
|
||||
// ------------------------------------------------------------------------
|
||||
std::string getLine();
|
||||
|
||||
@ -60,7 +61,8 @@ public:
|
||||
static std::string getCurrentExecutableLocation();
|
||||
// ------------------------------------------------------------------------
|
||||
SeparateProcess(const std::string& exe, const std::string& argument,
|
||||
bool create_pipe = false);
|
||||
bool create_pipe = false,
|
||||
const std::string& childprocess_name = "childprocess");
|
||||
// ------------------------------------------------------------------------
|
||||
~SeparateProcess();
|
||||
// ------------------------------------------------------------------------
|
||||
|
Loading…
x
Reference in New Issue
Block a user