Merge branch 'master' of https://github.com/supertuxkart/stk-code into GUI_Folders

This commit is contained in:
Alayan 2018-09-16 16:44:31 +02:00
commit 085e3f8eae
15 changed files with 285 additions and 45 deletions

View File

@ -1,6 +1,8 @@
# Online networking games for STK # Online networking games for STK
## Hosting server ## Hosting server
First of all, you can compile STK with `-DSERVER_ONLY=ON` which will produce a GUI-less STK binary optimized for size and memory usage, useful for situation like in VPS.
### Hosting WAN (public internet) server ### Hosting WAN (public internet) server
You are required to have an stk online account first, go [here](https://addons.supertuxkart.net/register.php) for registration. You are required to have an stk online account first, go [here](https://addons.supertuxkart.net/register.php) for registration.
@ -36,7 +38,7 @@ The current server configuration xml looks like this:
<!-- Number of grand prix tracks per game (If grand prix enabled). --> <!-- Number of grand prix tracks per game (If grand prix enabled). -->
<gp-track-count value="3" /> <gp-track-count value="3" />
<!-- Use goal torget in soccer. --> <!-- Use goal target in soccer. -->
<soccer-goal-target value="false" /> <soccer-goal-target value="false" />
<!-- Enable wan server, which requires you to have an stk-addons account with a saved session. Check init-user command for details. --> <!-- Enable wan server, which requires you to have an stk-addons account with a saved session. Check init-user command for details. -->
@ -69,11 +71,11 @@ The current server configuration xml looks like this:
<!-- No server owner in lobby which can control the starting of game or kick any players. --> <!-- No server owner in lobby which can control the starting of game or kick any players. -->
<owner-less value="false" /> <owner-less value="false" />
<!-- Time to wait before entering kart selection screen if satisfied start-game-threshold below for owner less or ranked server. --> <!-- Time to wait before entering kart selection screen if satisfied min-start-game-players below for owner less or ranked server. -->
<start-game-counter value="30" /> <start-game-counter value="30" />
<!-- Only auto start kart selection when number of connected player is larger than max player * this value, for owner less or ranked server, after start-game-counter. --> <!-- Only auto start kart selection when number of connected player is larger than or equals this value, for owner less or ranked server, after start-game-counter reaches 0. -->
<start-game-threshold value="0.5" /> <min-start-game-players value="2" />
<!-- Automatically end linear race game after 1st player finished for some time (currently his finished time * 0.25 + 15.0). --> <!-- Automatically end linear race game after 1st player finished for some time (currently his finished time * 0.25 + 15.0). -->
<auto-end value="false" /> <auto-end value="false" />
@ -123,16 +125,17 @@ The current server configuration xml looks like this:
</server-config> </server-config>
``` ```
At the moment STK has a list of STUN servers for NAT penetration which allows players or servers behind a firewall or router to make connectable to each other, but in case it doesn't work, you have to manually disable firewall / do a port-forward for the server port STK using. At the moment STK has a list of STUN servers for NAT penetration which allows players or servers behind a firewall or router to be able to connect to each other, but in case it doesn't work, you have to manually disable the firewall or port forward the port(s) used by the STK.
By default STK uses `2759` for server port, for example in Ubuntu alike Linux distribution do the following to disable firewall on such port: By default STK servers use port `2759`. For example, in Ubuntu based distributions, run the following command to disable the firewall on that port:
`sudo ufw allow 2759` `sudo ufw allow 2759`
You may also need to handle the server discovery port `2757` for connecting your WAN server in LAN / localhost. You may also need to handle the server discovery port `2757` for connecting your WAN server in LAN / localhost.
Notice: You don't need to make any firewall or router configuration if you connect to our official servers. Notice: You don't need to make any firewall or router configuration changes if you connect to our official servers.
### Hosting LAN (local internet) server ### Hosting LAN (local internet) server
Everything is basically the same as WAN one, except you don't need an stk online account, just do: Everything is basically the same as WAN one, except you don't need an stk online account, just do:
@ -148,3 +151,21 @@ After the first time configuration, you can just start the server with the comma
You can find out that directory location [here (See Where is the configuration stored?)](https://supertuxkart.net/FAQ) You can find out that directory location [here (See Where is the configuration stored?)](https://supertuxkart.net/FAQ)
## Testing server
There is a network AI tester in STK which can use AI on player controller for server hosting linear races game mode, which helps automating the testing for servers, to enable it use:
`supertuxkart --connect-now=x.x.x.x:y --server-id=id --network-ai=n --auto-connect --no-graphics`
x.x.x.x:y is your server ip address with its port, id is the id field of server-info in STK server xml list, omit it if you are testing LAN server, n is the number of AI you want to create.
You can see STK server xml list [here](https://addons.supertuxkart.net/api/v2/server/get-all).
The server you want to test must be able to be connected without NAT penetration. You can remove `--auto-connect` if you have another client which can control the starting of games in server, or you can consider enable owner-less mode on server so the games on server can keep going. Remove `--no-graphics` if you want to see the AI racing. You can also run network AI tester in server-only build of STK.
With the network AI tester, it's easier to for example simulate high-loaded servers or bad (high ping with packet loss) network.
Tested on a Raspberry Pi 3 Model B+, if you have 8 players connected to a server hosted on it, the CPU usage of STK is ~60% and there are ~60MB of memory usage for game with heavy tracks like Cocoa Temple or Candela City on the server, you can use the above figures to consider number of STK servers hosting on a same computer.
For bad network simulation, we recommend `network traffic control` by linux kernel, see [here](https://wiki.linuxfoundation.org/networking/netem) for details.
You have the best gaming experience when choosing server less than 100ms ping with no packet loss.

View File

@ -1102,7 +1102,7 @@ msgstr "Nachdem die Eingabegeräte konfiguriert worden sind, wähle im Hauptmen
#. I18N: ./data/gui/kart_color_slider.stkgui #. I18N: ./data/gui/kart_color_slider.stkgui
#. I18N: In the kart color slider dialog #. I18N: In the kart color slider dialog
msgid "0 to use the original color, otherwise pick one from slider." msgid "0 to use the original color, otherwise pick one from slider."
msgstr "0, um Ursprungsfarbe zu wählen, wähle ansonsten eine vom Schieberegler." msgstr "0, um Originalfarbe zu wählen, wähle ansonsten eine vom Schieberegler."
#. I18N: ./data/gui/karts.stkgui #. I18N: ./data/gui/karts.stkgui
#. I18N: In the kart selection (player setup) screen #. I18N: In the kart selection (player setup) screen
@ -1256,7 +1256,7 @@ msgstr "Passwort für privaten Server (optional)"
#: src/states_screens/ghost_replay_selection.cpp:130 #: src/states_screens/ghost_replay_selection.cpp:130
#: src/states_screens/server_selection.cpp:121 #: src/states_screens/server_selection.cpp:121
msgid "Difficulty" msgid "Difficulty"
msgstr "Schwierigkeitsgrad" msgstr "Schwierigk."
#. I18N: ./data/gui/online/create_server.stkgui #. I18N: ./data/gui/online/create_server.stkgui
#. I18N: Difficulty #. I18N: Difficulty
@ -1398,7 +1398,7 @@ msgstr "Server finden"
#. I18N: In the online multiplayer screen #. I18N: In the online multiplayer screen
#: src/states_screens/create_server_screen.cpp:91 #: src/states_screens/create_server_screen.cpp:91
msgid "Create Server" msgid "Create Server"
msgstr "Server Erstellen" msgstr "Server erstellen"
#. I18N: ./data/gui/online/lobby_settings.stkgui #. I18N: ./data/gui/online/lobby_settings.stkgui
#. I18N: In the lobby settings screen #. I18N: In the lobby settings screen
@ -1775,7 +1775,7 @@ msgstr "Ton"
#. I18N: ./data/gui/user_screen_tab.stkgui #. I18N: ./data/gui/user_screen_tab.stkgui
#. I18N: Section in the settings menu #. I18N: Section in the settings menu
msgid "User Interface" msgid "User Interface"
msgstr "Benutzeroberfläche" msgstr "Benutzer- oberfläche"
#. I18N: ./data/gui/options_audio.stkgui #. I18N: ./data/gui/options_audio.stkgui
#. I18N: Section in the settings menu #. I18N: Section in the settings menu
@ -1912,7 +1912,7 @@ msgstr "Bildrate anzeigen"
#. I18N: ./data/gui/options_ui.stkgui #. I18N: ./data/gui/options_ui.stkgui
#. I18N: In the ui settings #. I18N: In the ui settings
msgid "Multiplayer splits screen horizontally" msgid "Multiplayer splits screen horizontally"
msgstr "Mehrspieler teilt Bildschirm horizontal" msgstr "Mehrspieler teilt Bildschirm horiz."
#. I18N: ./data/gui/options_ui.stkgui #. I18N: ./data/gui/options_ui.stkgui
#. I18N: In the ui settings #. I18N: In the ui settings
@ -1927,7 +1927,7 @@ msgstr "Mit dem Internet verbinden"
#. I18N: ./data/gui/options_ui.stkgui #. I18N: ./data/gui/options_ui.stkgui
#. I18N: In the ui settings #. I18N: In the ui settings
msgid "Send anonymous hardware statistics" msgid "Send anonymous hardware statistics"
msgstr "Anonyme Hardwarestatistiken senden" msgstr "Anonyme HW-Statistiken senden"
#. I18N: ./data/gui/options_ui.stkgui #. I18N: ./data/gui/options_ui.stkgui
#. I18N: In the ui settings #. I18N: In the ui settings
@ -2136,7 +2136,7 @@ msgstr "Passwort speichern"
#. I18N: ./data/gui/user_screen_tab.stkgui #. I18N: ./data/gui/user_screen_tab.stkgui
#. I18N: In the user screen #. I18N: In the user screen
msgid "Add user" msgid "Add user"
msgstr "Nutzer hinzufügen" msgstr "Neuer Nutzer"
#. I18N: ./data/gui/user_screen.stkgui #. I18N: ./data/gui/user_screen.stkgui
#. I18N: In the user screen #. I18N: In the user screen
@ -4782,7 +4782,7 @@ msgstr "Inhaber"
#. I18N: In server selection screen, distance to server #. I18N: In server selection screen, distance to server
#: src/states_screens/server_selection.cpp:129 #: src/states_screens/server_selection.cpp:129
msgid "Distance (km)" msgid "Distance (km)"
msgstr "Entfernung (km)" msgstr "Entf. (km)"
#. I18N: In server selection screen, unknown distance to server #. I18N: In server selection screen, unknown distance to server
#: src/states_screens/server_selection.cpp:214 #: src/states_screens/server_selection.cpp:214

View File

@ -1,5 +1,5 @@
# Modify this file to change the last-modified date when you add/remove a file. # Modify this file to change the last-modified date when you add/remove a file.
# This will then trigger a new cmake run automatically. # This will then trigger a new cmake run automatically.
file(GLOB_RECURSE STK_HEADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "src/*.hpp") file(GLOB_RECURSE STK_HEADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "src/*.hpp")
file(GLOB_RECURSE STK_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "src/*.cpp") file(GLOB_RECURSE STK_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "src/*.cpp")
file(GLOB_RECURSE STK_SHADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "data/shaders/*") file(GLOB_RECURSE STK_SHADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "data/shaders/*")

View File

@ -48,6 +48,7 @@ AIBaseController::AIBaseController(AbstractKart *kart)
void AIBaseController::reset() void AIBaseController::reset()
{ {
m_enabled_network_ai = false;
m_stuck = false; m_stuck = false;
m_collision_ticks.clear(); m_collision_ticks.clear();
} // reset } // reset

View File

@ -43,6 +43,7 @@ private:
bool m_stuck; bool m_stuck;
protected: protected:
bool m_enabled_network_ai;
/** Length of the kart, storing it here saves many function calls. */ /** Length of the kart, storing it here saves many function calls. */
float m_kart_length; float m_kart_length;
@ -106,6 +107,7 @@ public:
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
virtual void saveState(BareNetworkString *buffer) const OVERRIDE; virtual void saveState(BareNetworkString *buffer) const OVERRIDE;
virtual void rewindTo(BareNetworkString *buffer) OVERRIDE; virtual void rewindTo(BareNetworkString *buffer) OVERRIDE;
void setNetworkAI(bool val) { m_enabled_network_ai = val; }
}; // AIBaseController }; // AIBaseController

View File

@ -103,6 +103,8 @@ public:
/** Get a pointer on the kart controls. */ /** Get a pointer on the kart controls. */
virtual KartControl* getControls() { return m_controls; } virtual KartControl* getControls() { return m_controls; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
void setControls(KartControl* kc) { m_controls = kc; }
// ------------------------------------------------------------------------
/** Only local players can get achievements. */ /** Only local players can get achievements. */
virtual bool canGetAchievements () const { return false; } virtual bool canGetAchievements () const { return false; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------

View File

@ -0,0 +1,123 @@
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2018 SuperTuxKart-Team
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "karts/controller/network_ai_controller.hpp"
#include "graphics/camera.hpp"
#include "karts/abstract_kart.hpp"
#include "karts/controller/kart_control.hpp"
#include "karts/controller/skidding_ai.hpp"
#include "modes/world.hpp"
#include "network/protocols/game_protocol.hpp"
#include "network/network_config.hpp"
#include "network/rewind_manager.hpp"
// ============================================================================
const int UPDATE_FREQUENCY = 30;
// ----------------------------------------------------------------------------
NetworkAIController::NetworkAIController(AbstractKart *kart,
int local_player_id,
SkiddingAI* ai)
: PlayerController(kart)
{
m_ai_controller = ai;
m_ai_controls = new KartControl;
Camera::createCamera(kart, local_player_id);
ai->setControls(m_ai_controls);
} // NetworkAIController
// ----------------------------------------------------------------------------
NetworkAIController::~NetworkAIController()
{
delete m_ai_controller;
delete m_ai_controls;
} // ~NetworkAIController
// ----------------------------------------------------------------------------
void NetworkAIController::update(int ticks)
{
if (!RewindManager::get()->isRewinding())
{
if (World::getWorld()->isStartPhase() ||
World::getWorld()->getTicksSinceStart() > m_prev_update_ticks)
{
m_prev_update_ticks = World::getWorld()->getTicksSinceStart() +
UPDATE_FREQUENCY;
m_ai_controller->update(UPDATE_FREQUENCY);
convertAIToPlayerActions();
}
}
PlayerController::update(ticks);
} // update
// ----------------------------------------------------------------------------
void NetworkAIController::reset()
{
m_prev_update_ticks = 0;
m_ai_controller->reset();
m_ai_controller->setNetworkAI(true);
m_ai_controls->reset();
PlayerController::reset();
} // reset
// ----------------------------------------------------------------------------
void NetworkAIController::convertAIToPlayerActions()
{
std::vector<std::pair<PlayerAction, int> > all_actions;
if (m_ai_controls->getSteer() < 0.0f)
{
all_actions.emplace_back(PA_STEER_LEFT,
fabsf(m_ai_controls->getSteer()) * 32768);
}
else
{
all_actions.emplace_back(PA_STEER_RIGHT,
fabsf(m_ai_controls->getSteer()) * 32768);
}
all_actions.emplace_back(PA_ACCEL,
m_ai_controls->getAccel() * 32768);
all_actions.emplace_back(PA_BRAKE,
m_ai_controls->getBrake() ? 32768 : 0);
all_actions.emplace_back(PA_FIRE,
m_ai_controls->getFire() ? 32768 : 0);
all_actions.emplace_back(PA_NITRO,
m_ai_controls->getNitro() ? 32768 : 0);
all_actions.emplace_back(PA_DRIFT,
m_ai_controls->getSkidControl() == KartControl::SC_NONE ?
0 : 32768);
all_actions.emplace_back(PA_RESCUE,
m_ai_controls->getRescue() ? 32768 : 0);
for (const auto& a : all_actions)
{
if (!PlayerController::action(a.first, a.second, /*dry_run*/true))
continue;
if (NetworkConfig::get()->isNetworking() &&
NetworkConfig::get()->isClient() &&
!RewindManager::get()->isRewinding())
{
if (auto gp = GameProtocol::lock())
{
gp->controllerAction(m_kart->getWorldKartId(),
a.first, a.second,
m_steer_val_l, m_steer_val_r);
}
}
PlayerController::action(a.first, a.second, false);
}
} // convertAIToPlayerActions

View File

@ -0,0 +1,42 @@
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2018 SuperTuxKart-Team
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef HEADER_NETWORK_AI_CONTROLLER_HPP
#define HEADER_NETWORK_AI_CONTROLLER_HPP
#include "karts/controller/player_controller.hpp"
class AbstractKart;
class SkiddingAI;
class NetworkAIController : public PlayerController
{
private:
int m_prev_update_ticks;
SkiddingAI* m_ai_controller;
KartControl* m_ai_controls;
void convertAIToPlayerActions();
public:
NetworkAIController(AbstractKart *kart, int local_player_id,
SkiddingAI* ai);
virtual ~NetworkAIController();
virtual void update(int ticks) OVERRIDE;
virtual void reset() OVERRIDE;
}; // class NetworkAIController
#endif // HEADER_PLAYER_CONTROLLER_HPP

View File

@ -221,6 +221,8 @@ unsigned int SkiddingAI::getNextSector(unsigned int index)
void SkiddingAI::update(int ticks) void SkiddingAI::update(int ticks)
{ {
float dt = stk_config->ticks2Time(ticks); float dt = stk_config->ticks2Time(ticks);
m_controls->setRescue(false);
// This is used to enable firing an item backwards. // This is used to enable firing an item backwards.
m_controls->setLookBack(false); m_controls->setLookBack(false);
m_controls->setNitro(false); m_controls->setNitro(false);
@ -293,7 +295,11 @@ void SkiddingAI::update(int ticks)
// If the kart needs to be rescued, do it now (and nothing else) // If the kart needs to be rescued, do it now (and nothing else)
if(isStuck() && !m_kart->getKartAnimation()) if(isStuck() && !m_kart->getKartAnimation())
{ {
new RescueAnimation(m_kart); // For network AI controller
if (m_enabled_network_ai)
m_controls->setRescue(true);
else
new RescueAnimation(m_kart);
AIBaseLapController::update(ticks); AIBaseLapController::update(ticks);
return; return;
} }
@ -2085,6 +2091,11 @@ void SkiddingAI::handleRaceStart()
{ {
if( m_start_delay < 0 ) if( m_start_delay < 0 )
{ {
if (m_enabled_network_ai)
{
m_start_delay = 0;
return;
}
// Each kart starts at a different, random time, and the time is // Each kart starts at a different, random time, and the time is
// smaller depending on the difficulty. // smaller depending on the difficulty.
m_start_delay = stk_config->time2Ticks( m_start_delay = stk_config->time2Ticks(
@ -2122,7 +2133,11 @@ void SkiddingAI::handleRescue(const float dt)
m_time_since_stuck += dt; m_time_since_stuck += dt;
if(m_time_since_stuck > 2.0f) if(m_time_since_stuck > 2.0f)
{ {
new RescueAnimation(m_kart); // For network AI controller
if (m_enabled_network_ai)
m_controls->setRescue(true);
else
new RescueAnimation(m_kart);
m_time_since_stuck=0.0f; m_time_since_stuck=0.0f;
} // m_time_since_stuck > 2.0f } // m_time_since_stuck > 2.0f
} }

View File

@ -610,6 +610,8 @@ void cmdLineHelp()
" (in format x.x.x.x:xxx(port)), the port should be its\n" " (in format x.x.x.x:xxx(port)), the port should be its\n"
" public port.\n" " public port.\n"
" --server-id=n Server id in stk addons for --connect-now.\n" " --server-id=n Server id in stk addons for --connect-now.\n"
" --network-ai=n Numbers of AI for connecting to linear race server, used\n"
" together with --connect-now.\n"
" --login=s Automatically log in (set the login).\n" " --login=s Automatically log in (set the login).\n"
" --password=s Automatically log in (set the password).\n" " --password=s Automatically log in (set the password).\n"
" --init-user Save the above login and password (if set) in config.\n" " --init-user Save the above login and password (if set) in config.\n"
@ -1272,14 +1274,28 @@ int handleCmdLine(bool has_server_config, bool has_parent_process)
if (CommandLine::has("--connect-now", &s)) if (CommandLine::has("--connect-now", &s))
{ {
TransportAddress server_addr(s);
NetworkConfig::get()->setIsWAN(); NetworkConfig::get()->setIsWAN();
NetworkConfig::get()->setIsServer(false); NetworkConfig::get()->setIsServer(false);
if (CommandLine::has("--network-ai", &n))
{
NetworkConfig::get()->setNetworkAITester(true);
PlayerManager::get()->createGuestPlayers(n);
for (int i = 0; i < n; i++)
{
NetworkConfig::get()->addNetworkPlayer(
NULL, PlayerManager::get()->getPlayer(i),
PLAYER_DIFFICULTY_NORMAL);
}
}
else
{
NetworkConfig::get()->addNetworkPlayer(
input_manager->getDeviceManager()->getLatestUsedDevice(),
PlayerManager::getCurrentPlayer(), PLAYER_DIFFICULTY_NORMAL);
}
TransportAddress server_addr(s);
auto server = std::make_shared<Server>(0, L"", 0, 0, 0, 0, server_addr, auto server = std::make_shared<Server>(0, L"", 0, 0, 0, 0, server_addr,
!server_password.empty(), false); !server_password.empty(), false);
NetworkConfig::get()->addNetworkPlayer(
input_manager->getDeviceManager()->getLatestUsedDevice(),
PlayerManager::getCurrentPlayer(), PLAYER_DIFFICULTY_NORMAL);
NetworkConfig::get()->doneAddingNetworkPlayers(); NetworkConfig::get()->doneAddingNetworkPlayers();
STKHost::create(); STKHost::create();
auto cts = std::make_shared<ConnectToServer>(server); auto cts = std::make_shared<ConnectToServer>(server);

View File

@ -44,6 +44,7 @@
#include "karts/controller/soccer_ai.hpp" #include "karts/controller/soccer_ai.hpp"
#include "karts/controller/spare_tire_ai.hpp" #include "karts/controller/spare_tire_ai.hpp"
#include "karts/controller/test_ai.hpp" #include "karts/controller/test_ai.hpp"
#include "karts/controller/network_ai_controller.hpp"
#include "karts/controller/network_player_controller.hpp" #include "karts/controller/network_player_controller.hpp"
#include "karts/kart.hpp" #include "karts/kart.hpp"
#include "karts/kart_model.hpp" #include "karts/kart_model.hpp"
@ -387,15 +388,22 @@ std::shared_ptr<AbstractKart> World::createKart
{ {
case RaceManager::KT_PLAYER: case RaceManager::KT_PLAYER:
{ {
controller = new LocalPlayerController(new_kart.get(), local_player_id, if (NetworkConfig::get()->isNetworkAITester())
difficulty);
const PlayerProfile* p = StateManager::get()
->getActivePlayer(local_player_id)->getConstProfile();
if (p && p->getDefaultKartColor() > 0.0f)
{ {
ri->setHue(p->getDefaultKartColor()); controller = new NetworkAIController(new_kart.get(),
local_player_id, new SkiddingAI(new_kart.get()));
}
else
{
controller = new LocalPlayerController(new_kart.get(),
local_player_id, difficulty);
const PlayerProfile* p = StateManager::get()
->getActivePlayer(local_player_id)->getConstProfile();
if (p && p->getDefaultKartColor() > 0.0f)
{
ri->setHue(p->getDefaultKartColor());
}
} }
m_num_players ++; m_num_players ++;
break; break;
} }

View File

@ -54,6 +54,7 @@ NetworkConfig::NetworkConfig()
m_client_port = UserConfigParams::m_random_client_port ? m_client_port = UserConfigParams::m_random_client_port ?
0 : stk_config->m_client_port; 0 : stk_config->m_client_port;
m_joined_server_version = 0; m_joined_server_version = 0;
m_network_ai_tester = false;
} // NetworkConfig } // NetworkConfig
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

View File

@ -65,14 +65,17 @@ private:
/** True if this host is a server, false otherwise. */ /** True if this host is a server, false otherwise. */
bool m_is_server; bool m_is_server;
/** The LAN port on which a client is waiting for a server connection. */
uint16_t m_client_port;
/** True if a client should connect to the first server it finds and /** True if a client should connect to the first server it finds and
* immediately start a race. */ * immediately start a race. */
bool m_auto_connect; bool m_auto_connect;
bool m_done_adding_network_players; bool m_done_adding_network_players;
bool m_network_ai_tester;
/** The LAN port on which a client is waiting for a server connection. */
uint16_t m_client_port;
/** Used by wan server. */ /** Used by wan server. */
uint32_t m_cur_user_id; uint32_t m_cur_user_id;
std::string m_cur_user_token; std::string m_cur_user_token;
@ -154,7 +157,7 @@ public:
{ {
for (auto& p : m_network_players) for (auto& p : m_network_players)
{ {
if (std::get<0>(p) == device) if (std::get<0>(p) == device && !m_network_ai_tester)
return false; return false;
if (std::get<1>(p) == profile) if (std::get<1>(p) == profile)
return false; return false;
@ -192,6 +195,10 @@ public:
* requested. */ * requested. */
bool isAutoConnect() const { return m_auto_connect; } bool isAutoConnect() const { return m_auto_connect; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
void setNetworkAITester(bool b) { m_network_ai_tester = b; }
// ------------------------------------------------------------------------
bool isNetworkAITester() const { return m_network_ai_tester; }
// ------------------------------------------------------------------------
void setCurrentUserId(uint32_t id) { m_cur_user_id = id ; } void setCurrentUserId(uint32_t id) { m_cur_user_id = id ; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
void setCurrentUserToken(const std::string& t) { m_cur_user_token = t; } void setCurrentUserToken(const std::string& t) { m_cur_user_token = t; }

View File

@ -20,6 +20,7 @@
#include "network/event.hpp" #include "network/event.hpp"
#include "network/protocol.hpp" #include "network/protocol.hpp"
#include "network/stk_peer.hpp"
#include "utils/log.hpp" #include "utils/log.hpp"
#include "utils/profiler.hpp" #include "utils/profiler.hpp"
#include "utils/time.hpp" #include "utils/time.hpp"
@ -440,8 +441,9 @@ void ProtocolManager::update(int ticks)
} }
catch (std::exception& e) catch (std::exception& e)
{ {
Log::error("ProtocolManager", "Synchronous event error: %s", const std::string& name = (*i)->getPeer()->getAddress().toString();
e.what()); Log::error("ProtocolManager",
"Synchronous event error from %s: %s", name.c_str(), e.what());
Log::error("ProtocolManager", (*i)->data().getLogMessage().c_str()); Log::error("ProtocolManager", (*i)->data().getLogMessage().c_str());
} }
m_sync_events_to_process.lock(); m_sync_events_to_process.lock();
@ -496,8 +498,9 @@ void ProtocolManager::asynchronousUpdate()
} }
catch (std::exception& e) catch (std::exception& e)
{ {
Log::error("ProtocolManager", "Asynchronous event error: %s", const std::string& name = (*i)->getPeer()->getAddress().toString();
e.what()); Log::error("ProtocolManager", "Asynchronous event "
"error from %s: %s", name.c_str(), e.what());
Log::error("ProtocolManager", Log::error("ProtocolManager",
(*i)->data().getLogMessage().c_str()); (*i)->data().getLogMessage().c_str());
} }

View File

@ -376,6 +376,14 @@ void ClientLobby::update(int ticks)
break; break;
case REQUESTING_CONNECTION: case REQUESTING_CONNECTION:
case CONNECTED: case CONNECTED:
if (STKHost::get()->isAuthorisedToControl() &&
NetworkConfig::get()->isAutoConnect())
{
// Send a message to the server to start
NetworkString start(PROTOCOL_LOBBY_ROOM);
start.addUInt8(LobbyProtocol::LE_REQUEST_BEGIN);
STKHost::get()->sendToServer(&start, true);
}
case SELECTING_ASSETS: case SELECTING_ASSETS:
case RACING: case RACING:
case EXITING: case EXITING:
@ -709,15 +717,6 @@ void ClientLobby::handleBadConnection()
void ClientLobby::becomingServerOwner() void ClientLobby::becomingServerOwner()
{ {
STKHost::get()->setAuthorisedToControl(true); STKHost::get()->setAuthorisedToControl(true);
if (m_state.load() == CONNECTED && NetworkConfig::get()->isAutoConnect())
{
// Send a message to the server to start
NetworkString start(PROTOCOL_LOBBY_ROOM);
start.setSynchronous(true);
start.addUInt8(LobbyProtocol::LE_REQUEST_BEGIN);
STKHost::get()->sendToServer(&start, true);
}
if (STKHost::get()->isClientServer()) if (STKHost::get()->isClientServer())
return; return;