merging uni's branch
git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/branches/hilnius@13337 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
commit
c5c6c6195f
@ -42,6 +42,8 @@ endif()
|
||||
# Build the irrlicht library
|
||||
add_subdirectory("${PROJECT_SOURCE_DIR}/lib/irrlicht")
|
||||
include_directories("${PROJECT_SOURCE_DIR}/lib/irrlicht/include")
|
||||
include_directories("${PROJECT_SOURCE_DIR}/lib/irrlicht/source/Irrlicht")
|
||||
|
||||
|
||||
|
||||
# Set include paths
|
||||
|
36
data/gui/online/create_server.stkgui
Normal file
36
data/gui/online/create_server.stkgui
Normal file
@ -0,0 +1,36 @@
|
||||
<stkgui>
|
||||
<div x="0" y="0" width="100%" height="100%" layout="vertical-row" >
|
||||
|
||||
<header text_align="center" width="80%" align="center" I18N="In the create server screen" text="Server Creation"/>
|
||||
<spacer height="15" width="10"/>
|
||||
<box proportion="4" width="90%" layout="vertical-row" align="center">
|
||||
<div width="90%" align="center" layout="vertical-row" y="2%" height="96%">
|
||||
<div width="100%" align="center" layout="vertical-row" height="fit" >
|
||||
<div width="100%" height="fit" layout="horizontal-row" >
|
||||
<label proportion="1" text_align="left" I18N="In the create server screen" text="Name of the server"/>
|
||||
<textbox proportion="1" id="name" I18N="In the create server screen"/>
|
||||
</div>
|
||||
|
||||
<spacer height="20" width="20">
|
||||
|
||||
<div width="100%" height="fit" layout="horizontal-row" >
|
||||
<label proportion="1" text_align="left" I18N="In the create server screen" text="Max. number of players"/>
|
||||
<gauge id="max_players" proportion="1" min_value="2" max_value="12"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<label id="info" proportion="1" width="100%" align="center" text_align="center" word_wrap="true" text=""/>
|
||||
|
||||
<buttonbar id="options" x="0" y="0" width="25%" height="12%" align="center">
|
||||
<icon-button id="create" width="64" height="64" icon="gui/green_check.png"
|
||||
I18N="Main menu button" text="Create" label_location="bottom"/>
|
||||
<icon-button id="cancel" width="64" height="64" icon="gui/main_quit.png"
|
||||
I18N="Main menu button" text="Cancel" label_location="bottom"/>
|
||||
</buttonbar>
|
||||
</div>
|
||||
</box>
|
||||
<spacer height="15" width="10"/>
|
||||
|
||||
|
||||
</div>
|
||||
</stkgui>
|
@ -6,8 +6,10 @@
|
||||
<div proportion="1" x="2%" width="96%" layout="vertical-row">
|
||||
<div width="100%" proportion="2" layout="horizontal-row">
|
||||
<box id="info" proportion="2" height="100%" layout="vertical-row">
|
||||
<label I18N="In networking lobby" word_wrap="true" text="Description about room"
|
||||
align="center" text-align="center"/>
|
||||
<div width="100%" height="fit" layout="horizontal-row" >
|
||||
<label proportion="1" text_align="left" I18N="In the networking lobby" text="Server name :"/>
|
||||
<label proportion="2" text_align="left" id="server_name" text=""/>
|
||||
</div>
|
||||
</box>
|
||||
<spacer width="20" height="20"/>
|
||||
<box proportion="1" height="100%" layout="vertical-row">
|
||||
@ -36,12 +38,8 @@
|
||||
<spacer width="10" height="10" />
|
||||
|
||||
<buttonbar id="menu_bottomrow" x="0" y="0" width="20%" height="100%" align="center">
|
||||
<icon-button id="sign_in" width="64" height="64" icon="gui/main_about.png" extend_label="50"
|
||||
I18N="Main menu button" text="Sign In" label_location="hover"/>
|
||||
<icon-button id="register" width="64" height="64" icon="gui/tutorial.png" extend_label="75"
|
||||
I18N="Main menu button" text="Register" label_location="hover"/>
|
||||
<icon-button id="sign_out" width="64" height="64" icon="gui/main_quit.png" extend_label="70"
|
||||
I18N="Main menu button" text="Sign Out" label_location="hover"/>
|
||||
<icon-button id="exit" width="64" height="64" icon="gui/main_quit.png" extend_label="50"
|
||||
I18N="Main menu button" text="Exit" label_location="hover"/>
|
||||
</buttonbar>
|
||||
|
||||
</bottombar>
|
||||
|
@ -7,32 +7,47 @@
|
||||
|
||||
<spacer height="20" width="50">
|
||||
|
||||
<label id="info" proportion="2" width="90%" align="center" text_align="left" word_wrap="true" text=""/>
|
||||
<label id="message" proportion="2" width="90%" align="center" text_align="left" word_wrap="true" text=""/>
|
||||
|
||||
<spacer height="40" width="50">
|
||||
|
||||
<div width="80%" align="center" layout="vertical-row" height="fit" >
|
||||
<div width="100%" height="fit" layout="horizontal-row" >
|
||||
<label proportion="1" text_align="left" I18N="In the login dialog" text="Username"/>
|
||||
<textbox proportion="2" id="username" I18N="In the login dialog"/>
|
||||
<div proportion="2" height="100%" layout="horizontal-row">
|
||||
<spacer height="1" width="2%">
|
||||
<textbox proportion="2" id="username" I18N="In the login dialog"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<spacer height="20" width="20">
|
||||
|
||||
<div width="100%" height="fit" layout="horizontal-row" >
|
||||
<label proportion="1" text_align="left" I18N="In the login dialog" text="Password"/>
|
||||
<textbox proportion="2" id="password" I18N="In the login dialog"/>
|
||||
<div proportion="2" height="100%" layout="horizontal-row">
|
||||
<spacer height="1" width="2%">
|
||||
<textbox proportion="2" id="password" I18N="In the login dialog"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<spacer height="20" width="20">
|
||||
|
||||
<div width="100%" height="fit" layout="horizontal-row" >
|
||||
<label proportion="1" text_align="left" I18N="In the login dialog" text="Stay signed in"/>
|
||||
<div proportion="2" height="100%" layout="horizontal-row">
|
||||
<checkbox width="fit" height="fit" id="remember" I18N="In the login dialog"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<spacer height="20" width="50">
|
||||
<spacer height="20" width="50">
|
||||
|
||||
<label id="message" proportion="1" width="90%" align="center" text_align="center" word_wrap="true" text=""/>
|
||||
<label id="info" proportion="1" width="90%" align="center" text_align="center" word_wrap="true" text=""/>
|
||||
|
||||
<spacer height="20" width="50">
|
||||
|
||||
<buttonbar id="options" width="90%" proportion="1" align="center">
|
||||
<icon-button id="sign_in" width="64" height="64" icon="gui/main_options.png"
|
||||
<icon-button id="sign_in" width="64" height="64" icon="gui/green_check.png"
|
||||
I18N="Login dialog" text="Sign In" label_location="bottom"/>
|
||||
<icon-button id="recovery" width="64" height="64" icon="gui/main_help.png"
|
||||
I18N="Login dialog" text="Recovery" label_location="bottom"/>
|
||||
@ -41,7 +56,7 @@
|
||||
<icon-button id="as_guest" width="64" height="64" icon="gui/main_about.png"
|
||||
I18N="Login dialog" text="As guest" label_location="bottom"/>
|
||||
<icon-button id="cancel" width="64" height="64" icon="gui/main_quit.png"
|
||||
I18N="Login dialog" text="Cancel" label_location="bottom"/>
|
||||
I18N="Login dialog" text="Close" label_location="bottom"/>
|
||||
</buttonbar>
|
||||
|
||||
|
||||
|
@ -31,7 +31,7 @@
|
||||
|
||||
<spacer width="10" height="10" />
|
||||
|
||||
<buttonbar id="menu_bottomrow" x="0" y="0" width="20%" height="100%" align="center">
|
||||
<buttonbar id="menu_bottomrow" x="0" y="0" width="12%" height="100%" align="center">
|
||||
<icon-button id="sign_in" width="64" height="64" icon="gui/main_about.png" extend_label="50"
|
||||
I18N="Main menu button" text="Sign In" label_location="hover"/>
|
||||
<icon-button id="register" width="64" height="64" icon="gui/tutorial.png" extend_label="75"
|
||||
|
@ -15,11 +15,12 @@
|
||||
|
||||
<spacer height="20" width="50">
|
||||
|
||||
<div id="options" width="fit" proportion="1" align="center" layout="horizontal-row">
|
||||
<button id="next" height="fit" align="center" width="fit" I18N="In the registration dialog" text="Activate"/>
|
||||
<spacer height="50" width="50">
|
||||
<button id="cancel" height="fit" align="center" width="fit" I18N="In the registration dialog" text="Close"/>
|
||||
</div>
|
||||
<buttonbar id="options" width="25%" proportion="1" align="center">
|
||||
<icon-button id="next" width="64" height="64" icon="gui/green_check.png"
|
||||
I18N="Registration dialog" text="Next" label_location="none"/>
|
||||
<icon-button id="cancel" width="64" height="64" icon="gui/main_quit.png"
|
||||
I18N="Registration dialog" text="Cancel" label_location="none"/>
|
||||
</buttonbar>
|
||||
|
||||
|
||||
</div>
|
||||
|
@ -49,12 +49,12 @@
|
||||
|
||||
<spacer height="20" width="50">
|
||||
|
||||
<div id="options" width="fit" proportion="1" align="center" layout="horizontal-row">
|
||||
<button id="next" height="fit" align="center" width="fit" I18N="In the registration dialog" text="Next"/>
|
||||
<spacer height="50" width="50">
|
||||
<button id="cancel" height="fit" align="center" width="fit" I18N="In the registration dialog" text="Cancel"/>
|
||||
</div>
|
||||
|
||||
<buttonbar id="options" width="25%" proportion="1" align="center">
|
||||
<icon-button id="next" width="64" height="64" icon="gui/green_check.png"
|
||||
I18N="Registration dialog" text="Next" label_location="none"/>
|
||||
<icon-button id="cancel" width="64" height="64" icon="gui/main_quit.png"
|
||||
I18N="Registration dialog" text="Cancel" label_location="none"/>
|
||||
</buttonbar>
|
||||
|
||||
</div>
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
<spacer height="20" width="50">
|
||||
|
||||
<label id="terms" proportion="6" width="90%" align="center" text_align="center" word_wrap="true"
|
||||
<label id="terms" proportion="5" width="90%" align="center" text_align="center" word_wrap="true"
|
||||
I18N="In the registration dialog' dialog" text="The terms will come here. In a fancy scroll box."/>
|
||||
|
||||
<div align="center" width="fit" height="fit" layout="horizontal-row" >
|
||||
@ -17,14 +17,20 @@
|
||||
</div>
|
||||
|
||||
<spacer height="20" width="50">
|
||||
|
||||
<div id="options" width="fit" proportion="1" align="center" layout="horizontal-row">
|
||||
<button id="previous" height="fit" align="center" width="fit" I18N="In the registration dialog" text="Previous"/>
|
||||
<spacer height="50" width="50">
|
||||
<button id="next" height="fit" align="center" width="fit" I18N="In the registration dialog" text="Submit"/>
|
||||
<spacer height="50" width="50">
|
||||
<button id="cancel" height="fit" align="center" width="fit" I18N="In the registration dialog" text="Cancel"/>
|
||||
</div>
|
||||
|
||||
<label id="info" proportion="1" width="90%" align="center" text_align="center" word_wrap="true"
|
||||
I18N="In the registration dialog' dialog" text=""/>
|
||||
|
||||
<spacer height="20" width="50">
|
||||
|
||||
<buttonbar id="options" width="45%" proportion="1" align="center">
|
||||
<icon-button id="previous" width="64" height="64" icon="gui/back.png"
|
||||
I18N="Registration dialog" text="Previous" label_location="bottom"/>
|
||||
<icon-button id="next" width="64" height="64" icon="gui/green_check.png"
|
||||
I18N="Registration dialog" text="Submit" label_location="bottom"/>
|
||||
<icon-button id="cancel" width="64" height="64" icon="gui/main_quit.png"
|
||||
I18N="Registration dialog" text="Cancel" label_location="bottom"/>
|
||||
</buttonbar>
|
||||
|
||||
|
||||
</div>
|
||||
|
33
data/gui/online/server_info_dialog.stkgui
Normal file
33
data/gui/online/server_info_dialog.stkgui
Normal file
@ -0,0 +1,33 @@
|
||||
<stkgui>
|
||||
|
||||
<div x="2%" y="5%" width="96%" height="85%" layout="vertical-row" >
|
||||
|
||||
<header id="title" width="96%" height="fit" text_align="center" word_wrap="true"
|
||||
I18N="In the server info dialog' dialog" text="Server Info"/>
|
||||
|
||||
<spacer height="20" width="50">
|
||||
|
||||
<div width="80%" align="center" layout="vertical-row" height="fit" >
|
||||
<div width="100%" height="fit" layout="horizontal-row" >
|
||||
<label proportion="1" text_align="left" I18N="In the server info dialog" text="Name"/>
|
||||
<label id="name" proportion="2" text_align="left" text=""/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<spacer height="20" width="50">
|
||||
|
||||
<label id="info" proportion="1" width="90%" align="center" text_align="center" word_wrap="true" text=""/>
|
||||
|
||||
<spacer height="20" width="50">
|
||||
|
||||
<buttonbar id="options" width="90%" height="20%" align="center">
|
||||
<icon-button id="join" width="64" height="64" icon="gui/green_check.png"
|
||||
I18N="Login dialog" text="Join" label_location="bottom"/>
|
||||
<icon-button id="cancel" width="64" height="64" icon="gui/main_quit.png"
|
||||
I18N="Login dialog" text="Cancel" label_location="bottom"/>
|
||||
</buttonbar>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</stkgui>
|
17
data/gui/online/server_selection.stkgui
Normal file
17
data/gui/online/server_selection.stkgui
Normal file
@ -0,0 +1,17 @@
|
||||
<stkgui>
|
||||
|
||||
<div x="0%" y="0%" width="100%" height="98%" layout="vertical-row" >
|
||||
|
||||
<div x="0" y="0" width="100%" layout="horizontal-row" height="8%">
|
||||
<icon-button id="back" height="100%" icon="gui/back.png"/>
|
||||
<header text_align="center" proportion="1" text="Server Selection" align="center"/>
|
||||
<icon-button id="reload" height="90%" icon="gui/restart.png"/>
|
||||
</div>
|
||||
|
||||
<box proportion="1" width="98%" align="center" layout="vertical-row" padding="6">
|
||||
<list id="server_list" x="0" y="0" width="100%" height="100%"/>
|
||||
</box>
|
||||
|
||||
</div>
|
||||
|
||||
</stkgui>
|
@ -63,6 +63,7 @@ src/guiengine/widget.cpp
|
||||
src/guiengine/widgets/bubble_widget.cpp
|
||||
src/guiengine/widgets/button_widget.cpp
|
||||
src/guiengine/widgets/CGUIEditBox.cpp
|
||||
src/guiengine/widgets/CGUISTKListBox.cpp
|
||||
src/guiengine/widgets/check_box_widget.cpp
|
||||
src/guiengine/widgets/dynamic_ribbon_widget.cpp
|
||||
src/guiengine/widgets/icon_button_widget.cpp
|
||||
@ -169,9 +170,13 @@ src/network/server_network_manager.cpp
|
||||
src/network/stk_host.cpp
|
||||
src/network/stk_peer.cpp
|
||||
src/network/types.cpp
|
||||
src/online/current_online_user.cpp
|
||||
src/online/http_connector.cpp
|
||||
src/online/online_user.cpp
|
||||
src/online/current_user.cpp
|
||||
src/online/http_manager.cpp
|
||||
src/online/messages.cpp
|
||||
src/online/request.cpp
|
||||
src/online/server.cpp
|
||||
src/online/servers_manager.cpp
|
||||
src/online/user.cpp
|
||||
src/physics/btKart.cpp
|
||||
src/physics/btKartRaycast.cpp
|
||||
src/physics/btUprightConstraint.cpp
|
||||
@ -190,6 +195,7 @@ src/replay/replay_play.cpp
|
||||
src/replay/replay_recorder.cpp
|
||||
src/states_screens/addons_screen.cpp
|
||||
src/states_screens/arenas_screen.cpp
|
||||
src/states_screens/create_server_screen.cpp
|
||||
src/states_screens/credits.cpp
|
||||
src/states_screens/cutscene_gui.cpp
|
||||
src/states_screens/dialogs/add_device_dialog.cpp
|
||||
@ -205,6 +211,7 @@ src/states_screens/dialogs/press_a_key_dialog.cpp
|
||||
src/states_screens/dialogs/race_paused_dialog.cpp
|
||||
src/states_screens/dialogs/registration_dialog.cpp
|
||||
src/states_screens/dialogs/select_challenge.cpp
|
||||
src/states_screens/dialogs/server_info_dialog.cpp
|
||||
src/states_screens/dialogs/track_info_dialog.cpp
|
||||
src/states_screens/dialogs/tutorial_message_dialog.cpp
|
||||
src/states_screens/feature_unlocked.cpp
|
||||
@ -230,6 +237,7 @@ src/states_screens/race_gui.cpp
|
||||
src/states_screens/race_gui_overworld.cpp
|
||||
src/states_screens/race_result_gui.cpp
|
||||
src/states_screens/race_setup_screen.cpp
|
||||
src/states_screens/server_selection.cpp
|
||||
src/states_screens/soccer_setup_screen.cpp
|
||||
src/states_screens/state_manager.cpp
|
||||
src/states_screens/story_mode_lobby.cpp
|
||||
@ -430,9 +438,9 @@ src/network/protocols/client_lobby_room_protocol.hpp
|
||||
src/network/protocols/connect_to_peer.hpp
|
||||
src/network/protocols/connect_to_server.hpp
|
||||
src/network/protocols/controller_events_protocol.hpp
|
||||
src/network/protocols/game_events_protocol.hpp
|
||||
src/network/protocols/get_peer_address.hpp
|
||||
src/network/protocols/get_public_address.hpp
|
||||
src/network/protocols/game_events_protocol.hpp
|
||||
src/network/protocols/hide_public_address.hpp
|
||||
src/network/protocols/kart_update_protocol.hpp
|
||||
src/network/protocols/lobby_room_protocol.hpp
|
||||
@ -451,9 +459,13 @@ src/network/singleton.hpp
|
||||
src/network/stk_host.hpp
|
||||
src/network/stk_peer.hpp
|
||||
src/network/types.hpp
|
||||
src/online/current_online_user.hpp
|
||||
src/online/http_connector.hpp
|
||||
src/online/online_user.hpp
|
||||
src/online/current_user.hpp
|
||||
src/online/http_manager.hpp
|
||||
src/online/messages.hpp
|
||||
src/online/request.hpp
|
||||
src/online/server.hpp
|
||||
src/online/servers_manager.hpp
|
||||
src/online/user.hpp
|
||||
src/physics/btKart.hpp
|
||||
src/physics/btKartRaycast.hpp
|
||||
src/physics/btUprightConstraint.hpp
|
||||
@ -475,6 +487,7 @@ src/replay/replay_play.hpp
|
||||
src/replay/replay_recorder.hpp
|
||||
src/states_screens/addons_screen.hpp
|
||||
src/states_screens/arenas_screen.hpp
|
||||
src/states_screens/create_server_screen.hpp
|
||||
src/states_screens/credits.hpp
|
||||
src/states_screens/cutscene_gui.hpp
|
||||
src/states_screens/dialogs/add_device_dialog.hpp
|
||||
@ -490,6 +503,7 @@ src/states_screens/dialogs/press_a_key_dialog.hpp
|
||||
src/states_screens/dialogs/race_paused_dialog.hpp
|
||||
src/states_screens/dialogs/registration_dialog.hpp
|
||||
src/states_screens/dialogs/select_challenge.hpp
|
||||
src/states_screens/dialogs/server_info_dialog.hpp
|
||||
src/states_screens/dialogs/track_info_dialog.hpp
|
||||
src/states_screens/dialogs/tutorial_message_dialog.hpp
|
||||
src/states_screens/feature_unlocked.hpp
|
||||
@ -515,6 +529,7 @@ src/states_screens/race_gui.hpp
|
||||
src/states_screens/race_gui_overworld.hpp
|
||||
src/states_screens/race_result_gui.hpp
|
||||
src/states_screens/race_setup_screen.hpp
|
||||
src/states_screens/server_selection.hpp
|
||||
src/states_screens/soccer_setup_screen.hpp
|
||||
src/states_screens/state_manager.hpp
|
||||
src/states_screens/story_mode_lobby.hpp
|
||||
|
@ -605,16 +605,48 @@ namespace UserConfigParams
|
||||
PARAM_DEFAULT( WStringUserConfigParam(L"", "default_player",
|
||||
"Which player to use by default (if empty, will prompt)") );
|
||||
|
||||
// ---- Online multiplayer related
|
||||
// ---- Internet related
|
||||
|
||||
PARAM_PREFIX IntUserConfigParam m_internet_status
|
||||
PARAM_DEFAULT( IntUserConfigParam(0, "enable_internet",
|
||||
"Status of internet: 0 user "
|
||||
"wasn't asked, 1: allowed, 2: "
|
||||
"not allowed") );
|
||||
|
||||
// ---- Online gameplay related
|
||||
|
||||
PARAM_PREFIX GroupUserConfigParam m_online_group
|
||||
PARAM_DEFAULT( GroupUserConfigParam("OnlinePlay",
|
||||
"Everything related to online play.") );
|
||||
|
||||
PARAM_PREFIX StringUserConfigParam m_server_multiplayer
|
||||
PARAM_DEFAULT( StringUserConfigParam("http://api.stkaddons.net/",
|
||||
"server_multiplayer",
|
||||
"The server used for online multiplayer."));
|
||||
PARAM_DEFAULT( StringUserConfigParam( "http://api.stkaddons.net/",
|
||||
"server_multiplayer",
|
||||
&m_online_group,
|
||||
"The server used for online multiplayer."));
|
||||
|
||||
PARAM_PREFIX BoolUserConfigParam m_saved_session
|
||||
PARAM_DEFAULT( BoolUserConfigParam( false,
|
||||
"saved_session",
|
||||
&m_online_group,
|
||||
"Is there a saved session?") );
|
||||
|
||||
PARAM_PREFIX IntUserConfigParam m_saved_user
|
||||
PARAM_DEFAULT( IntUserConfigParam( 0,
|
||||
"saved_user",
|
||||
&m_online_group,
|
||||
"User ID of the saved session.") );
|
||||
|
||||
PARAM_PREFIX StringUserConfigParam m_saved_token
|
||||
PARAM_DEFAULT( StringUserConfigParam( "",
|
||||
"saved_token",
|
||||
&m_online_group,
|
||||
"Token of the saved session.") );
|
||||
|
||||
|
||||
// ---- Addon server related entries
|
||||
PARAM_PREFIX GroupUserConfigParam m_addon_group
|
||||
PARAM_DEFAULT( GroupUserConfigParam("AddonAndNews",
|
||||
PARAM_DEFAULT( GroupUserConfigParam("AddonAndNews",
|
||||
"Addon and news related settings") );
|
||||
|
||||
PARAM_PREFIX StringUserConfigParam m_server_addons
|
||||
@ -645,13 +677,6 @@ namespace UserConfigParams
|
||||
"Don't show important message "
|
||||
"with this or a lower id again") );
|
||||
|
||||
PARAM_PREFIX IntUserConfigParam m_internet_status
|
||||
PARAM_DEFAULT( IntUserConfigParam(0, "enable_internet",
|
||||
&m_addon_group,
|
||||
"Status of internet: 0 user "
|
||||
"wasn't asked, 1: allowed, 2: "
|
||||
"not allowed") );
|
||||
|
||||
PARAM_PREFIX TimeUserConfigParam m_addons_last_updated
|
||||
PARAM_DEFAULT( TimeUserConfigParam(0, "addon_last_updated",
|
||||
&m_addon_group,
|
||||
|
@ -105,7 +105,7 @@ namespace GUIEngine
|
||||
static bool isADialogActive();
|
||||
|
||||
/** Override to change what happens on escape pressed */
|
||||
virtual void escapePressed() { dismiss(); }
|
||||
virtual bool onEscapePressed() { return true; }
|
||||
|
||||
/** Override to be notified of updates */
|
||||
virtual void onUpdate(float dt) { }
|
||||
|
@ -32,7 +32,6 @@ ScalableFont::ScalableFont(IGUIEnvironment *env, const io::path& filename)
|
||||
m_fallback_kerning_width = 0;
|
||||
m_fallback_font_scale = 1.0f;
|
||||
m_scale = 1.0f;
|
||||
m_tab_stop = 0.5f;
|
||||
m_is_hollow_copy = false;
|
||||
m_black_border = false;
|
||||
m_shadow = false;
|
||||
@ -500,15 +499,12 @@ void ScalableFont::draw(const core::stringw& text,
|
||||
core::position2d<s32> offset = position.UpperLeftCorner;
|
||||
core::dimension2d<s32> text_dimension;
|
||||
|
||||
// When we use the "tab" hack, disable right-alignment, it messes up everything
|
||||
bool has_tab = (text.findFirst(L'\t') != -1);
|
||||
|
||||
if ((m_rtl && !has_tab) || hcenter || vcenter || clip)
|
||||
if (m_rtl || hcenter || vcenter || clip)
|
||||
{
|
||||
text_dimension = getDimension(text.c_str());
|
||||
|
||||
if (hcenter) offset.X += (position.getWidth() - text_dimension.Width) / 2;
|
||||
else if (m_rtl && !has_tab) offset.X += (position.getWidth() - text_dimension.Width);
|
||||
if (hcenter) offset.X += (position.getWidth() - text_dimension.Width) / 2;
|
||||
else if (m_rtl) offset.X += (position.getWidth() - text_dimension.Width);
|
||||
|
||||
if (vcenter) offset.Y += (position.getHeight() - text_dimension.Height) / 2;
|
||||
if (clip)
|
||||
@ -519,14 +515,6 @@ void ScalableFont::draw(const core::stringw& text,
|
||||
}
|
||||
}
|
||||
|
||||
if (m_rtl && has_tab)
|
||||
{
|
||||
const int where = text.findFirst(L'\t');
|
||||
core::stringw substr = text.subString(0, where-1);
|
||||
text_dimension = getDimension(substr.c_str()) + getDimension(L"XX");
|
||||
offset.X += (int)(position.getWidth()*m_tab_stop-text_dimension.Width);
|
||||
}
|
||||
|
||||
// ---- collect character locations
|
||||
const unsigned int text_size = text.size();
|
||||
core::array<s32> indices(text_size);
|
||||
@ -537,14 +525,6 @@ void ScalableFont::draw(const core::stringw& text,
|
||||
{
|
||||
wchar_t c = text[i];
|
||||
|
||||
//hack: one tab character is supported, it moves the cursor to the tab stop
|
||||
if (c == L'\t')
|
||||
{
|
||||
offset.X = (int)(position.UpperLeftCorner.X +
|
||||
position.getWidth()*m_tab_stop);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (c == L'\r' || // Windows breaks
|
||||
c == L'\n' ) // Unix breaks
|
||||
{
|
||||
|
@ -61,9 +61,6 @@ class ScalableFont : public IGUIFontBitmap
|
||||
bool m_is_hollow_copy;
|
||||
bool m_rtl;
|
||||
|
||||
/** Position in range [0..1] of the single tab stop we support */
|
||||
float m_tab_stop;
|
||||
|
||||
public:
|
||||
|
||||
LEAK_CHECK()
|
||||
@ -145,9 +142,6 @@ public:
|
||||
|
||||
void updateRTL();
|
||||
|
||||
/** \param pos position of the tab stop, in range [0..1] */
|
||||
void setTabStop(float pos) { m_tab_stop = pos; }
|
||||
|
||||
private:
|
||||
|
||||
struct SFontArea
|
||||
|
@ -327,6 +327,15 @@ bool Widget::isVisible() const
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
bool Widget::isActivated() const
|
||||
{
|
||||
if (isVisible())
|
||||
return !m_deactivated;
|
||||
return false;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void Widget::setVisible(bool visible)
|
||||
{
|
||||
if (m_element != NULL)
|
||||
|
@ -326,6 +326,8 @@ namespace GUIEngine
|
||||
/** Returns if the element is visible. */
|
||||
bool isVisible() const;
|
||||
|
||||
bool isActivated() const;
|
||||
|
||||
/**
|
||||
* Call to resize/move the widget. Not all widgets can resize gracefully.
|
||||
*/
|
||||
|
757
src/guiengine/widgets/CGUISTKListBox.cpp
Normal file
757
src/guiengine/widgets/CGUISTKListBox.cpp
Normal file
@ -0,0 +1,757 @@
|
||||
// Copyright (C) 2002-2012 Nikolaus Gebhardt
|
||||
// 2013 Glenn De Jonghe
|
||||
// This file is part of the "Irrlicht Engine".
|
||||
// For conditions of distribution and use, see copyright notice in irrlicht.h
|
||||
|
||||
#include "guiengine/widgets/CGUISTKListBox.h"
|
||||
|
||||
#include "IGUISkin.h"
|
||||
#include "IGUIEnvironment.h"
|
||||
#include "IVideoDriver.h"
|
||||
#include "IGUIFont.h"
|
||||
#include "IGUISpriteBank.h"
|
||||
#include "CGUIScrollBar.h"
|
||||
//#include "os.h"
|
||||
#include "utils/time.hpp"
|
||||
|
||||
|
||||
namespace irr
|
||||
{
|
||||
namespace gui
|
||||
{
|
||||
|
||||
//! constructor
|
||||
CGUISTKListBox::CGUISTKListBox(IGUIEnvironment* environment, IGUIElement* parent,
|
||||
s32 id, core::rect<s32> rectangle, bool clip,
|
||||
bool drawBack, bool moveOverSelect)
|
||||
: IGUIElement(EGUIET_LIST_BOX, environment, parent, id, rectangle), Selected(-1),
|
||||
ItemHeight(0),ItemHeightOverride(0),
|
||||
TotalItemHeight(0), ItemsIconWidth(0), Font(0), IconBank(0),
|
||||
ScrollBar(0), selectTime(0), LastKeyTime(0), Selecting(false), DrawBack(drawBack),
|
||||
MoveOverSelect(moveOverSelect), AutoScroll(true), HighlightWhenNotFocused(true)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
setDebugName("CGUISTKListBox");
|
||||
#endif
|
||||
|
||||
IGUISkin* skin = Environment->getSkin();
|
||||
const s32 s = skin->getSize(EGDS_SCROLLBAR_SIZE);
|
||||
|
||||
ScrollBar = new CGUIScrollBar(false, Environment, this, -1,
|
||||
core::rect<s32>(RelativeRect.getWidth() - s, 0, RelativeRect.getWidth(), RelativeRect.getHeight()),
|
||||
!clip);
|
||||
ScrollBar->setSubElement(true);
|
||||
ScrollBar->setTabStop(false);
|
||||
ScrollBar->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT);
|
||||
ScrollBar->setVisible(false);
|
||||
ScrollBar->setPos(0);
|
||||
|
||||
setNotClipped(!clip);
|
||||
|
||||
// this element can be tabbed to
|
||||
setTabStop(true);
|
||||
setTabOrder(-1);
|
||||
|
||||
updateAbsolutePosition();
|
||||
}
|
||||
|
||||
|
||||
//! destructor
|
||||
CGUISTKListBox::~CGUISTKListBox()
|
||||
{
|
||||
if (ScrollBar)
|
||||
ScrollBar->drop();
|
||||
|
||||
if (Font)
|
||||
Font->drop();
|
||||
|
||||
if (IconBank)
|
||||
IconBank->drop();
|
||||
}
|
||||
|
||||
|
||||
//! returns amount of list items
|
||||
u32 CGUISTKListBox::getItemCount() const
|
||||
{
|
||||
return Items.size();
|
||||
}
|
||||
|
||||
|
||||
|
||||
const wchar_t* CGUISTKListBox::getCellText(u32 row_num, u32 col_num) const
|
||||
{
|
||||
if ( row_num >= Items.size() )
|
||||
return 0;
|
||||
if ( col_num >= Items[row_num].m_contents.size() )
|
||||
return 0;
|
||||
return Items[row_num].m_contents[col_num].m_text.c_str();
|
||||
}
|
||||
|
||||
CGUISTKListBox::ListItem CGUISTKListBox::getItem(u32 id) const
|
||||
{
|
||||
return Items[id];
|
||||
}
|
||||
|
||||
|
||||
//! Returns the icon of an item
|
||||
s32 CGUISTKListBox::getIcon(u32 row_num, u32 col_num) const
|
||||
{
|
||||
if ( row_num >= Items.size() )
|
||||
return -1;
|
||||
if ( col_num >= Items[row_num].m_contents.size() )
|
||||
return -1;
|
||||
return Items[row_num].m_contents[col_num].m_icon;
|
||||
}
|
||||
|
||||
void CGUISTKListBox::removeItem(u32 id)
|
||||
{
|
||||
if (id >= Items.size())
|
||||
return;
|
||||
|
||||
if ((u32)Selected==id)
|
||||
{
|
||||
Selected = -1;
|
||||
}
|
||||
else if ((u32)Selected > id)
|
||||
{
|
||||
Selected -= 1;
|
||||
selectTime = Time::getTimeSinceEpoch();
|
||||
}
|
||||
|
||||
Items.erase(id);
|
||||
|
||||
recalculateItemHeight();
|
||||
}
|
||||
|
||||
|
||||
s32 CGUISTKListBox::getItemAt(s32 xpos, s32 ypos) const
|
||||
{
|
||||
if ( xpos < AbsoluteRect.UpperLeftCorner.X || xpos >= AbsoluteRect.LowerRightCorner.X
|
||||
|| ypos < AbsoluteRect.UpperLeftCorner.Y || ypos >= AbsoluteRect.LowerRightCorner.Y
|
||||
)
|
||||
return -1;
|
||||
|
||||
if ( ItemHeight == 0 )
|
||||
return -1;
|
||||
|
||||
s32 item = ((ypos - AbsoluteRect.UpperLeftCorner.Y - 1) + ScrollBar->getPos()) / ItemHeight;
|
||||
if ( item < 0 || item >= (s32)Items.size())
|
||||
return -1;
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
//! clears the list
|
||||
void CGUISTKListBox::clear()
|
||||
{
|
||||
Items.clear();
|
||||
ItemsIconWidth = 0;
|
||||
Selected = -1;
|
||||
|
||||
if (ScrollBar)
|
||||
ScrollBar->setPos(0);
|
||||
|
||||
recalculateItemHeight();
|
||||
}
|
||||
|
||||
|
||||
void CGUISTKListBox::recalculateItemHeight()
|
||||
{
|
||||
IGUISkin* skin = Environment->getSkin();
|
||||
|
||||
if (Font != skin->getFont())
|
||||
{
|
||||
if (Font)
|
||||
Font->drop();
|
||||
|
||||
Font = skin->getFont();
|
||||
if ( 0 == ItemHeightOverride )
|
||||
ItemHeight = 0;
|
||||
|
||||
if (Font)
|
||||
{
|
||||
if ( 0 == ItemHeightOverride )
|
||||
ItemHeight = Font->getDimension(L"A").Height + 4;
|
||||
|
||||
Font->grab();
|
||||
}
|
||||
}
|
||||
|
||||
TotalItemHeight = ItemHeight * Items.size();
|
||||
ScrollBar->setMax( core::max_(0, TotalItemHeight - AbsoluteRect.getHeight()) );
|
||||
s32 minItemHeight = ItemHeight > 0 ? ItemHeight : 1;
|
||||
ScrollBar->setSmallStep ( minItemHeight );
|
||||
ScrollBar->setLargeStep ( 2*minItemHeight );
|
||||
|
||||
if ( TotalItemHeight <= AbsoluteRect.getHeight() )
|
||||
ScrollBar->setVisible(false);
|
||||
else
|
||||
ScrollBar->setVisible(true);
|
||||
}
|
||||
|
||||
|
||||
//! returns id of selected item. returns -1 if no item is selected.
|
||||
s32 CGUISTKListBox::getSelected() const
|
||||
{
|
||||
return Selected;
|
||||
}
|
||||
|
||||
|
||||
//! sets the selected item. Set this to -1 if no item should be selected
|
||||
void CGUISTKListBox::setSelected(s32 id)
|
||||
{
|
||||
if ((u32)id>=Items.size())
|
||||
Selected = -1;
|
||||
else
|
||||
Selected = id;
|
||||
|
||||
selectTime = Time::getTimeSinceEpoch();
|
||||
|
||||
recalculateScrollPos();
|
||||
}
|
||||
|
||||
s32 CGUISTKListBox::getRowByCellText(const wchar_t * text)
|
||||
{
|
||||
s32 row_index = -1;
|
||||
s32 col_index = -1;
|
||||
if (text)
|
||||
{
|
||||
for ( row_index = 0; row_index < (s32) Items.size(); ++row_index )
|
||||
{
|
||||
for ( col_index = 0; col_index < (s32) Items[row_index].m_contents.size(); ++col_index )
|
||||
{
|
||||
if ( Items[row_index].m_contents[col_index].m_text == text ) return row_index;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
//! sets the selected item. Set this to -1 if no item should be selected
|
||||
void CGUISTKListBox::setSelectedByCellText(const wchar_t * text)
|
||||
{
|
||||
setSelected(getRowByCellText(text));
|
||||
}
|
||||
|
||||
s32 CGUISTKListBox::getRowByInternalName(const std::string & text) const
|
||||
{
|
||||
s32 row_index = -1;
|
||||
if (text != "")
|
||||
{
|
||||
for ( row_index = 0; row_index < (s32) Items.size(); ++row_index )
|
||||
{
|
||||
if (Items[row_index].m_internal_name == text) return row_index;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
//! called if an event happened.
|
||||
bool CGUISTKListBox::OnEvent(const SEvent& event)
|
||||
{
|
||||
if (isEnabled())
|
||||
{
|
||||
switch(event.EventType)
|
||||
{
|
||||
case EET_KEY_INPUT_EVENT:
|
||||
if (event.KeyInput.PressedDown &&
|
||||
(event.KeyInput.Key == KEY_DOWN ||
|
||||
event.KeyInput.Key == KEY_UP ||
|
||||
event.KeyInput.Key == KEY_HOME ||
|
||||
event.KeyInput.Key == KEY_END ||
|
||||
event.KeyInput.Key == KEY_NEXT ||
|
||||
event.KeyInput.Key == KEY_PRIOR ) )
|
||||
{
|
||||
s32 oldSelected = Selected;
|
||||
switch (event.KeyInput.Key)
|
||||
{
|
||||
case KEY_DOWN:
|
||||
Selected += 1;
|
||||
break;
|
||||
case KEY_UP:
|
||||
Selected -= 1;
|
||||
break;
|
||||
case KEY_HOME:
|
||||
Selected = 0;
|
||||
break;
|
||||
case KEY_END:
|
||||
Selected = (s32)Items.size()-1;
|
||||
break;
|
||||
case KEY_NEXT:
|
||||
Selected += AbsoluteRect.getHeight() / ItemHeight;
|
||||
break;
|
||||
case KEY_PRIOR:
|
||||
Selected -= AbsoluteRect.getHeight() / ItemHeight;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (Selected >= (s32)Items.size())
|
||||
Selected = Items.size() - 1;
|
||||
else
|
||||
if (Selected<0)
|
||||
Selected = 0;
|
||||
|
||||
recalculateScrollPos();
|
||||
|
||||
// post the news
|
||||
|
||||
if (oldSelected != Selected && Parent && !Selecting && !MoveOverSelect)
|
||||
{
|
||||
SEvent e;
|
||||
e.EventType = EET_GUI_EVENT;
|
||||
e.GUIEvent.Caller = this;
|
||||
e.GUIEvent.Element = 0;
|
||||
e.GUIEvent.EventType = EGET_LISTBOX_CHANGED;
|
||||
Parent->OnEvent(e);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
if (!event.KeyInput.PressedDown && ( event.KeyInput.Key == KEY_RETURN || event.KeyInput.Key == KEY_SPACE ) )
|
||||
{
|
||||
if (Parent)
|
||||
{
|
||||
SEvent e;
|
||||
e.EventType = EET_GUI_EVENT;
|
||||
e.GUIEvent.Caller = this;
|
||||
e.GUIEvent.Element = 0;
|
||||
e.GUIEvent.EventType = EGET_LISTBOX_SELECTED_AGAIN;
|
||||
Parent->OnEvent(e);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
||||
case EET_GUI_EVENT:
|
||||
switch(event.GUIEvent.EventType)
|
||||
{
|
||||
case gui::EGET_SCROLL_BAR_CHANGED:
|
||||
if (event.GUIEvent.Caller == ScrollBar)
|
||||
return true;
|
||||
break;
|
||||
case gui::EGET_ELEMENT_FOCUS_LOST:
|
||||
{
|
||||
if (event.GUIEvent.Caller == this)
|
||||
Selecting = false;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case EET_MOUSE_INPUT_EVENT:
|
||||
{
|
||||
core::position2d<s32> p(event.MouseInput.X, event.MouseInput.Y);
|
||||
|
||||
switch(event.MouseInput.Event)
|
||||
{
|
||||
case EMIE_MOUSE_WHEEL:
|
||||
ScrollBar->setPos(ScrollBar->getPos() + (event.MouseInput.Wheel < 0 ? -1 : 1)*-ItemHeight/2);
|
||||
return true;
|
||||
|
||||
case EMIE_LMOUSE_PRESSED_DOWN:
|
||||
{
|
||||
Selecting = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
case EMIE_LMOUSE_LEFT_UP:
|
||||
{
|
||||
Selecting = false;
|
||||
|
||||
if (isPointInside(p))
|
||||
selectNew(event.MouseInput.Y);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
case EMIE_MOUSE_MOVED:
|
||||
if (Selecting || MoveOverSelect)
|
||||
{
|
||||
if (isPointInside(p))
|
||||
{
|
||||
selectNew(event.MouseInput.Y, true);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case EET_LOG_TEXT_EVENT:
|
||||
case EET_USER_EVENT:
|
||||
case EET_JOYSTICK_INPUT_EVENT:
|
||||
case EGUIET_FORCE_32_BIT:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return IGUIElement::OnEvent(event);
|
||||
}
|
||||
|
||||
|
||||
void CGUISTKListBox::selectNew(s32 ypos, bool onlyHover)
|
||||
{
|
||||
u32 now = Time::getTimeSinceEpoch();
|
||||
s32 oldSelected = Selected;
|
||||
|
||||
Selected = getItemAt(AbsoluteRect.UpperLeftCorner.X, ypos);
|
||||
if (Selected<0 && !Items.empty())
|
||||
Selected = 0;
|
||||
|
||||
recalculateScrollPos();
|
||||
|
||||
gui::EGUI_EVENT_TYPE eventType = (Selected == oldSelected && now < selectTime + 500) ? EGET_LISTBOX_SELECTED_AGAIN : EGET_LISTBOX_CHANGED;
|
||||
selectTime = now;
|
||||
// post the news
|
||||
if (Parent && !onlyHover)
|
||||
{
|
||||
SEvent event;
|
||||
event.EventType = EET_GUI_EVENT;
|
||||
event.GUIEvent.Caller = this;
|
||||
event.GUIEvent.Element = 0;
|
||||
event.GUIEvent.EventType = eventType;
|
||||
Parent->OnEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//! Update the position and size of the listbox, and update the scrollbar
|
||||
void CGUISTKListBox::updateAbsolutePosition()
|
||||
{
|
||||
IGUIElement::updateAbsolutePosition();
|
||||
|
||||
recalculateItemHeight();
|
||||
}
|
||||
|
||||
|
||||
//! draws the element and its children
|
||||
void CGUISTKListBox::draw()
|
||||
{
|
||||
if (!IsVisible)
|
||||
return;
|
||||
|
||||
recalculateItemHeight(); // if the font changed
|
||||
|
||||
IGUISkin* skin = Environment->getSkin();
|
||||
|
||||
core::rect<s32>* clipRect = 0;
|
||||
|
||||
// draw background
|
||||
core::rect<s32> frameRect(AbsoluteRect);
|
||||
|
||||
// draw items
|
||||
|
||||
core::rect<s32> clientClip(AbsoluteRect);
|
||||
clientClip.UpperLeftCorner.Y += 1;
|
||||
clientClip.UpperLeftCorner.X += 1;
|
||||
if (ScrollBar->isVisible())
|
||||
clientClip.LowerRightCorner.X = AbsoluteRect.LowerRightCorner.X - skin->getSize(EGDS_SCROLLBAR_SIZE);
|
||||
clientClip.LowerRightCorner.Y -= 1;
|
||||
clientClip.clipAgainst(AbsoluteClippingRect);
|
||||
|
||||
skin->draw3DSunkenPane(this, skin->getColor(EGDC_3D_HIGH_LIGHT), true,
|
||||
DrawBack, frameRect, &clientClip);
|
||||
|
||||
if (clipRect)
|
||||
clientClip.clipAgainst(*clipRect);
|
||||
|
||||
frameRect = AbsoluteRect;
|
||||
frameRect.UpperLeftCorner.X += 1;
|
||||
if (ScrollBar->isVisible())
|
||||
frameRect.LowerRightCorner.X = AbsoluteRect.LowerRightCorner.X - skin->getSize(EGDS_SCROLLBAR_SIZE);
|
||||
|
||||
frameRect.LowerRightCorner.Y = AbsoluteRect.UpperLeftCorner.Y + ItemHeight;
|
||||
|
||||
frameRect.UpperLeftCorner.Y -= ScrollBar->getPos();
|
||||
frameRect.LowerRightCorner.Y -= ScrollBar->getPos();
|
||||
|
||||
bool hl = (HighlightWhenNotFocused || Environment->hasFocus(this) || Environment->hasFocus(ScrollBar));
|
||||
|
||||
for (s32 i=0; i<(s32)Items.size(); ++i)
|
||||
{
|
||||
if (frameRect.LowerRightCorner.Y >= AbsoluteRect.UpperLeftCorner.Y &&
|
||||
frameRect.UpperLeftCorner.Y <= AbsoluteRect.LowerRightCorner.Y)
|
||||
{
|
||||
if (i == Selected && hl)
|
||||
skin->draw2DRectangle(this, skin->getColor(EGDC_HIGH_LIGHT), frameRect, &clientClip);
|
||||
|
||||
core::rect<s32> textRect = frameRect;
|
||||
|
||||
if (Font)
|
||||
{
|
||||
int total_proportion = 0;
|
||||
for(int x = 0; x < Items[i].m_contents.size(); ++x)
|
||||
{
|
||||
total_proportion += Items[i].m_contents[x].m_proportion;
|
||||
}
|
||||
int part_size = (int)(textRect.getWidth() / float(total_proportion));
|
||||
|
||||
for(int x = 0; x < Items[i].m_contents.size(); ++x)
|
||||
{
|
||||
textRect.LowerRightCorner.X = textRect.UpperLeftCorner.X +
|
||||
(Items[i].m_contents[x].m_proportion * part_size);
|
||||
textRect.UpperLeftCorner.X += 3;
|
||||
|
||||
if (IconBank && (Items[i].m_contents[x].m_icon > -1))
|
||||
{
|
||||
core::position2di iconPos = textRect.UpperLeftCorner;
|
||||
iconPos.Y += textRect.getHeight() / 2;
|
||||
iconPos.X += ItemsIconWidth/2;
|
||||
|
||||
if ( i==Selected && hl )
|
||||
{
|
||||
IconBank->draw2DSprite(
|
||||
(u32)Items[i].m_contents[x].m_icon,
|
||||
iconPos, &clientClip,
|
||||
hasItemOverrideColor(i, EGUI_LBC_ICON_HIGHLIGHT) ?
|
||||
getItemOverrideColor(i, EGUI_LBC_ICON_HIGHLIGHT) : getItemDefaultColor(EGUI_LBC_ICON_HIGHLIGHT),
|
||||
selectTime, Time::getTimeSinceEpoch(), false, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
IconBank->draw2DSprite(
|
||||
(u32)Items[i].m_contents[x].m_icon,
|
||||
iconPos,
|
||||
&clientClip,
|
||||
hasItemOverrideColor(i, EGUI_LBC_ICON) ? getItemOverrideColor(i, EGUI_LBC_ICON) : getItemDefaultColor(EGUI_LBC_ICON),
|
||||
0 , (i==Selected) ? Time::getTimeSinceEpoch() : 0, false, true);
|
||||
}
|
||||
textRect.UpperLeftCorner.X += ItemsIconWidth;
|
||||
}
|
||||
|
||||
textRect.UpperLeftCorner.X += 3;
|
||||
|
||||
if ( i==Selected && hl )
|
||||
{
|
||||
Font->draw(
|
||||
Items[i].m_contents[x].m_text.c_str(),
|
||||
textRect,
|
||||
hasItemOverrideColor(i, EGUI_LBC_TEXT_HIGHLIGHT) ?
|
||||
getItemOverrideColor(i, EGUI_LBC_TEXT_HIGHLIGHT) : getItemDefaultColor(EGUI_LBC_TEXT_HIGHLIGHT),
|
||||
Items[i].m_contents[x].m_center, true, &clientClip);
|
||||
}
|
||||
else
|
||||
{
|
||||
Font->draw(
|
||||
Items[i].m_contents[x].m_text.c_str(),
|
||||
textRect,
|
||||
hasItemOverrideColor(i, EGUI_LBC_TEXT) ? getItemOverrideColor(i, EGUI_LBC_TEXT) : getItemDefaultColor(EGUI_LBC_TEXT),
|
||||
Items[i].m_contents[x].m_center, true, &clientClip);
|
||||
}
|
||||
//Position back to inital pos
|
||||
textRect.UpperLeftCorner.X -= ItemsIconWidth+6;
|
||||
//Calculate new beginning
|
||||
textRect.UpperLeftCorner.X += Items[i].m_contents[x].m_proportion * part_size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
frameRect.UpperLeftCorner.Y += ItemHeight;
|
||||
frameRect.LowerRightCorner.Y += ItemHeight;
|
||||
}
|
||||
|
||||
IGUIElement::draw();
|
||||
}
|
||||
|
||||
|
||||
//! adds an list item with an icon
|
||||
u32 CGUISTKListBox::addItem(const ListItem & item)
|
||||
{
|
||||
Items.push_back(item);
|
||||
recalculateItemHeight();
|
||||
recalculateIconWidth();
|
||||
return Items.size() - 1;
|
||||
}
|
||||
|
||||
|
||||
void CGUISTKListBox::setSpriteBank(IGUISpriteBank* bank)
|
||||
{
|
||||
if ( bank == IconBank )
|
||||
return;
|
||||
if (IconBank)
|
||||
IconBank->drop();
|
||||
|
||||
IconBank = bank;
|
||||
if (IconBank)
|
||||
IconBank->grab();
|
||||
}
|
||||
|
||||
|
||||
void CGUISTKListBox::recalculateScrollPos()
|
||||
{
|
||||
if (!AutoScroll)
|
||||
return;
|
||||
|
||||
const s32 selPos = (Selected == -1 ? TotalItemHeight : Selected * ItemHeight) - ScrollBar->getPos();
|
||||
|
||||
if (selPos < 0)
|
||||
{
|
||||
ScrollBar->setPos(ScrollBar->getPos() + selPos);
|
||||
}
|
||||
else
|
||||
if (selPos > AbsoluteRect.getHeight() - ItemHeight)
|
||||
{
|
||||
ScrollBar->setPos(ScrollBar->getPos() + selPos - AbsoluteRect.getHeight() + ItemHeight);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CGUISTKListBox::setAutoScrollEnabled(bool scroll)
|
||||
{
|
||||
AutoScroll = scroll;
|
||||
}
|
||||
|
||||
|
||||
bool CGUISTKListBox::isAutoScrollEnabled() const
|
||||
{
|
||||
_IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
|
||||
return AutoScroll;
|
||||
}
|
||||
|
||||
void CGUISTKListBox::recalculateIconWidth()
|
||||
{
|
||||
for(int x = 0; x < (int)Items.getLast().m_contents.size(); ++x)
|
||||
{
|
||||
s32 icon = Items.getLast().m_contents[x].m_icon;
|
||||
if (IconBank && icon > -1 &&
|
||||
IconBank->getSprites().size() > (u32)icon &&
|
||||
IconBank->getSprites()[(u32)icon].Frames.size())
|
||||
{
|
||||
u32 rno = IconBank->getSprites()[(u32)icon].Frames[0].rectNumber;
|
||||
if (IconBank->getPositions().size() > rno)
|
||||
{
|
||||
const s32 w = IconBank->getPositions()[rno].getWidth();
|
||||
if (w > ItemsIconWidth)
|
||||
ItemsIconWidth = w;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CGUISTKListBox::setCell(u32 row_num, u32 col_num, const wchar_t* text, s32 icon)
|
||||
{
|
||||
if ( row_num >= Items.size() )
|
||||
return;
|
||||
if ( col_num >= Items[row_num].m_contents.size() )
|
||||
return;
|
||||
Items[row_num].m_contents[col_num].m_text = text;
|
||||
Items[row_num].m_contents[col_num].m_icon = icon;
|
||||
|
||||
recalculateItemHeight();
|
||||
recalculateIconWidth();
|
||||
}
|
||||
|
||||
void CGUISTKListBox::swapItems(u32 index1, u32 index2)
|
||||
{
|
||||
if ( index1 >= Items.size() || index2 >= Items.size() )
|
||||
return;
|
||||
|
||||
ListItem dummmy = Items[index1];
|
||||
Items[index1] = Items[index2];
|
||||
Items[index2] = dummmy;
|
||||
}
|
||||
|
||||
|
||||
void CGUISTKListBox::setItemOverrideColor(u32 index, video::SColor color)
|
||||
{
|
||||
for ( u32 c=0; c < EGUI_LBC_COUNT; ++c )
|
||||
{
|
||||
Items[index].OverrideColors[c].Use = true;
|
||||
Items[index].OverrideColors[c].Color = color;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CGUISTKListBox::setItemOverrideColor(u32 index, EGUI_LISTBOX_COLOR colorType, video::SColor color)
|
||||
{
|
||||
if ( index >= Items.size() || colorType < 0 || colorType >= EGUI_LBC_COUNT )
|
||||
return;
|
||||
|
||||
Items[index].OverrideColors[colorType].Use = true;
|
||||
Items[index].OverrideColors[colorType].Color = color;
|
||||
}
|
||||
|
||||
|
||||
void CGUISTKListBox::clearItemOverrideColor(u32 index)
|
||||
{
|
||||
for (u32 c=0; c < (u32)EGUI_LBC_COUNT; ++c )
|
||||
{
|
||||
Items[index].OverrideColors[c].Use = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CGUISTKListBox::clearItemOverrideColor(u32 index, EGUI_LISTBOX_COLOR colorType)
|
||||
{
|
||||
if ( index >= Items.size() || colorType < 0 || colorType >= EGUI_LBC_COUNT )
|
||||
return;
|
||||
|
||||
Items[index].OverrideColors[colorType].Use = false;
|
||||
}
|
||||
|
||||
|
||||
bool CGUISTKListBox::hasItemOverrideColor(u32 index, EGUI_LISTBOX_COLOR colorType) const
|
||||
{
|
||||
if ( index >= Items.size() || colorType < 0 || colorType >= EGUI_LBC_COUNT )
|
||||
return false;
|
||||
|
||||
return Items[index].OverrideColors[colorType].Use;
|
||||
}
|
||||
|
||||
|
||||
video::SColor CGUISTKListBox::getItemOverrideColor(u32 index, EGUI_LISTBOX_COLOR colorType) const
|
||||
{
|
||||
if ( (u32)index >= Items.size() || colorType < 0 || colorType >= EGUI_LBC_COUNT )
|
||||
return video::SColor();
|
||||
|
||||
return Items[index].OverrideColors[colorType].Color;
|
||||
}
|
||||
|
||||
|
||||
video::SColor CGUISTKListBox::getItemDefaultColor(EGUI_LISTBOX_COLOR colorType) const
|
||||
{
|
||||
IGUISkin* skin = Environment->getSkin();
|
||||
if ( !skin )
|
||||
return video::SColor();
|
||||
|
||||
switch ( colorType )
|
||||
{
|
||||
case EGUI_LBC_TEXT:
|
||||
return skin->getColor(EGDC_BUTTON_TEXT);
|
||||
case EGUI_LBC_TEXT_HIGHLIGHT:
|
||||
return skin->getColor(EGDC_HIGH_LIGHT_TEXT);
|
||||
case EGUI_LBC_ICON:
|
||||
return skin->getColor(EGDC_ICON);
|
||||
case EGUI_LBC_ICON_HIGHLIGHT:
|
||||
return skin->getColor(EGDC_ICON_HIGH_LIGHT);
|
||||
default:
|
||||
return video::SColor();
|
||||
}
|
||||
}
|
||||
|
||||
//! set global itemHeight
|
||||
void CGUISTKListBox::setItemHeight( s32 height )
|
||||
{
|
||||
ItemHeight = height;
|
||||
ItemHeightOverride = 1;
|
||||
}
|
||||
|
||||
|
||||
//! Sets whether to draw the background
|
||||
void CGUISTKListBox::setDrawBackground(bool draw)
|
||||
{
|
||||
DrawBack = draw;
|
||||
}
|
||||
|
||||
|
||||
} // end namespace gui
|
||||
} // end namespace irr
|
||||
|
||||
|
198
src/guiengine/widgets/CGUISTKListBox.h
Normal file
198
src/guiengine/widgets/CGUISTKListBox.h
Normal file
@ -0,0 +1,198 @@
|
||||
// Copyright (C) 2002-2012 Nikolaus Gebhardt
|
||||
// 2013 Glenn De Jonghe
|
||||
// This file is part of the "Irrlicht Engine".
|
||||
// For conditions of distribution and use, see copyright notice in irrlicht.h
|
||||
|
||||
#ifndef HEADER_CGUISTKListBox_HPP
|
||||
#define HEADER_CGUISTKListBox_HPP
|
||||
|
||||
#include "IrrCompileConfig.h"
|
||||
|
||||
#include "IGUIListBox.h"
|
||||
#include "IGUIElement.h"
|
||||
#include "irrArray.h"
|
||||
#include <string>
|
||||
|
||||
namespace irr
|
||||
{
|
||||
namespace gui
|
||||
{
|
||||
class IGUIFont;
|
||||
class IGUIScrollBar;
|
||||
|
||||
class CGUISTKListBox : public IGUIElement
|
||||
{
|
||||
public:
|
||||
|
||||
struct ListItem
|
||||
{
|
||||
|
||||
struct ListCell
|
||||
{
|
||||
irr::core::stringw m_text;
|
||||
int m_proportion;
|
||||
s32 m_icon;
|
||||
bool m_center;
|
||||
|
||||
ListCell(irr::core::stringw text, s32 icon = -1, int proportion = 1, bool center = false)
|
||||
{
|
||||
m_text = text;
|
||||
m_proportion = proportion;
|
||||
m_icon = icon;
|
||||
m_center = center;
|
||||
}
|
||||
};
|
||||
|
||||
core::array< ListCell > m_contents;
|
||||
|
||||
// Actually only used in list_widget -- still refactoring FIXME
|
||||
std::string m_internal_name;
|
||||
int m_current_id;
|
||||
|
||||
// A multicolor extension
|
||||
struct ListItemOverrideColor
|
||||
{
|
||||
ListItemOverrideColor() : Use(false) {}
|
||||
bool Use;
|
||||
video::SColor Color;
|
||||
};
|
||||
|
||||
ListItemOverrideColor OverrideColors[EGUI_LBC_COUNT];
|
||||
};
|
||||
|
||||
//! constructor
|
||||
CGUISTKListBox(IGUIEnvironment* environment, IGUIElement* parent,
|
||||
s32 id, core::rect<s32> rectangle, bool clip=true,
|
||||
bool drawBack=false, bool moveOverSelect=false);
|
||||
|
||||
//! destructor
|
||||
virtual ~CGUISTKListBox();
|
||||
|
||||
//! returns amount of list items
|
||||
virtual u32 getItemCount() const;
|
||||
|
||||
virtual const wchar_t* getCellText(u32 row_num, u32 col_num) const;
|
||||
|
||||
virtual ListItem getItem(u32 id) const;
|
||||
|
||||
//! clears the list
|
||||
virtual void clear();
|
||||
|
||||
//! returns id of selected item. returns -1 if no item is selected.
|
||||
virtual s32 getSelected() const;
|
||||
|
||||
//! sets the selected item. Set this to -1 if no item should be selected
|
||||
virtual void setSelected(s32 id);
|
||||
|
||||
virtual s32 getRowByCellText(const wchar_t * text);
|
||||
|
||||
//! sets the selected item. Set this to -1 if no item should be selected
|
||||
virtual void setSelectedByCellText(const wchar_t * text);
|
||||
|
||||
virtual s32 getRowByInternalName(const std::string & text) const;
|
||||
|
||||
//! called if an event happened.
|
||||
virtual bool OnEvent(const SEvent& event);
|
||||
|
||||
//! draws the element and its children
|
||||
virtual void draw();
|
||||
|
||||
//! adds an list item with an icon
|
||||
//! \param text Text of list entry
|
||||
//! \param icon Sprite index of the Icon within the current sprite bank. Set it to -1 if you want no icon
|
||||
//! \return
|
||||
//! returns the id of the new created item
|
||||
//virtual u32 addItem(const wchar_t* text, s32 icon);
|
||||
|
||||
virtual u32 addItem(const ListItem & item);
|
||||
|
||||
//! Returns the icon of an item
|
||||
virtual s32 getIcon(u32 row_num, u32 col_num) const;
|
||||
|
||||
//! removes an item from the list
|
||||
virtual void removeItem(u32 id);
|
||||
|
||||
//! get the the id of the item at the given absolute coordinates
|
||||
virtual s32 getItemAt(s32 xpos, s32 ypos) const;
|
||||
|
||||
//! Sets the sprite bank which should be used to draw list icons. This font is set to the sprite bank of
|
||||
//! the built-in-font by default. A sprite can be displayed in front of every list item.
|
||||
//! An icon is an index within the icon sprite bank. Several default icons are available in the
|
||||
//! skin through getIcon
|
||||
virtual void setSpriteBank(IGUISpriteBank* bank);
|
||||
|
||||
//! set whether the listbox should scroll to newly selected items
|
||||
virtual void setAutoScrollEnabled(bool scroll);
|
||||
|
||||
//! returns true if automatic scrolling is enabled, false if not.
|
||||
virtual bool isAutoScrollEnabled() const;
|
||||
|
||||
//! Update the position and size of the listbox, and update the scrollbar
|
||||
virtual void updateAbsolutePosition();
|
||||
|
||||
//! set all item colors at given index to color
|
||||
virtual void setItemOverrideColor(u32 index, video::SColor color);
|
||||
|
||||
//! set all item colors of specified type at given index to color
|
||||
virtual void setItemOverrideColor(u32 index, EGUI_LISTBOX_COLOR colorType, video::SColor color);
|
||||
|
||||
//! clear all item colors at index
|
||||
virtual void clearItemOverrideColor(u32 index);
|
||||
|
||||
//! clear item color at index for given colortype
|
||||
virtual void clearItemOverrideColor(u32 index, EGUI_LISTBOX_COLOR colorType);
|
||||
|
||||
//! has the item at index its color overwritten?
|
||||
virtual bool hasItemOverrideColor(u32 index, EGUI_LISTBOX_COLOR colorType) const;
|
||||
|
||||
//! return the overwrite color at given item index.
|
||||
virtual video::SColor getItemOverrideColor(u32 index, EGUI_LISTBOX_COLOR colorType) const;
|
||||
|
||||
//! return the default color which is used for the given colorType
|
||||
virtual video::SColor getItemDefaultColor(EGUI_LISTBOX_COLOR colorType) const;
|
||||
|
||||
//! set the item at the given index
|
||||
virtual void setCell(u32 row_num, u32 col_num, const wchar_t* text, s32 icon);
|
||||
|
||||
//! Swap the items at the given indices
|
||||
virtual void swapItems(u32 index1, u32 index2);
|
||||
|
||||
//! set global itemHeight
|
||||
virtual void setItemHeight( s32 height );
|
||||
|
||||
//! Sets whether to draw the background
|
||||
virtual void setDrawBackground(bool draw);
|
||||
|
||||
private:
|
||||
|
||||
void recalculateItemHeight();
|
||||
void selectNew(s32 ypos, bool onlyHover=false);
|
||||
void recalculateScrollPos();
|
||||
|
||||
// extracted that function to avoid copy&paste code
|
||||
void recalculateIconWidth();
|
||||
|
||||
core::array< ListItem > Items;
|
||||
s32 Selected;
|
||||
s32 ItemHeight;
|
||||
s32 ItemHeightOverride;
|
||||
s32 TotalItemHeight;
|
||||
s32 ItemsIconWidth;
|
||||
gui::IGUIFont* Font;
|
||||
gui::IGUISpriteBank* IconBank;
|
||||
gui::IGUIScrollBar* ScrollBar;
|
||||
u32 selectTime;
|
||||
u32 LastKeyTime;
|
||||
core::stringw KeyBuffer;
|
||||
bool Selecting;
|
||||
bool DrawBack;
|
||||
bool MoveOverSelect;
|
||||
bool AutoScroll;
|
||||
bool HighlightWhenNotFocused;
|
||||
};
|
||||
|
||||
|
||||
} // end namespace gui
|
||||
} // end namespace irr
|
||||
|
||||
#endif
|
@ -39,15 +39,17 @@ using namespace irr;
|
||||
LabelWidget::LabelWidget(bool title, bool bright) : Widget(WTYPE_LABEL)
|
||||
{
|
||||
m_title_font = title;
|
||||
m_has_color = false;
|
||||
m_scroll_speed = 0;
|
||||
m_scroll_offset = 0;
|
||||
m_bright = bright;
|
||||
|
||||
if (bright)
|
||||
if (m_bright)
|
||||
{
|
||||
m_has_color = true;
|
||||
m_color = Skin::getColor("brighttext::neutral");
|
||||
}
|
||||
else
|
||||
m_has_color = false;
|
||||
} // LabelWidget
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -126,11 +128,11 @@ void LabelWidget::add()
|
||||
|
||||
void LabelWidget::setText(const wchar_t *text, bool expandIfNeeded)
|
||||
{
|
||||
assert(m_element != NULL);
|
||||
m_scroll_offset = 0;
|
||||
|
||||
if (expandIfNeeded)
|
||||
{
|
||||
assert(m_element != NULL);
|
||||
|
||||
const int fwidth = (m_title_font ? GUIEngine::getTitleFont() : GUIEngine::getFont())->getDimension(text).Width;
|
||||
core::rect<s32> rect = m_element->getRelativePosition();
|
||||
@ -173,7 +175,6 @@ bool LabelWidget::scrolledOff() const
|
||||
{
|
||||
// This method may only be called after this widget has been add()ed
|
||||
assert(m_element != NULL);
|
||||
|
||||
return m_scroll_offset <= -m_element->getAbsolutePosition().getWidth();
|
||||
}
|
||||
|
||||
@ -189,9 +190,34 @@ void LabelWidget::setScrollSpeed(float speed)
|
||||
|
||||
void LabelWidget::setColor(const irr::video::SColor& color)
|
||||
{
|
||||
assert(m_element != NULL);
|
||||
m_color = color;
|
||||
m_has_color = true;
|
||||
if (m_element != NULL)
|
||||
((IGUIStaticText*)m_element)->setOverrideColor(m_color);
|
||||
((IGUIStaticText*)m_element)->setOverrideColor(m_color);
|
||||
}
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void LabelWidget::setErrorColor()
|
||||
{
|
||||
setColor(irr::video::SColor(255, 255, 0, 0));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void LabelWidget::setDefaultColor()
|
||||
{
|
||||
if (m_bright)
|
||||
{
|
||||
setColor(Skin::getColor("brighttext::neutral"));
|
||||
}
|
||||
else
|
||||
{
|
||||
if(m_has_color)
|
||||
{
|
||||
assert(m_element != NULL);
|
||||
m_has_color = false;
|
||||
((IGUIStaticText*)m_element)->enableOverrideColor(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -34,6 +34,7 @@ namespace GUIEngine
|
||||
*/
|
||||
class LabelWidget : public Widget
|
||||
{
|
||||
bool m_bright;
|
||||
bool m_has_color;
|
||||
irr::video::SColor m_color;
|
||||
|
||||
@ -58,10 +59,12 @@ namespace GUIEngine
|
||||
|
||||
/** \brief Callback from base class Widget */
|
||||
virtual void add();
|
||||
|
||||
/** Sets the color of the widget.
|
||||
|
||||
/** Sets the color of the widget.
|
||||
* \param color The color to use for this widget. */
|
||||
void setColor(const irr::video::SColor& color);
|
||||
void setErrorColor();
|
||||
void setDefaultColor();
|
||||
|
||||
/** \brief Callback from base class Widget */
|
||||
virtual void update(float dt);
|
||||
@ -83,11 +86,11 @@ namespace GUIEngine
|
||||
virtual void setText(const wchar_t *text, bool expandAsNeeded);
|
||||
|
||||
/** Overloaded function which takes a stringw. */
|
||||
virtual void setText(const irr::core::stringw &s, bool expandAsNeeded)
|
||||
virtual void setText(const irr::core::stringw &s, bool expandAsNeeded)
|
||||
{
|
||||
setText(s.c_str(), expandAsNeeded);
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/** Sets horizontal scroll speed. */
|
||||
|
@ -15,14 +15,16 @@
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#include "guiengine/widgets/list_widget.hpp"
|
||||
|
||||
#include "guiengine/CGUISpriteBank.h"
|
||||
#include "guiengine/engine.hpp"
|
||||
#include "guiengine/widgets/list_widget.hpp"
|
||||
#include "io/file_manager.hpp"
|
||||
|
||||
#include <IGUIElement.h>
|
||||
#include <IGUISkin.h>
|
||||
#include <IGUIEnvironment.h>
|
||||
#include <IGUIListBox.h>
|
||||
#include "IGUIFontBitmap.h"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
@ -50,7 +52,7 @@ void ListWidget::setIcons(STKModifiedSpriteBank* icons, int size)
|
||||
|
||||
if (m_use_icons)
|
||||
{
|
||||
IGUIListBox* list = getIrrlichtElement<IGUIListBox>();
|
||||
CGUISTKListBox* list = getIrrlichtElement<CGUISTKListBox>();
|
||||
assert(list != NULL);
|
||||
|
||||
list->setSpriteBank(m_icons);
|
||||
@ -80,8 +82,8 @@ void ListWidget::setIcons(STKModifiedSpriteBank* icons, int size)
|
||||
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
void ListWidget::add()
|
||||
{
|
||||
const int header_height = GUIEngine::getFontHeight() + 15;
|
||||
@ -89,11 +91,32 @@ void ListWidget::add()
|
||||
rect<s32> widget_size = (m_header.size() > 0 ? rect<s32>(m_x, m_y + header_height, m_x + m_w, m_y + m_h) :
|
||||
rect<s32>(m_x, m_y, m_x + m_w, m_y + m_h) );
|
||||
|
||||
IGUIListBox* list = GUIEngine::getGUIEnv()->addListBox (widget_size, m_parent, getNewID());
|
||||
list->setAutoScrollEnabled(false);
|
||||
IGUISkin * current_skin = GUIEngine::getGUIEnv()->getSkin();
|
||||
IGUIFont * current_font = GUIEngine::getGUIEnv()->getBuiltInFont();
|
||||
CGUISTKListBox * list_box = new CGUISTKListBox(
|
||||
GUIEngine::getGUIEnv(),
|
||||
m_parent ? m_parent : GUIEngine::getGUIEnv()->getRootGUIElement(),
|
||||
getNewID(),
|
||||
widget_size,
|
||||
true,
|
||||
true,
|
||||
false);
|
||||
|
||||
m_element = list;
|
||||
m_element->setTabOrder( list->getID() );
|
||||
if (current_skin && current_skin->getSpriteBank())
|
||||
{
|
||||
list_box->setSpriteBank(current_skin->getSpriteBank());
|
||||
}
|
||||
else if (current_font && current_font->getType() == EGFT_BITMAP)
|
||||
{
|
||||
list_box->setSpriteBank( ((IGUIFontBitmap*)current_font)->getSpriteBank());
|
||||
}
|
||||
|
||||
list_box->drop();
|
||||
|
||||
list_box->setAutoScrollEnabled(false);
|
||||
|
||||
m_element = list_box;
|
||||
m_element->setTabOrder( list_box->getID() );
|
||||
|
||||
if (m_header.size() > 0)
|
||||
{
|
||||
@ -149,91 +172,129 @@ void ListWidget::clear()
|
||||
// May only be called AFTER this widget has been add()ed
|
||||
assert(m_element != NULL);
|
||||
|
||||
IGUIListBox* list = getIrrlichtElement<IGUIListBox>();
|
||||
CGUISTKListBox* list = getIrrlichtElement<CGUISTKListBox>();
|
||||
assert(list != NULL);
|
||||
|
||||
list->clear();
|
||||
m_items.clear();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void ListWidget::addItem(const std::string& internalName,
|
||||
const irr::core::stringw& name, const int icon)
|
||||
void ListWidget::addItem( const std::string& internal_name,
|
||||
const irr::core::stringw &name,
|
||||
const int icon,
|
||||
bool center)
|
||||
{
|
||||
// May only be called AFTER this widget has been add()ed
|
||||
assert(m_element != NULL);
|
||||
|
||||
ListCell cell(name, icon, 1, center);
|
||||
ListItem newItem;
|
||||
newItem.m_internal_name = internal_name;
|
||||
newItem.m_contents.push_back(cell);
|
||||
|
||||
CGUISTKListBox* list = getIrrlichtElement<CGUISTKListBox>();
|
||||
assert(list != NULL);
|
||||
|
||||
u32 itemID = list->addItem( newItem );
|
||||
if (m_use_icons)
|
||||
{
|
||||
list->setItemOverrideColor( itemID, gui::EGUI_LBC_ICON, video::SColor(255,255,255,255) );
|
||||
list->setItemOverrideColor( itemID, gui::EGUI_LBC_ICON_HIGHLIGHT, video::SColor(255,255,255,255) );
|
||||
}
|
||||
newItem.m_current_id = itemID;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void ListWidget::addItem(const std::string& internal_name,
|
||||
PtrVector<ListCell> * contents)
|
||||
{
|
||||
// May only be called AFTER this widget has been add()ed
|
||||
assert(m_element != NULL);
|
||||
|
||||
ListItem newItem;
|
||||
newItem.m_label = name;
|
||||
newItem.m_internal_name = internalName;
|
||||
newItem.m_internal_name = internal_name;
|
||||
for(int i = 0; i < (int)contents->size(); i++)
|
||||
{
|
||||
newItem.m_contents.push_back(*contents->get(i));
|
||||
}
|
||||
|
||||
IGUIListBox* list = getIrrlichtElement<IGUIListBox>();
|
||||
CGUISTKListBox* list = getIrrlichtElement<CGUISTKListBox>();
|
||||
assert(list != NULL);
|
||||
|
||||
if (m_use_icons && icon != -1)
|
||||
u32 itemID = list->addItem( newItem );
|
||||
if (m_use_icons)
|
||||
{
|
||||
u32 itemID = list->addItem( name.c_str(), icon );
|
||||
list->setItemOverrideColor( itemID, gui::EGUI_LBC_ICON, video::SColor(255,255,255,255) );
|
||||
list->setItemOverrideColor( itemID, gui::EGUI_LBC_ICON_HIGHLIGHT, video::SColor(255,255,255,255) );
|
||||
newItem.m_current_id = itemID;
|
||||
}
|
||||
else
|
||||
{
|
||||
newItem.m_current_id = list->addItem( name.c_str() );
|
||||
}
|
||||
m_items.push_back(newItem);
|
||||
newItem.m_current_id = itemID;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void ListWidget::renameItem(const int itemID, const irr::core::stringw newName, const int icon)
|
||||
void ListWidget::renameCell(const int row_index, const int col_index, const irr::core::stringw newName, const int icon)
|
||||
{
|
||||
// May only be called AFTER this widget has been add()ed
|
||||
assert(m_element != NULL);
|
||||
|
||||
IGUIListBox* list = getIrrlichtElement<IGUIListBox>();
|
||||
CGUISTKListBox* list = getIrrlichtElement<CGUISTKListBox>();
|
||||
assert(list != NULL);
|
||||
|
||||
m_items[itemID].m_label = newName;
|
||||
list->setItem(itemID, newName.c_str(), icon);
|
||||
list->setCell(row_index, col_index, newName.c_str(), icon);
|
||||
|
||||
list->setItemOverrideColor( itemID, EGUI_LBC_TEXT , video::SColor(255,0,0,0) );
|
||||
list->setItemOverrideColor( itemID, EGUI_LBC_TEXT_HIGHLIGHT, video::SColor(255,255,255,255) );
|
||||
list->setItemOverrideColor( row_index, EGUI_LBC_TEXT , video::SColor(255,0,0,0) );
|
||||
list->setItemOverrideColor( row_index, EGUI_LBC_TEXT_HIGHLIGHT, video::SColor(255,255,255,255) );
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
void ListWidget::renameItem(const int row_index, const irr::core::stringw newName, const int icon)
|
||||
{
|
||||
renameCell(row_index, 0, newName, icon);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
void ListWidget::renameItem(const std::string & internal_name, const irr::core::stringw newName, const int icon)
|
||||
{
|
||||
CGUISTKListBox* list = getIrrlichtElement<CGUISTKListBox>();
|
||||
assert(list != NULL);
|
||||
renameCell(list->getRowByInternalName(internal_name), 0, newName, icon);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
std::string ListWidget::getSelectionInternalName()
|
||||
{
|
||||
if (getSelectionID() == -1) return "";
|
||||
return m_items[ getSelectionID() ].m_internal_name;
|
||||
|
||||
CGUISTKListBox* list = getIrrlichtElement<CGUISTKListBox>();
|
||||
assert(list != NULL);
|
||||
if (getSelectionID() == -1 || (getSelectionID() >= (int)list->getItemCount()))
|
||||
return "";
|
||||
return list->getItem(getSelectionID()).m_internal_name;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
irr::core::stringw ListWidget::getSelectionLabel() const
|
||||
irr::core::stringw ListWidget::getSelectionLabel(const int cell) const
|
||||
{
|
||||
const IGUIListBox* list = getIrrlichtElement<IGUIListBox>();
|
||||
const CGUISTKListBox* list = getIrrlichtElement<CGUISTKListBox>();
|
||||
assert(list != NULL);
|
||||
return list->getListItem( list->getSelected() );
|
||||
return list->getCellText( list->getSelected(), cell);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void ListWidget::selectItemWithLabel(const irr::core::stringw& name)
|
||||
{
|
||||
IGUIListBox* list = getIrrlichtElement<IGUIListBox>();
|
||||
CGUISTKListBox* list = getIrrlichtElement<CGUISTKListBox>();
|
||||
assert(list != NULL);
|
||||
return list->setSelected( name.c_str() );
|
||||
return list->setSelectedByCellText( name.c_str() );
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void ListWidget::unfocused(const int playerID, Widget* new_focus)
|
||||
{
|
||||
IGUIListBox* list = getIrrlichtElement<IGUIListBox>();
|
||||
CGUISTKListBox* list = getIrrlichtElement<CGUISTKListBox>();
|
||||
|
||||
// remove selection when leaving list
|
||||
if (list != NULL) list->setSelected(-1);
|
||||
@ -246,7 +307,7 @@ int ListWidget::getSelectionID() const
|
||||
// May only be called AFTER this widget has been add()ed
|
||||
assert(m_element != NULL);
|
||||
|
||||
return getIrrlichtElement<IGUIListBox>()->getSelected();
|
||||
return getIrrlichtElement<CGUISTKListBox>()->getSelected();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@ -256,7 +317,7 @@ void ListWidget::setSelectionID(const int index)
|
||||
// May only be called AFTER this widget has been add()ed
|
||||
assert(m_element != NULL);
|
||||
|
||||
IGUIListBox* irritem = getIrrlichtElement<IGUIListBox>();
|
||||
CGUISTKListBox* irritem = getIrrlichtElement<CGUISTKListBox>();
|
||||
|
||||
// auto-scroll to item when selecting something, don't auto-scroll when selecting nothing
|
||||
if (index != -1)
|
||||
@ -279,8 +340,7 @@ int ListWidget::getItemCount() const
|
||||
// May only be called AFTER this widget has been add()ed
|
||||
assert(m_element != NULL);
|
||||
|
||||
const int count = getIrrlichtElement<IGUIListBox>()->getItemCount();
|
||||
assert((int)m_items.size() == count);
|
||||
const int count = getIrrlichtElement<CGUISTKListBox>()->getItemCount();
|
||||
|
||||
return count;
|
||||
}
|
||||
@ -290,7 +350,6 @@ int ListWidget::getItemCount() const
|
||||
void ListWidget::elementRemoved()
|
||||
{
|
||||
Widget::elementRemoved();
|
||||
m_items.clear();
|
||||
|
||||
for (int n=0; n<m_header_elements.size(); n++)
|
||||
{
|
||||
@ -303,26 +362,12 @@ void ListWidget::elementRemoved()
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
int ListWidget::getItemID(const std::string internalName) const
|
||||
{
|
||||
const int count = m_items.size();
|
||||
|
||||
for (int i=0; i<count; i++)
|
||||
{
|
||||
if (m_items[i].m_internal_name == internalName) return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void ListWidget::markItemRed(const int id, bool red)
|
||||
{
|
||||
// May only be called AFTER this widget has been add()ed
|
||||
assert(m_element != NULL);
|
||||
|
||||
IGUIListBox* irritem = getIrrlichtElement<IGUIListBox>();
|
||||
CGUISTKListBox* irritem = getIrrlichtElement<CGUISTKListBox>();
|
||||
|
||||
if (red)
|
||||
{
|
||||
@ -343,7 +388,7 @@ void ListWidget::markItemBlue(const int id, bool blue)
|
||||
// May only be called AFTER this widget has been add()ed
|
||||
assert(m_element != NULL);
|
||||
|
||||
IGUIListBox* irritem = getIrrlichtElement<IGUIListBox>();
|
||||
CGUISTKListBox* irritem = getIrrlichtElement<CGUISTKListBox>();
|
||||
|
||||
if (blue)
|
||||
{
|
||||
@ -389,3 +434,11 @@ EventPropagation ListWidget::transmitEvent(Widget* w,
|
||||
|
||||
return EVENT_LET;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
int ListWidget::getItemID(const std::string internalName) const
|
||||
{
|
||||
const CGUISTKListBox* list = getIrrlichtElement<CGUISTKListBox>();
|
||||
assert(list != NULL);
|
||||
return list->getRowByInternalName(internalName);
|
||||
}
|
||||
|
@ -22,10 +22,13 @@
|
||||
|
||||
#include <irrString.h>
|
||||
|
||||
#include "guiengine/widgets/CGUISTKListBox.h"
|
||||
#include "guiengine/widget.hpp"
|
||||
#include "guiengine/widgets/button_widget.hpp"
|
||||
#include "utils/leak_check.hpp"
|
||||
#include "utils/ptr_vector.hpp"
|
||||
#include "IGUIElement.h"
|
||||
|
||||
|
||||
namespace irr { namespace gui { class STKModifiedSpriteBank; } }
|
||||
|
||||
@ -47,7 +50,6 @@ namespace GUIEngine
|
||||
class ListWidget : public Widget
|
||||
{
|
||||
friend class Skin;
|
||||
|
||||
|
||||
/** \brief whether this list has icons */
|
||||
bool m_use_icons;
|
||||
@ -55,14 +57,6 @@ namespace GUIEngine
|
||||
/** \brief if m_use_icons is true, this will contain the icon bank */
|
||||
irr::gui::STKModifiedSpriteBank* m_icons;
|
||||
|
||||
struct ListItem
|
||||
{
|
||||
std::string m_internal_name;
|
||||
irr::core::stringw m_label;
|
||||
int m_current_id;
|
||||
};
|
||||
std::vector< ListItem > m_items;
|
||||
|
||||
PtrVector< ButtonWidget > m_header_elements;
|
||||
|
||||
ButtonWidget* m_selected_column;
|
||||
@ -86,8 +80,10 @@ namespace GUIEngine
|
||||
std::vector< Column > m_header;
|
||||
|
||||
IListWidgetHeaderListener* m_listener;
|
||||
|
||||
|
||||
public:
|
||||
typedef irr::gui::CGUISTKListBox::ListItem ListItem;
|
||||
typedef ListItem::ListCell ListCell;
|
||||
|
||||
LEAK_CHECK()
|
||||
|
||||
@ -124,8 +120,13 @@ namespace GUIEngine
|
||||
* \param icon ID of the icon within the icon bank. Only used if an icon bank was passed.
|
||||
* \pre may only be called after the widget has been added to the screen with add()
|
||||
*/
|
||||
void addItem(const std::string& internal_name,
|
||||
const irr::core::stringw &name, const int icon=-1);
|
||||
void addItem( const std::string& internal_name,
|
||||
const irr::core::stringw &name,
|
||||
const int icon=-1,
|
||||
bool center = false);
|
||||
|
||||
void addItem( const std::string& internal_name,
|
||||
PtrVector<ListCell> * contents);
|
||||
|
||||
/**
|
||||
* \brief erases all items in the list
|
||||
@ -151,7 +152,7 @@ namespace GUIEngine
|
||||
*/
|
||||
std::string getSelectionInternalName();
|
||||
|
||||
irr::core::stringw getSelectionLabel() const;
|
||||
irr::core::stringw getSelectionLabel(const int cell = 0) const;
|
||||
|
||||
void selectItemWithLabel(const irr::core::stringw& name);
|
||||
|
||||
@ -171,18 +172,24 @@ namespace GUIEngine
|
||||
* \brief rename an item and/or change its icon based on its ID
|
||||
* \pre may only be called after the widget has been added to the screen with add()
|
||||
*/
|
||||
void renameItem(const int itemID, const irr::core::stringw newName, const int icon=-1);
|
||||
void renameCell(const int row_num, const int col_num, const irr::core::stringw newName, const int icon=-1);
|
||||
|
||||
/**
|
||||
* renames first cell only
|
||||
*/
|
||||
void renameItem(const int row_num, const irr::core::stringw newName, const int icon=-1);
|
||||
void renameItem(const std::string & internal_name, const irr::core::stringw newName, const int icon=-1);
|
||||
|
||||
/**
|
||||
* \brief rename an item and/or change its icon based on its internal name
|
||||
* \pre may only be called after the widget has been added to the screen with add()
|
||||
*/
|
||||
void renameItem(const std::string internalName, const irr::core::stringw newName,
|
||||
void renameCell(const std::string internalName, const int col_num, const irr::core::stringw newName,
|
||||
const int icon=-1)
|
||||
{
|
||||
const int id = getItemID(internalName);
|
||||
assert(id != -1);
|
||||
renameItem( id, newName, icon );
|
||||
renameCell( id, col_num, newName, icon );
|
||||
}
|
||||
|
||||
/**
|
||||
|
15
src/main.cpp
15
src/main.cpp
@ -173,7 +173,8 @@
|
||||
#include "network/server_network_manager.hpp"
|
||||
#include "network/protocol_manager.hpp"
|
||||
#include "network/protocols/server_lobby_room_protocol.hpp"
|
||||
#include "online/current_online_user.hpp"
|
||||
#include "online/current_user.hpp"
|
||||
#include "online/http_manager.hpp"
|
||||
#include "race/grand_prix_manager.hpp"
|
||||
#include "race/highscore_manager.hpp"
|
||||
#include "race/history.hpp"
|
||||
@ -1107,8 +1108,16 @@ int handleCmdLine(int argc, char **argv)
|
||||
|
||||
if (try_login)
|
||||
{
|
||||
/*
|
||||
irr::core::stringw s;
|
||||
CurrentOnlineUser::get()->signIn(login, password, s);
|
||||
Online::CurrentUser::SignInRequest* request =
|
||||
Online::CurrentUser::acquire()->requestSignIn(login, password, false);
|
||||
request->setManageMemory(true);
|
||||
|
||||
if (request->isSuccess())
|
||||
{
|
||||
Log::info("Main", "Logged in from command line.");
|
||||
}*/
|
||||
}
|
||||
|
||||
return 1;
|
||||
@ -1230,6 +1239,8 @@ void cleanSuperTuxKart()
|
||||
|
||||
if(INetworkHttp::get())
|
||||
INetworkHttp::get()->stopNetworkThread();
|
||||
if(Online::HTTPManager::isRunning())
|
||||
Online::HTTPManager::get()->stopNetworkThread();
|
||||
//delete in reverse order of what they were created in.
|
||||
//delete in reverse order of what they were created in.
|
||||
//see InitTuxkart()
|
||||
|
@ -22,7 +22,7 @@
|
||||
#ifndef GAME_SETUP_HPP
|
||||
#define GAME_SETUP_HPP
|
||||
|
||||
#include "online/online_user.hpp"
|
||||
#include "online/user.hpp"
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
@ -35,10 +35,10 @@ class NetworkPlayerProfile
|
||||
public:
|
||||
NetworkPlayerProfile() { race_id = 0; user_profile = NULL; }
|
||||
~NetworkPlayerProfile() {}
|
||||
|
||||
|
||||
uint8_t race_id; //!< The id of the player for the race
|
||||
std::string kart_name; //!< The selected kart.
|
||||
OnlineUser* user_profile; //!< Pointer to the lobby profile
|
||||
Online::User* user_profile; //!< Pointer to the lobby profile
|
||||
};
|
||||
|
||||
/*! \class GameSetup
|
||||
@ -60,7 +60,7 @@ class GameSetup
|
||||
int getPlayerCount() { return m_players.size(); }
|
||||
const NetworkPlayerProfile* getProfile(uint32_t id); //!< Get a profile by database id
|
||||
const NetworkPlayerProfile* getProfile(uint8_t id); //!< Get the profile by the lobby id
|
||||
|
||||
|
||||
bool isKartAvailable(std::string kart_name);
|
||||
bool isKartAllowed(std::string kart_name) {return true; }
|
||||
|
||||
|
@ -20,7 +20,7 @@
|
||||
|
||||
#include "network/network_manager.hpp"
|
||||
#include "network/protocols/start_game_protocol.hpp"
|
||||
#include "online/current_online_user.hpp"
|
||||
#include "online/current_user.hpp"
|
||||
#include "utils/log.hpp"
|
||||
|
||||
ClientLobbyRoomProtocol::ClientLobbyRoomProtocol(const TransportAddress& server_address)
|
||||
@ -105,7 +105,7 @@ void ClientLobbyRoomProtocol::update()
|
||||
{
|
||||
NetworkString ns;
|
||||
// 1 (connection request), 4 (size of id), global id
|
||||
ns.ai8(1).ai8(4).ai32(CurrentOnlineUser::get()->getUserID());
|
||||
ns.ai8(1).ai8(4).ai32(Online::CurrentUser::acquire()->getUserID());
|
||||
m_listener->sendMessage(this, ns);
|
||||
m_state = REQUESTING_CONNECTION;
|
||||
} break;
|
||||
@ -145,7 +145,7 @@ void ClientLobbyRoomProtocol::newPlayer(Event* event)
|
||||
uint32_t global_id = event->data.gui32(1);
|
||||
uint8_t race_id = event->data.gui8(6);
|
||||
|
||||
if (global_id == CurrentOnlineUser::get()->getUserID())
|
||||
if (global_id == Online::CurrentUser::acquire()->getUserID())
|
||||
{
|
||||
Log::error("ClientLobbyRoomProtocol", "The server notified me that i'm a new player in the room (not normal).");
|
||||
}
|
||||
@ -155,7 +155,7 @@ void ClientLobbyRoomProtocol::newPlayer(Event* event)
|
||||
NetworkPlayerProfile* profile = new NetworkPlayerProfile();
|
||||
profile->kart_name = "";
|
||||
profile->race_id = race_id;
|
||||
profile->user_profile = new OnlineUser(global_id);
|
||||
profile->user_profile = new Online::User(global_id);
|
||||
m_setup->addPlayer(profile);
|
||||
}
|
||||
else
|
||||
@ -216,7 +216,7 @@ void ClientLobbyRoomProtocol::connectionAccepted(Event* event)
|
||||
STKPeer* peer = *(event->peer);
|
||||
|
||||
uint32_t global_id = event->data.gui32(8);
|
||||
if (global_id == CurrentOnlineUser::get()->getUserID())
|
||||
if (global_id == Online::CurrentUser::acquire()->getUserID())
|
||||
{
|
||||
Log::info("ClientLobbyRoomProtocol", "The server accepted the connection.");
|
||||
|
||||
@ -224,7 +224,7 @@ void ClientLobbyRoomProtocol::connectionAccepted(Event* event)
|
||||
NetworkPlayerProfile* profile = new NetworkPlayerProfile();
|
||||
profile->kart_name = "";
|
||||
profile->race_id = event->data.gui8(1);
|
||||
profile->user_profile = CurrentOnlineUser::get();
|
||||
profile->user_profile = Online::CurrentUser::acquire();
|
||||
m_setup->addPlayer(profile);
|
||||
// connection token
|
||||
uint32_t token = event->data.gui32(3);
|
||||
@ -243,7 +243,7 @@ void ClientLobbyRoomProtocol::connectionAccepted(Event* event)
|
||||
Log::error("ClientLobbyRoomProtocol", "Bad format in players list.");
|
||||
uint8_t race_id = event->data[1];
|
||||
uint32_t global_id = event->data.gui32(3);
|
||||
OnlineUser* new_user = new OnlineUser(global_id);
|
||||
Online::User* new_user = new Online::User(global_id);
|
||||
NetworkPlayerProfile* profile2 = new NetworkPlayerProfile();
|
||||
profile2->race_id = race_id;
|
||||
profile2->user_profile = new_user;
|
||||
|
@ -25,7 +25,7 @@
|
||||
#include "network/protocols/hide_public_address.hpp"
|
||||
#include "network/protocols/request_connection.hpp"
|
||||
#include "network/protocols/ping_protocol.hpp"
|
||||
#include "online/current_online_user.hpp"
|
||||
#include "online/current_user.hpp"
|
||||
#include "utils/time.hpp"
|
||||
#include "utils/log.hpp"
|
||||
|
||||
|
@ -27,7 +27,7 @@
|
||||
#include "network/protocols/ping_protocol.hpp"
|
||||
#include "network/protocols/quick_join_protocol.hpp"
|
||||
#include "network/protocols/client_lobby_room_protocol.hpp"
|
||||
#include "online/current_online_user.hpp"
|
||||
#include "online/current_user.hpp"
|
||||
#include "utils/time.hpp"
|
||||
#include "utils/log.hpp"
|
||||
|
||||
|
@ -20,8 +20,8 @@
|
||||
|
||||
#include "network/protocol_manager.hpp"
|
||||
#include "network/http_functions.hpp"
|
||||
#include "online/http_connector.hpp"
|
||||
#include "online/current_online_user.hpp"
|
||||
#include "online/http_manager.hpp"
|
||||
#include "online/current_user.hpp"
|
||||
#include "config/user_config.hpp"
|
||||
#include "utils/log.hpp"
|
||||
|
||||
@ -42,20 +42,26 @@ void GetPeerAddress::notifyEvent(Event* event)
|
||||
void GetPeerAddress::setup()
|
||||
{
|
||||
m_state = NONE;
|
||||
m_request = NULL;
|
||||
}
|
||||
|
||||
void GetPeerAddress::asynchronousUpdate()
|
||||
{
|
||||
if (m_state == NONE)
|
||||
{
|
||||
m_request = new Online::XMLRequest();
|
||||
m_request->setURL((std::string)UserConfigParams::m_server_multiplayer + "address-management.php");
|
||||
m_request->setParameter("id",Online::CurrentUser::acquire()->getUserID());
|
||||
m_request->setParameter("token",Online::CurrentUser::acquire()->getToken());
|
||||
m_request->setParameter("peer_id",m_peer_id);
|
||||
m_request->setParameter("action","get");
|
||||
|
||||
HTTPConnector connector((std::string)UserConfigParams::m_server_multiplayer + "address-management.php");
|
||||
connector.setParameter("id",CurrentOnlineUser::get()->getUserID());
|
||||
connector.setParameter("token",CurrentOnlineUser::get()->getToken());
|
||||
connector.setParameter("peer_id",m_peer_id);
|
||||
connector.setParameter("action","get");
|
||||
|
||||
const XMLNode * result = connector.getXMLFromPage();
|
||||
Online::HTTPManager::get()->addRequest(m_request);
|
||||
m_state = REQUEST_PENDING;
|
||||
}
|
||||
else if (m_state == REQUEST_PENDING && m_request->isDone())
|
||||
{
|
||||
const XMLNode * result = m_request->getResult();
|
||||
std::string rec_success;
|
||||
|
||||
if(result->get("success", &rec_success))
|
||||
@ -81,6 +87,8 @@ void GetPeerAddress::asynchronousUpdate()
|
||||
else if (m_state == DONE)
|
||||
{
|
||||
m_state = EXITING;
|
||||
delete m_request;
|
||||
m_request = NULL;
|
||||
m_listener->requestTerminate(this);
|
||||
}
|
||||
}
|
||||
|
@ -20,6 +20,7 @@
|
||||
#define GET_PEER_ADDRESS_HPP
|
||||
|
||||
#include "network/protocol.hpp"
|
||||
#include "online/request.hpp"
|
||||
|
||||
class GetPeerAddress : public Protocol
|
||||
{
|
||||
@ -35,10 +36,11 @@ class GetPeerAddress : public Protocol
|
||||
void setPeerID(uint32_t m_peer_id);
|
||||
protected:
|
||||
uint32_t m_peer_id;
|
||||
|
||||
Online::XMLRequest* m_request;
|
||||
enum STATE
|
||||
{
|
||||
NONE,
|
||||
REQUEST_PENDING,
|
||||
DONE,
|
||||
EXITING
|
||||
};
|
||||
|
@ -19,8 +19,8 @@
|
||||
#include "network/protocols/hide_public_address.hpp"
|
||||
|
||||
#include "network/protocol_manager.hpp"
|
||||
#include "online/http_connector.hpp"
|
||||
#include "online/current_online_user.hpp"
|
||||
#include "online/http_manager.hpp"
|
||||
#include "online/current_user.hpp"
|
||||
#include "config/user_config.hpp"
|
||||
#include "utils/log.hpp"
|
||||
|
||||
@ -45,12 +45,18 @@ void HidePublicAddress::asynchronousUpdate()
|
||||
{
|
||||
if (m_state == NONE)
|
||||
{
|
||||
HTTPConnector connector((std::string)UserConfigParams::m_server_multiplayer + "address-management.php");
|
||||
connector.setParameter("id",CurrentOnlineUser::get()->getUserID());
|
||||
connector.setParameter("token",CurrentOnlineUser::get()->getToken());
|
||||
connector.setParameter("action","unset");
|
||||
m_request = new Online::XMLRequest();
|
||||
m_request->setURL((std::string)UserConfigParams::m_server_multiplayer + "address-management.php");
|
||||
m_request->setParameter("id",Online::CurrentUser::acquire()->getUserID());
|
||||
m_request->setParameter("token",Online::CurrentUser::acquire()->getToken());
|
||||
m_request->setParameter("action","unset");
|
||||
|
||||
const XMLNode * result = connector.getXMLFromPage();
|
||||
Online::HTTPManager::get()->addRequest(m_request);
|
||||
m_state = REQUEST_PENDING;
|
||||
}
|
||||
else if (m_state == REQUEST_PENDING && m_request->isDone())
|
||||
{
|
||||
const XMLNode * result = m_request->getResult();
|
||||
std::string rec_success;
|
||||
|
||||
if(result->get("success", &rec_success))
|
||||
@ -73,6 +79,8 @@ void HidePublicAddress::asynchronousUpdate()
|
||||
else if (m_state == DONE)
|
||||
{
|
||||
m_state = EXITING;
|
||||
delete m_request;
|
||||
m_request = NULL;
|
||||
m_listener->requestTerminate(this);
|
||||
}
|
||||
}
|
||||
|
@ -20,6 +20,7 @@
|
||||
#define HIDE_PUBLIC_ADDRESS_HPP
|
||||
|
||||
#include "network/protocol.hpp"
|
||||
#include "online/request.hpp"
|
||||
#include <string>
|
||||
|
||||
class HidePublicAddress : public Protocol
|
||||
@ -34,10 +35,11 @@ class HidePublicAddress : public Protocol
|
||||
virtual void asynchronousUpdate();
|
||||
|
||||
protected:
|
||||
|
||||
Online::XMLRequest* m_request;
|
||||
enum STATE
|
||||
{
|
||||
NONE,
|
||||
REQUEST_PENDING,
|
||||
DONE,
|
||||
EXITING
|
||||
};
|
||||
|
@ -19,8 +19,8 @@
|
||||
#include "quick_join_protocol.hpp"
|
||||
|
||||
#include "network/network_manager.hpp"
|
||||
#include "online/current_online_user.hpp"
|
||||
#include "online/http_connector.hpp"
|
||||
#include "online/current_user.hpp"
|
||||
#include "online/http_manager.hpp"
|
||||
#include "config/user_config.hpp"
|
||||
#include "utils/log.hpp"
|
||||
|
||||
@ -47,12 +47,18 @@ void QuickJoinProtocol::asynchronousUpdate()
|
||||
if (m_state == NONE)
|
||||
{
|
||||
TransportAddress addr = NetworkManager::getInstance()->getPublicAddress();
|
||||
HTTPConnector connector((std::string)UserConfigParams::m_server_multiplayer + "address-management.php");
|
||||
connector.setParameter("id",CurrentOnlineUser::get()->getUserID());
|
||||
connector.setParameter("token",CurrentOnlineUser::get()->getToken());
|
||||
connector.setParameter("action","quick-join");
|
||||
m_request = new Online::XMLRequest();
|
||||
m_request->setURL((std::string)UserConfigParams::m_server_multiplayer + "address-management.php");
|
||||
m_request->setParameter("id",Online::CurrentUser::acquire()->getUserID());
|
||||
m_request->setParameter("token",Online::CurrentUser::acquire()->getToken());
|
||||
m_request->setParameter("action","quick-join");
|
||||
|
||||
const XMLNode * result = connector.getXMLFromPage();
|
||||
Online::HTTPManager::get()->addRequest(m_request);
|
||||
m_state = REQUEST_PENDING;
|
||||
}
|
||||
else if (m_state == REQUEST_PENDING && m_request->isDone())
|
||||
{
|
||||
const XMLNode * result = m_request->getResult();
|
||||
std::string rec_success;
|
||||
TransportAddress* res = static_cast<TransportAddress*>(m_callback_object);
|
||||
|
||||
@ -79,6 +85,8 @@ void QuickJoinProtocol::asynchronousUpdate()
|
||||
else if (m_state == DONE)
|
||||
{
|
||||
m_state = EXITING;
|
||||
delete m_request;
|
||||
m_request = NULL;
|
||||
m_listener->requestTerminate(this);
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
#define QUICK_JOIN_PROTOCOL_HPP
|
||||
|
||||
#include "network/protocol.hpp"
|
||||
|
||||
#include "online/request.hpp"
|
||||
|
||||
class QuickJoinProtocol : public Protocol
|
||||
{
|
||||
@ -17,9 +17,11 @@ class QuickJoinProtocol : public Protocol
|
||||
|
||||
protected:
|
||||
uint32_t* m_server_id;
|
||||
Online::XMLRequest* m_request;
|
||||
enum STATE
|
||||
{
|
||||
NONE,
|
||||
REQUEST_PENDING,
|
||||
DONE,
|
||||
EXITING
|
||||
};
|
||||
|
@ -19,8 +19,8 @@
|
||||
#include "network/protocols/request_connection.hpp"
|
||||
|
||||
#include "network/protocol_manager.hpp"
|
||||
#include "online/http_connector.hpp"
|
||||
#include "online/current_online_user.hpp"
|
||||
#include "online/http_manager.hpp"
|
||||
#include "online/current_user.hpp"
|
||||
#include "config/user_config.hpp"
|
||||
|
||||
RequestConnection::RequestConnection(uint32_t server_id) : Protocol(NULL, PROTOCOL_SILENT)
|
||||
@ -47,13 +47,22 @@ void RequestConnection::asynchronousUpdate()
|
||||
{
|
||||
case NONE:
|
||||
{
|
||||
HTTPConnector connector((std::string)UserConfigParams::m_server_multiplayer + "address-management.php");
|
||||
connector.setParameter("id",CurrentOnlineUser::get()->getUserID());
|
||||
connector.setParameter("token",CurrentOnlineUser::get()->getToken());
|
||||
connector.setParameter("server_id",m_server_id);
|
||||
connector.setParameter("action","request-connection");
|
||||
m_request = new Online::XMLRequest();
|
||||
m_request->setURL((std::string)UserConfigParams::m_server_multiplayer + "address-management.php");
|
||||
m_request->setParameter("id",Online::CurrentUser::acquire()->getUserID());
|
||||
m_request->setParameter("token",Online::CurrentUser::acquire()->getToken());
|
||||
m_request->setParameter("server_id",m_server_id);
|
||||
m_request->setParameter("action","request-connection");
|
||||
|
||||
const XMLNode * result = connector.getXMLFromPage();
|
||||
Online::HTTPManager::get()->addRequest(m_request);
|
||||
m_state = REQUEST_PENDING;
|
||||
break;
|
||||
}
|
||||
case REQUEST_PENDING:
|
||||
{
|
||||
if (!m_request->isDone())
|
||||
return;
|
||||
const XMLNode * result = m_request->getResult();
|
||||
std::string rec_success;
|
||||
|
||||
if(result->get("success", &rec_success))
|
||||
@ -77,6 +86,8 @@ void RequestConnection::asynchronousUpdate()
|
||||
}
|
||||
case DONE:
|
||||
m_state = EXITING;
|
||||
delete m_request;
|
||||
m_request = NULL;
|
||||
m_listener->requestTerminate(this);
|
||||
break;
|
||||
case EXITING:
|
||||
|
@ -2,6 +2,7 @@
|
||||
#define REQUEST_CONNECTION_HPP
|
||||
|
||||
#include "network/protocol.hpp"
|
||||
#include "online/request.hpp"
|
||||
|
||||
class RequestConnection : public Protocol
|
||||
{
|
||||
@ -16,10 +17,11 @@ class RequestConnection : public Protocol
|
||||
|
||||
protected:
|
||||
uint32_t m_server_id;
|
||||
|
||||
Online::XMLRequest* m_request;
|
||||
enum STATE
|
||||
{
|
||||
NONE,
|
||||
REQUEST_PENDING,
|
||||
DONE,
|
||||
EXITING
|
||||
};
|
||||
|
@ -25,8 +25,8 @@
|
||||
#include "network/protocols/start_server.hpp"
|
||||
#include "network/protocols/start_game_protocol.hpp"
|
||||
|
||||
#include "online/current_online_user.hpp"
|
||||
#include "online/http_connector.hpp"
|
||||
#include "online/current_user.hpp"
|
||||
#include "online/http_manager.hpp"
|
||||
#include "config/user_config.hpp"
|
||||
#include "utils/log.hpp"
|
||||
#include "utils/time.hpp"
|
||||
@ -113,14 +113,18 @@ void ServerLobbyRoomProtocol::update()
|
||||
{
|
||||
last_poll_time = Time::getRealTime();
|
||||
TransportAddress addr = NetworkManager::getInstance()->getPublicAddress();
|
||||
HTTPConnector connector((std::string)UserConfigParams::m_server_multiplayer + "address-management.php");
|
||||
connector.setParameter("id",CurrentOnlineUser::get()->getUserID());
|
||||
connector.setParameter("token",CurrentOnlineUser::get()->getToken());
|
||||
connector.setParameter("address",addr.ip);
|
||||
connector.setParameter("port",addr.port);
|
||||
connector.setParameter("action","poll-connection-requests");
|
||||
Online::XMLRequest* request = new Online::XMLRequest();
|
||||
request->setURL((std::string)UserConfigParams::m_server_multiplayer + "address-management.php");
|
||||
request->setParameter("id",Online::CurrentUser::acquire()->getUserID());
|
||||
request->setParameter("token",Online::CurrentUser::acquire()->getToken());
|
||||
request->setParameter("address",addr.ip);
|
||||
request->setParameter("port",addr.port);
|
||||
request->setParameter("action","poll-connection-requests");
|
||||
|
||||
const XMLNode * result = connector.getXMLFromPage();
|
||||
Online::HTTPManager::get()->synchronousRequest(request);
|
||||
assert(request->isDone());
|
||||
|
||||
const XMLNode * result = request->getResult();
|
||||
std::string rec_success;
|
||||
if(result->get("success", &rec_success))
|
||||
{
|
||||
@ -144,6 +148,7 @@ void ServerLobbyRoomProtocol::update()
|
||||
{
|
||||
Log::error("ServerLobbyRoomProtocol", "Cannot retrieve the list.");
|
||||
}
|
||||
delete request;
|
||||
}
|
||||
|
||||
// now
|
||||
@ -257,7 +262,7 @@ void ServerLobbyRoomProtocol::connectionRequested(Event* event)
|
||||
NetworkPlayerProfile* profile = new NetworkPlayerProfile();
|
||||
profile->race_id = m_next_id;
|
||||
profile->kart_name = "";
|
||||
profile->user_profile = new OnlineUser(player_id);
|
||||
profile->user_profile = new Online::User(player_id);
|
||||
m_setup->addPlayer(profile);
|
||||
peer->setPlayerProfile(profile);
|
||||
Log::verbose("ServerLobbyRoomProtocol", "New player.");
|
||||
|
@ -19,8 +19,8 @@
|
||||
#include "network/protocols/show_public_address.hpp"
|
||||
|
||||
#include "network/network_manager.hpp"
|
||||
#include "online/http_connector.hpp"
|
||||
#include "online/current_online_user.hpp"
|
||||
#include "online/http_manager.hpp"
|
||||
#include "online/current_user.hpp"
|
||||
#include "config/user_config.hpp"
|
||||
#include "utils/log.hpp"
|
||||
|
||||
@ -46,14 +46,20 @@ void ShowPublicAddress::asynchronousUpdate()
|
||||
if (m_state == NONE)
|
||||
{
|
||||
TransportAddress addr = NetworkManager::getInstance()->getPublicAddress();
|
||||
HTTPConnector connector((std::string)UserConfigParams::m_server_multiplayer + "address-management.php");
|
||||
connector.setParameter("id",CurrentOnlineUser::get()->getUserID());
|
||||
connector.setParameter("token",CurrentOnlineUser::get()->getToken());
|
||||
connector.setParameter("address",addr.ip);
|
||||
connector.setParameter("port",addr.port);
|
||||
connector.setParameter("action","set");
|
||||
m_request = new Online::XMLRequest();
|
||||
m_request->setURL((std::string)UserConfigParams::m_server_multiplayer + "address-management.php");
|
||||
m_request->setParameter("id",Online::CurrentUser::acquire()->getUserID());
|
||||
m_request->setParameter("token",Online::CurrentUser::acquire()->getToken());
|
||||
m_request->setParameter("address",addr.ip);
|
||||
m_request->setParameter("port",addr.port);
|
||||
m_request->setParameter("action","set");
|
||||
|
||||
const XMLNode * result = connector.getXMLFromPage();
|
||||
Online::HTTPManager::get()->addRequest(m_request);
|
||||
m_state = REQUEST_PENDING;
|
||||
}
|
||||
else if (m_state == REQUEST_PENDING && m_request->isDone())
|
||||
{
|
||||
const XMLNode * result = m_request->getResult();
|
||||
std::string rec_success;
|
||||
|
||||
if(result->get("success", &rec_success))
|
||||
@ -76,6 +82,8 @@ void ShowPublicAddress::asynchronousUpdate()
|
||||
else if (m_state == DONE)
|
||||
{
|
||||
m_state = EXITING;
|
||||
delete m_request;
|
||||
m_request = NULL;
|
||||
m_listener->requestTerminate(this);
|
||||
}
|
||||
}
|
||||
|
@ -20,6 +20,7 @@
|
||||
#define SHOW_PUBLIC_ADDRESS_HPP
|
||||
|
||||
#include "network/protocol.hpp"
|
||||
#include "online/request.hpp"
|
||||
#include <string>
|
||||
|
||||
class ShowPublicAddress : public Protocol
|
||||
@ -34,10 +35,11 @@ class ShowPublicAddress : public Protocol
|
||||
virtual void asynchronousUpdate();
|
||||
|
||||
protected:
|
||||
|
||||
Online::XMLRequest* m_request;
|
||||
enum STATE
|
||||
{
|
||||
NONE,
|
||||
REQUEST_PENDING,
|
||||
DONE,
|
||||
EXITING
|
||||
};
|
||||
|
@ -14,7 +14,7 @@
|
||||
#include "challenges/unlock_manager.hpp"
|
||||
#include "states_screens/state_manager.hpp"
|
||||
#include "states_screens/kart_selection.hpp"
|
||||
#include "online/current_online_user.hpp"
|
||||
#include "online/current_user.hpp"
|
||||
|
||||
StartGameProtocol::StartGameProtocol(GameSetup* game_setup) :
|
||||
Protocol(NULL, PROTOCOL_START_GAME)
|
||||
@ -103,7 +103,7 @@ void StartGameProtocol::update()
|
||||
// have to add self first
|
||||
for (unsigned int i = 0; i < players.size(); i++)
|
||||
{
|
||||
bool is_me = (players[i]->user_profile == CurrentOnlineUser::get());
|
||||
bool is_me = (players[i]->user_profile == Online::CurrentUser::acquire());
|
||||
if (is_me)
|
||||
{
|
||||
NetworkPlayerProfile* profile = players[i];
|
||||
@ -127,7 +127,7 @@ void StartGameProtocol::update()
|
||||
}
|
||||
for (unsigned int i = 0; i < players.size(); i++)
|
||||
{
|
||||
bool is_me = (players[i]->user_profile == CurrentOnlineUser::get());
|
||||
bool is_me = (players[i]->user_profile == Online::CurrentUser::acquire());
|
||||
NetworkPlayerProfile* profile = players[i];
|
||||
RemoteKartInfo rki(profile->race_id, profile->kart_name,
|
||||
profile->user_profile->getUserName(), profile->race_id, !is_me);
|
||||
|
@ -19,8 +19,8 @@
|
||||
#include "network/protocols/start_server.hpp"
|
||||
|
||||
#include "network/network_manager.hpp"
|
||||
#include "online/current_online_user.hpp"
|
||||
#include "online/http_connector.hpp"
|
||||
#include "online/current_user.hpp"
|
||||
#include "online/http_manager.hpp"
|
||||
#include "config/user_config.hpp"
|
||||
|
||||
StartServer::StartServer() : Protocol(NULL, PROTOCOL_SILENT)
|
||||
@ -45,15 +45,21 @@ void StartServer::asynchronousUpdate()
|
||||
if (m_state == NONE)
|
||||
{
|
||||
TransportAddress addr = NetworkManager::getInstance()->getPublicAddress();
|
||||
HTTPConnector connector((std::string)UserConfigParams::m_server_multiplayer + "address-management.php");
|
||||
connector.setParameter("id",CurrentOnlineUser::get()->getUserID());
|
||||
connector.setParameter("token",CurrentOnlineUser::get()->getToken());
|
||||
connector.setParameter("address",addr.ip);
|
||||
connector.setParameter("port",addr.port);
|
||||
connector.setParameter("max_players",UserConfigParams::m_server_max_players);
|
||||
connector.setParameter("action","start-server");
|
||||
m_request = new Online::XMLRequest();
|
||||
m_request->setURL((std::string)UserConfigParams::m_server_multiplayer + "address-management.php");
|
||||
m_request->setParameter("id",Online::CurrentUser::acquire()->getUserID());
|
||||
m_request->setParameter("token",Online::CurrentUser::acquire()->getToken());
|
||||
m_request->setParameter("address",addr.ip);
|
||||
m_request->setParameter("port",addr.port);
|
||||
m_request->setParameter("max_players",UserConfigParams::m_server_max_players);
|
||||
m_request->setParameter("action","start-server");
|
||||
|
||||
const XMLNode * result = connector.getXMLFromPage();
|
||||
Online::HTTPManager::get()->addRequest(m_request);
|
||||
m_state = REQUEST_PENDING;
|
||||
}
|
||||
else if (m_state == REQUEST_PENDING && m_request->isDone())
|
||||
{
|
||||
const XMLNode * result = m_request->getResult();
|
||||
std::string rec_success;
|
||||
|
||||
if(result->get("success", &rec_success))
|
||||
@ -76,6 +82,8 @@ void StartServer::asynchronousUpdate()
|
||||
else if (m_state == DONE)
|
||||
{
|
||||
m_state = EXITING;
|
||||
delete m_request;
|
||||
m_request = NULL;
|
||||
m_listener->requestTerminate(this);
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
#define START_SERVER_HPP
|
||||
|
||||
#include "network/protocol.hpp"
|
||||
#include "online/request.hpp"
|
||||
|
||||
/*!
|
||||
* This protocol tells to the database that the server is up and running,
|
||||
@ -19,9 +20,11 @@ class StartServer : public Protocol
|
||||
virtual void asynchronousUpdate();
|
||||
|
||||
protected:
|
||||
Online::XMLRequest* m_request;
|
||||
enum STATE
|
||||
{
|
||||
NONE,
|
||||
REQUEST_PENDING,
|
||||
DONE,
|
||||
EXITING
|
||||
};
|
||||
|
@ -19,8 +19,8 @@
|
||||
#include "network/protocols/stop_server.hpp"
|
||||
|
||||
#include "network/network_manager.hpp"
|
||||
#include "online/current_online_user.hpp"
|
||||
#include "online/http_connector.hpp"
|
||||
#include "online/current_user.hpp"
|
||||
#include "online/http_manager.hpp"
|
||||
#include "config/user_config.hpp"
|
||||
|
||||
StopServer::StopServer() : Protocol(NULL, PROTOCOL_SILENT)
|
||||
@ -45,14 +45,20 @@ void StopServer::asynchronousUpdate()
|
||||
if (m_state == NONE)
|
||||
{
|
||||
TransportAddress addr = NetworkManager::getInstance()->getPublicAddress();
|
||||
HTTPConnector connector((std::string)UserConfigParams::m_server_multiplayer + "address-management.php");
|
||||
connector.setParameter("id",CurrentOnlineUser::get()->getUserID());
|
||||
connector.setParameter("token",CurrentOnlineUser::get()->getToken());
|
||||
connector.setParameter("address",addr.ip);
|
||||
connector.setParameter("port",addr.port);
|
||||
connector.setParameter("action","stop-server");
|
||||
m_request = new Online::XMLRequest();
|
||||
m_request->setURL((std::string)UserConfigParams::m_server_multiplayer + "address-management.php");
|
||||
m_request->setParameter("id",Online::CurrentUser::acquire()->getUserID());
|
||||
m_request->setParameter("token",Online::CurrentUser::acquire()->getToken());
|
||||
m_request->setParameter("address",addr.ip);
|
||||
m_request->setParameter("port",addr.port);
|
||||
m_request->setParameter("action","stop-server");
|
||||
|
||||
const XMLNode * result = connector.getXMLFromPage();
|
||||
Online::HTTPManager::get()->addRequest(m_request);
|
||||
m_state = REQUEST_PENDING;
|
||||
}
|
||||
else if (m_state == REQUEST_PENDING && m_request->isDone())
|
||||
{
|
||||
const XMLNode * result = m_request->getResult();
|
||||
std::string rec_success;
|
||||
|
||||
if(result->get("success", &rec_success))
|
||||
@ -75,6 +81,8 @@ void StopServer::asynchronousUpdate()
|
||||
else if (m_state == DONE)
|
||||
{
|
||||
m_state = EXITING;
|
||||
delete m_request;
|
||||
m_request = NULL;
|
||||
m_listener->requestTerminate(this);
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
#define STOP_SERVER_HPP
|
||||
|
||||
#include "network/protocol.hpp"
|
||||
|
||||
#include "online/request.hpp"
|
||||
|
||||
/*! \brief Removes the server info from the database
|
||||
*/
|
||||
@ -19,9 +19,11 @@ class StopServer : public Protocol
|
||||
virtual void asynchronousUpdate();
|
||||
|
||||
protected:
|
||||
Online::XMLRequest* m_request;
|
||||
enum STATE
|
||||
{
|
||||
NONE,
|
||||
REQUEST_PENDING,
|
||||
DONE,
|
||||
EXITING
|
||||
};
|
||||
|
@ -1,153 +0,0 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2013 Glenn De Jonghe
|
||||
//
|
||||
// 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 "online/current_online_user.hpp"
|
||||
|
||||
#include "config/user_config.hpp"
|
||||
#include "online/http_connector.hpp"
|
||||
#include "utils/translation.hpp"
|
||||
|
||||
#include <assert.h>
|
||||
#include <sstream>
|
||||
#include <stdlib.h>
|
||||
|
||||
static CurrentOnlineUser* user_singleton = NULL;
|
||||
|
||||
CurrentOnlineUser* CurrentOnlineUser::get()
|
||||
{
|
||||
if (user_singleton == NULL)
|
||||
user_singleton = new CurrentOnlineUser();
|
||||
return user_singleton;
|
||||
} // get
|
||||
|
||||
void CurrentOnlineUser::deallocate()
|
||||
{
|
||||
delete user_singleton;
|
||||
user_singleton = NULL;
|
||||
} // deallocate
|
||||
|
||||
// ============================================================================
|
||||
|
||||
|
||||
CurrentOnlineUser::CurrentOnlineUser(){
|
||||
m_is_signed_in = false;
|
||||
m_is_guest = false;
|
||||
m_id = 0;
|
||||
m_name = "";
|
||||
m_token = "";
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Register
|
||||
bool CurrentOnlineUser::signUp( const irr::core::stringw &username,
|
||||
const irr::core::stringw &password,
|
||||
const irr::core::stringw &password_ver,
|
||||
const irr::core::stringw &email,
|
||||
bool terms,
|
||||
irr::core::stringw &info)
|
||||
{
|
||||
assert(m_is_signed_in == false);
|
||||
HTTPConnector * connector = new HTTPConnector((std::string)UserConfigParams::m_server_multiplayer + "client-user.php");
|
||||
connector->setParameter("action",std::string("register"));
|
||||
connector->setParameter("username",username);
|
||||
connector->setParameter("password",password);
|
||||
|
||||
const XMLNode * result = connector->getXMLFromPage();
|
||||
std::string rec_success;
|
||||
|
||||
bool success = false;
|
||||
if(result->get("success", &rec_success))
|
||||
{
|
||||
success = (rec_success == "yes");
|
||||
assert(result->get("info", &info));
|
||||
}
|
||||
else
|
||||
{
|
||||
info = _("Unable to connect to the server. Check your internet connection or try again later.");
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
// ============================================================================
|
||||
|
||||
bool CurrentOnlineUser::signIn( const irr::core::stringw &username,
|
||||
const irr::core::stringw &password,
|
||||
irr::core::stringw &info)
|
||||
{
|
||||
assert(m_is_signed_in == false);
|
||||
HTTPConnector * connector = new HTTPConnector((std::string)UserConfigParams::m_server_multiplayer + "client-user.php");
|
||||
connector->setParameter("action",std::string("connect"));
|
||||
connector->setParameter("username",username);
|
||||
connector->setParameter("password",password);
|
||||
const XMLNode * result = connector->getXMLFromPage();
|
||||
std::string rec_success = "";
|
||||
if(result->get("success", &rec_success))
|
||||
{
|
||||
if (rec_success =="yes")
|
||||
{
|
||||
int token_fetched = result->get("token", &m_token);
|
||||
int username_fetched = result->get("username", &m_name);
|
||||
int userid_fetched = result->get("userid", &m_id);
|
||||
assert(token_fetched && username_fetched && userid_fetched);
|
||||
m_is_signed_in = true;
|
||||
m_is_guest = false;
|
||||
}
|
||||
result->get("info", &info);
|
||||
}
|
||||
else
|
||||
{
|
||||
info = _("Unable to connect to the server. Check your internet connection or try again later.");
|
||||
}
|
||||
|
||||
return m_is_signed_in;
|
||||
}
|
||||
// ============================================================================
|
||||
bool CurrentOnlineUser::signOut(){
|
||||
assert(m_is_signed_in == true);
|
||||
HTTPConnector * connector = new HTTPConnector((std::string)UserConfigParams::m_server_multiplayer + "client-user.php");
|
||||
connector->setParameter("action",std::string("disconnect"));
|
||||
connector->setParameter("token",m_token);
|
||||
connector->setParameter("userid",m_id);
|
||||
|
||||
const XMLNode * result = connector->getXMLFromPage();
|
||||
std::string rec_success = "";
|
||||
if(result->get("success", &rec_success))
|
||||
{
|
||||
if (rec_success =="yes")
|
||||
{
|
||||
m_token = "";
|
||||
m_name = "";
|
||||
m_id = 0;
|
||||
m_is_signed_in = false;
|
||||
m_is_guest = false;
|
||||
}
|
||||
}
|
||||
return !m_is_signed_in;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
|
||||
irr::core::stringw CurrentOnlineUser::getUserName() const
|
||||
{
|
||||
if(m_is_signed_in)
|
||||
return m_name;
|
||||
else
|
||||
return _("Currently not signed in");
|
||||
}
|
@ -1,72 +0,0 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2013 Glenn De Jonghe
|
||||
//
|
||||
// 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_CURRENT_ONLINE_USER_HPP
|
||||
#define HEADER_CURRENT_ONLINE_USER_HPP
|
||||
|
||||
#include "online/online_user.hpp"
|
||||
|
||||
#include <irrString.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* \brief Class that represents an online registered user
|
||||
* \ingroup online
|
||||
*/
|
||||
class CurrentOnlineUser : public OnlineUser
|
||||
{
|
||||
private:
|
||||
|
||||
protected:
|
||||
std::string m_token;
|
||||
bool m_is_signed_in;
|
||||
bool m_is_guest;
|
||||
CurrentOnlineUser();
|
||||
|
||||
public:
|
||||
// singleton
|
||||
static CurrentOnlineUser* get();
|
||||
static void deallocate();
|
||||
// Login
|
||||
bool signIn( const irr::core::stringw &username,
|
||||
const irr::core::stringw &password,
|
||||
irr::core::stringw &info);
|
||||
// Register
|
||||
bool signUp( const irr::core::stringw &username,
|
||||
const irr::core::stringw &password,
|
||||
const irr::core::stringw &password_ver,
|
||||
const irr::core::stringw &email,
|
||||
bool terms,
|
||||
irr::core::stringw &info);
|
||||
// Logout - Best to be followed by CurrentOnlineUser::deallocate
|
||||
bool signOut();
|
||||
/** Returns the username if signed in. */
|
||||
irr::core::stringw getUserName() const;
|
||||
std::string getToken() const { return m_token; }
|
||||
bool isSignedIn() { return m_is_signed_in; }
|
||||
bool isGuest() { return m_is_guest; }
|
||||
|
||||
}; // class CurrentOnlineUser
|
||||
|
||||
#endif
|
||||
|
||||
/*EOF*/
|
250
src/online/current_user.cpp
Normal file
250
src/online/current_user.cpp
Normal file
@ -0,0 +1,250 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2013 Glenn De Jonghe
|
||||
//
|
||||
// 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 "online/current_user.hpp"
|
||||
|
||||
#include <sstream>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include "config/user_config.hpp"
|
||||
#include "utils/translation.hpp"
|
||||
#include "utils/log.hpp"
|
||||
#include "online/servers_manager.hpp"
|
||||
|
||||
namespace Online{
|
||||
static Synchronised<CurrentUser*> user_singleton(NULL);
|
||||
|
||||
CurrentUser* CurrentUser::acquire()
|
||||
{
|
||||
user_singleton.lock();
|
||||
CurrentUser * user = user_singleton.getData();
|
||||
if (user == NULL)
|
||||
{
|
||||
user_singleton.unlock();
|
||||
user = new CurrentUser();
|
||||
user_singleton.setAtomic(user);
|
||||
user_singleton.lock();
|
||||
}
|
||||
return user;
|
||||
}
|
||||
|
||||
void CurrentUser::release()
|
||||
{
|
||||
user_singleton.unlock();
|
||||
}
|
||||
|
||||
void CurrentUser::deallocate()
|
||||
{
|
||||
user_singleton.lock();
|
||||
CurrentUser* user = user_singleton.getData();
|
||||
delete user;
|
||||
user = NULL;
|
||||
user_singleton.unlock();
|
||||
} // deallocate
|
||||
|
||||
// ============================================================================
|
||||
CurrentUser::CurrentUser(){
|
||||
m_state = US_SIGNED_OUT;
|
||||
m_id = 0;
|
||||
m_name = "";
|
||||
m_token = "";
|
||||
m_save_session = false;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
XMLRequest * CurrentUser::requestSignUp( const irr::core::stringw &username,
|
||||
const irr::core::stringw &password,
|
||||
const irr::core::stringw &password_confirm,
|
||||
const irr::core::stringw &email,
|
||||
bool terms)
|
||||
{
|
||||
assert(m_state == US_SIGNED_OUT || m_state == US_GUEST);
|
||||
XMLRequest * request = new XMLRequest();
|
||||
request->setURL((std::string)UserConfigParams::m_server_multiplayer + "client-user.php");
|
||||
request->setParameter("action", std::string("register"));
|
||||
request->setParameter("username", username);
|
||||
request->setParameter("password", password);
|
||||
request->setParameter("password_confirm", password_confirm);
|
||||
request->setParameter("email", email);
|
||||
request->setParameter("terms", std::string("on"));
|
||||
HTTPManager::get()->addRequest(request);
|
||||
return request;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
CurrentUser::SignInRequest * CurrentUser::requestSavedSession()
|
||||
{
|
||||
SignInRequest * request = NULL;
|
||||
if(m_state != US_SIGNED_IN && UserConfigParams::m_saved_session)
|
||||
{
|
||||
request = new SignInRequest();
|
||||
request->setURL((std::string)UserConfigParams::m_server_multiplayer + "client-user.php");
|
||||
request->setParameter("action",std::string("saved-session"));
|
||||
request->setParameter("userid", UserConfigParams::m_saved_user);
|
||||
request->setParameter("token", UserConfigParams::m_saved_token.c_str());
|
||||
HTTPManager::get()->addRequest(request);
|
||||
m_state = US_SIGNING_IN;
|
||||
}
|
||||
return request;
|
||||
}
|
||||
|
||||
CurrentUser::SignInRequest * CurrentUser::requestSignIn( const irr::core::stringw &username,
|
||||
const irr::core::stringw &password,
|
||||
bool save_session, bool request_now)
|
||||
{
|
||||
assert(m_state == US_SIGNED_OUT);
|
||||
m_save_session = save_session;
|
||||
SignInRequest * request = new SignInRequest();
|
||||
request->setURL((std::string)UserConfigParams::m_server_multiplayer + "client-user.php");
|
||||
request->setParameter("action",std::string("connect"));
|
||||
request->setParameter("username",username);
|
||||
request->setParameter("password",password);
|
||||
if (request_now)
|
||||
{
|
||||
HTTPManager::get()->addRequest(request);
|
||||
m_state = US_SIGNING_IN;
|
||||
}
|
||||
return request;
|
||||
}
|
||||
|
||||
void CurrentUser::signIn(const SignInRequest * input)
|
||||
{
|
||||
if (input->isSuccess())
|
||||
{
|
||||
int token_fetched = input->getResult()->get("token", &m_token);
|
||||
int username_fetched = input->getResult()->get("username", &m_name);
|
||||
int userid_fetched = input->getResult()->get("userid", &m_id);
|
||||
assert(token_fetched && username_fetched && userid_fetched);
|
||||
m_state = US_SIGNED_IN;
|
||||
if(m_save_session)
|
||||
{
|
||||
UserConfigParams::m_saved_user = m_id;
|
||||
UserConfigParams::m_saved_token = m_token;
|
||||
UserConfigParams::m_saved_session = true;
|
||||
m_save_session = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
m_state = US_SIGNED_OUT;
|
||||
}
|
||||
|
||||
void CurrentUser::SignInRequest::callback()
|
||||
{
|
||||
CurrentUser::acquire()->signIn(this);
|
||||
CurrentUser::release();
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
|
||||
CurrentUser::ServerCreationRequest * CurrentUser::requestServerCreation(const irr::core::stringw &name, int max_players)
|
||||
{
|
||||
assert(m_state == US_SIGNED_IN);
|
||||
ServerCreationRequest * request = new ServerCreationRequest();
|
||||
request->setURL((std::string)UserConfigParams::m_server_multiplayer + "client-user.php");
|
||||
request->setParameter("action", std::string("create_server"));
|
||||
request->setParameter("token", m_token);
|
||||
request->setParameter("userid", m_id);
|
||||
request->setParameter("name", name);
|
||||
request->setParameter("max_players", max_players);
|
||||
HTTPManager::get()->addRequest(request);
|
||||
return request;
|
||||
}
|
||||
|
||||
void CurrentUser::ServerCreationRequest::callback()
|
||||
{
|
||||
if(isSuccess())
|
||||
{
|
||||
Server * server = new Server(*getResult()->getNode("server"));
|
||||
ServersManager::acquire()->addServer(server);
|
||||
ServersManager::release();
|
||||
m_created_server_id.setAtomic(server->getServerId());
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
CurrentUser::SignOutRequest * CurrentUser::requestSignOut(){
|
||||
assert(m_state == US_SIGNED_IN || m_state == US_GUEST);
|
||||
SignOutRequest * request = new SignOutRequest();
|
||||
request->setURL((std::string)UserConfigParams::m_server_multiplayer + "client-user.php");
|
||||
request->setParameter("action",std::string("disconnect"));
|
||||
request->setParameter("token",m_token);
|
||||
request->setParameter("userid",m_id);
|
||||
HTTPManager::get()->addRequest(request);
|
||||
m_state = US_SIGNING_OUT;
|
||||
return request;
|
||||
}
|
||||
|
||||
void CurrentUser::signOut(const SignOutRequest * input)
|
||||
{
|
||||
if(!input->isSuccess())
|
||||
{
|
||||
Log::warn("CurrentUser::signOut", "%s", _("There were some connection issues while signing out. Report a bug if this caused issues."));
|
||||
}
|
||||
m_token = "";
|
||||
m_name = "";
|
||||
m_id = 0;
|
||||
m_state = US_SIGNED_OUT;
|
||||
UserConfigParams::m_saved_user = 0;
|
||||
UserConfigParams::m_saved_token = "";
|
||||
UserConfigParams::m_saved_session = false;
|
||||
}
|
||||
|
||||
void CurrentUser::SignOutRequest::callback()
|
||||
{
|
||||
CurrentUser::acquire()->signOut(this);
|
||||
CurrentUser::release();
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
|
||||
CurrentUser::ServerJoinRequest * CurrentUser::requestServerJoin(uint32_t server_id){
|
||||
assert(m_state == US_SIGNED_IN || m_state == US_GUEST);
|
||||
ServerJoinRequest * request = new ServerJoinRequest();
|
||||
request->setURL((std::string)UserConfigParams::m_server_multiplayer + "address-management.php");
|
||||
request->setParameter("action",std::string("request-connection"));
|
||||
request->setParameter("token", m_token);
|
||||
request->setParameter("id", m_id);
|
||||
request->setParameter("server_id", server_id);
|
||||
HTTPManager::get()->addRequest(request);
|
||||
return request;
|
||||
}
|
||||
|
||||
void CurrentUser::ServerJoinRequest::callback()
|
||||
{
|
||||
if(isSuccess())
|
||||
{
|
||||
uint32_t server_id;
|
||||
getResult()->get("serverid", &server_id);
|
||||
ServersManager::acquire()->setJoinedServer(server_id);
|
||||
ServersManager::release();
|
||||
}
|
||||
//FIXME needs changes for actual valid joining
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
|
||||
irr::core::stringw CurrentUser::getUserName() const
|
||||
{
|
||||
if((m_state == US_SIGNED_IN ) || (m_state == US_GUEST))
|
||||
return m_name;
|
||||
else
|
||||
return _("Currently not signed in");
|
||||
}
|
||||
|
||||
} // namespace Online
|
136
src/online/current_user.hpp
Normal file
136
src/online/current_user.hpp
Normal file
@ -0,0 +1,136 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2013 Glenn De Jonghe
|
||||
//
|
||||
// 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_CURRENT_ONLINE_USER_HPP
|
||||
#define HEADER_CURRENT_ONLINE_USER_HPP
|
||||
|
||||
#include "online/user.hpp"
|
||||
#include <string>
|
||||
#include <irrString.h>
|
||||
#include "utils/types.hpp"
|
||||
#include "online/server.hpp"
|
||||
#include "http_manager.hpp"
|
||||
|
||||
|
||||
namespace Online{
|
||||
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* \brief Class that represents an online registered user
|
||||
* \ingroup online
|
||||
*/
|
||||
class CurrentUser : public User
|
||||
{
|
||||
public:
|
||||
enum UserState
|
||||
{
|
||||
US_SIGNED_OUT,
|
||||
US_SIGNED_IN,
|
||||
US_GUEST,
|
||||
US_SIGNING_IN,
|
||||
US_SIGNING_OUT
|
||||
};
|
||||
|
||||
enum RequestType
|
||||
{
|
||||
RT_SIGN_IN = 1,
|
||||
RT_SIGN_OUT,
|
||||
RT_SIGN_UP,
|
||||
RT_SERVER_JOIN,
|
||||
RT_SERVER_CREATION
|
||||
};
|
||||
|
||||
class SignInRequest : public XMLRequest
|
||||
{
|
||||
virtual void callback ();
|
||||
public:
|
||||
SignInRequest() : XMLRequest(RT_SIGN_IN) {}
|
||||
};
|
||||
|
||||
class SignOutRequest : public XMLRequest
|
||||
{
|
||||
virtual void callback ();
|
||||
public:
|
||||
SignOutRequest() : XMLRequest(RT_SIGN_OUT) {}
|
||||
};
|
||||
|
||||
class ServerCreationRequest : public XMLRequest {
|
||||
virtual void callback ();
|
||||
Synchronised<uint32_t> m_created_server_id;
|
||||
public:
|
||||
ServerCreationRequest() : XMLRequest(RT_SERVER_CREATION) {}
|
||||
uint32_t getCreatedServerID() {return m_created_server_id.getAtomic();}
|
||||
};
|
||||
|
||||
class ServerJoinRequest : public XMLRequest {
|
||||
virtual void callback ();
|
||||
public:
|
||||
ServerJoinRequest() : XMLRequest(RT_SERVER_JOIN) {}
|
||||
};
|
||||
|
||||
|
||||
private:
|
||||
std::string m_token;
|
||||
bool m_save_session;
|
||||
UserState m_state;
|
||||
|
||||
CurrentUser();
|
||||
|
||||
void signIn (const SignInRequest * input);
|
||||
void signOut (const SignOutRequest * input);
|
||||
void createServer (const ServerCreationRequest * input);
|
||||
|
||||
public:
|
||||
//Singleton
|
||||
static CurrentUser* acquire();
|
||||
static void release();
|
||||
static void deallocate();
|
||||
|
||||
SignInRequest * requestSavedSession();
|
||||
SignInRequest * requestSignIn( const irr::core::stringw &username,
|
||||
const irr::core::stringw &password,
|
||||
bool save_session,
|
||||
bool request_now = true);
|
||||
SignOutRequest * requestSignOut();
|
||||
ServerCreationRequest * requestServerCreation( const irr::core::stringw &name, int max_players);
|
||||
ServerJoinRequest * requestServerJoin( uint32_t server_id);
|
||||
|
||||
|
||||
// Register
|
||||
XMLRequest * requestSignUp( const irr::core::stringw &username,
|
||||
const irr::core::stringw &password,
|
||||
const irr::core::stringw &password_ver,
|
||||
const irr::core::stringw &email,
|
||||
bool terms);
|
||||
|
||||
/** Returns the username if signed in. */
|
||||
irr::core::stringw getUserName() const;
|
||||
bool isSignedIn() const { return m_state == US_SIGNED_IN; }
|
||||
bool isGuest() const { return m_state == US_GUEST; }
|
||||
bool isSigningIn() const { return m_state == US_SIGNING_IN; }
|
||||
UserState getUserState() { return m_state; }
|
||||
std::string getToken() const { return m_token; }
|
||||
|
||||
}; // class CurrentUser
|
||||
|
||||
} // namespace Online
|
||||
|
||||
#endif
|
||||
|
||||
/*EOF*/
|
@ -1,88 +0,0 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2013 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 "http_connector.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <stdio.h>
|
||||
#include <memory.h>
|
||||
#include "io/file_manager.hpp"
|
||||
|
||||
|
||||
HTTPConnector::HTTPConnector(const std::string &url){
|
||||
curl_global_init(CURL_GLOBAL_DEFAULT);
|
||||
curl = curl_easy_init();
|
||||
if(!curl)
|
||||
Log::error("online/http_functions", "Error while loading cURL library.");
|
||||
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
|
||||
if (url.substr(0, 5)!="http:")
|
||||
{
|
||||
Log::error("online/http_functions", "Invalid URL.");
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
|
||||
|
||||
HTTPConnector::~HTTPConnector(){
|
||||
curl_easy_cleanup(curl);
|
||||
curl_global_cleanup();
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
|
||||
static size_t WriteCallback(void *contents, size_t size, size_t nmemb, void *userp)
|
||||
{
|
||||
((std::string*)userp)->append((char*)contents, size * nmemb);
|
||||
return size * nmemb;
|
||||
}
|
||||
|
||||
XMLNode * HTTPConnector::getXMLFromPage()
|
||||
{
|
||||
return file_manager->createXMLTreeFromString(getPage());
|
||||
}
|
||||
|
||||
std::string HTTPConnector::getPage()
|
||||
{
|
||||
|
||||
Parameters::iterator iter;
|
||||
std::string postString = "";
|
||||
for (iter = m_parameters.begin(); iter != m_parameters.end(); ++iter)
|
||||
{
|
||||
if(iter != m_parameters.begin())
|
||||
postString.append("&");
|
||||
char * escaped = curl_easy_escape(this->curl , iter->first.c_str(), iter->first.size());
|
||||
postString.append(escaped);
|
||||
curl_free(escaped);
|
||||
postString.append("=");
|
||||
escaped = curl_easy_escape(this->curl , iter->second.c_str(), iter->second.size());
|
||||
postString.append(escaped);
|
||||
curl_free(escaped);
|
||||
}
|
||||
curl_easy_setopt(this->curl, CURLOPT_POSTFIELDS, postString.c_str());
|
||||
std::string readBuffer;
|
||||
curl_easy_setopt(this->curl, CURLOPT_WRITEFUNCTION, WriteCallback);
|
||||
curl_easy_setopt(this->curl, CURLOPT_FILE, &readBuffer);
|
||||
res = curl_easy_perform(this->curl);
|
||||
if(res != CURLE_OK)
|
||||
Log::error("online/http_functions", "curl_easy_perform() failed: \"%s\"", curl_easy_strerror(res));
|
||||
else
|
||||
Log::verbose("online/http_functions", "Received : \"%s\"", readBuffer.c_str());
|
||||
m_parameters.clear();
|
||||
return readBuffer;
|
||||
}
|
@ -1,70 +0,0 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2013 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 HTTP_CONNECTOR_HPP
|
||||
#define HTTP_CONNECTOR_HPP
|
||||
|
||||
#include "io/xml_node.hpp"
|
||||
#include "utils/string_utils.hpp"
|
||||
|
||||
#include <irrString.h>
|
||||
#ifdef WIN32
|
||||
# include <WinSock2.h>
|
||||
#endif
|
||||
#include <curl/curl.h>
|
||||
#include <string>
|
||||
|
||||
/**
|
||||
* \brief Class to connect with a server over HTTP
|
||||
* \ingroup online
|
||||
*/
|
||||
class HTTPConnector
|
||||
{
|
||||
protected:
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
typedef std::map<std::string, std::string> Parameters;
|
||||
Parameters m_parameters;
|
||||
|
||||
public:
|
||||
|
||||
HTTPConnector(const std::string &url);
|
||||
~HTTPConnector();
|
||||
|
||||
//Execute
|
||||
std::string getPage();
|
||||
XMLNode * getXMLFromPage();
|
||||
|
||||
//Setting parameters to be send with the next request
|
||||
void setParameter(const std::string & name, const std::string &value){
|
||||
m_parameters[name] = value;
|
||||
};
|
||||
void setParameter(const std::string & name, const irr::core::stringw &value){
|
||||
m_parameters[name] = irr::core::stringc(value.c_str()).c_str();
|
||||
}
|
||||
template <typename T>
|
||||
void setParameter(const std::string & name, const T& value){
|
||||
m_parameters[name] = StringUtils::toString(value);
|
||||
}
|
||||
|
||||
}; //class HTTPConnector
|
||||
|
||||
|
||||
#endif // HTTP_CONNECTOR_HPP
|
||||
|
||||
/*EOF*/
|
222
src/online/http_manager.cpp
Normal file
222
src/online/http_manager.cpp
Normal file
@ -0,0 +1,222 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2013 Glenn De Jonghe
|
||||
//
|
||||
// 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 "online/http_manager.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <stdio.h>
|
||||
#include <memory.h>
|
||||
#include <errno.h>
|
||||
|
||||
#if defined(WIN32) && !defined(__CYGWIN__)
|
||||
# include <windows.h>
|
||||
# define isnan _isnan
|
||||
#else
|
||||
# include <sys/time.h>
|
||||
# include <math.h>
|
||||
#endif
|
||||
|
||||
#if defined(WIN32) && !defined(__CYGWIN__)
|
||||
// Use Sleep, which takes time in msecs. It must be defined after the
|
||||
// includes, since otherwise irrlicht's sleep function is changed.
|
||||
# define sleep(s) Sleep(1000*(s))
|
||||
#else
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
namespace Online{
|
||||
|
||||
static HTTPManager * http_singleton = NULL;
|
||||
|
||||
HTTPManager* HTTPManager::get()
|
||||
{
|
||||
if (http_singleton == NULL)
|
||||
{
|
||||
http_singleton = new HTTPManager();
|
||||
http_singleton->startNetworkThread();
|
||||
}
|
||||
return http_singleton;
|
||||
} // get
|
||||
|
||||
void HTTPManager::deallocate()
|
||||
{
|
||||
delete http_singleton;
|
||||
http_singleton = NULL;
|
||||
} // deallocate
|
||||
|
||||
bool HTTPManager::isRunning()
|
||||
{
|
||||
return http_singleton != NULL;
|
||||
}
|
||||
|
||||
|
||||
HTTPManager::HTTPManager(){
|
||||
curl_global_init(CURL_GLOBAL_DEFAULT);
|
||||
pthread_cond_init(&m_cond_request, NULL);
|
||||
m_abort.setAtomic(false);
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
HTTPManager::~HTTPManager(){
|
||||
curl_global_cleanup();
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
/** Start the actual network thread. This can not be done as part of
|
||||
* the constructor, since the assignment to the global network_http
|
||||
* variable has not been assigned at that stage, and the thread might
|
||||
* use network_http - a very subtle race condition. So the thread can
|
||||
* only be started after the assignment (in main) has been done.
|
||||
*/
|
||||
void HTTPManager::startNetworkThread()
|
||||
{
|
||||
pthread_attr_t attr;
|
||||
pthread_attr_init(&attr);
|
||||
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
|
||||
// Should be the default, but just in case:
|
||||
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
|
||||
//pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
|
||||
|
||||
m_thread_id.setAtomic(new pthread_t());
|
||||
int error = pthread_create(m_thread_id.getData(), &attr,
|
||||
&HTTPManager::mainLoop, this);
|
||||
if(error)
|
||||
{
|
||||
m_thread_id.lock();
|
||||
delete m_thread_id.getData();
|
||||
m_thread_id.unlock();
|
||||
m_thread_id.setAtomic(0);
|
||||
Log::error("HTTP Manager", "Could not create thread, error=%d.\n", errno);
|
||||
}
|
||||
pthread_attr_destroy(&attr);
|
||||
} // startNetworkThread
|
||||
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
/** This function inserts a high priority request to quit into the request
|
||||
* queue of the network thead, and also aborts any ongoing download.
|
||||
* Separating this allows more time for the thread to finish cleanly,
|
||||
* before it gets cancelled in the destructor.
|
||||
*/
|
||||
void HTTPManager::stopNetworkThread()
|
||||
{
|
||||
// If a download should be active (which means it was cancelled by the
|
||||
// user, in which case it will still be ongoing in the background)
|
||||
// we can't get the mutex, and would have to wait for a timeout,
|
||||
// and we couldn't finish STK. This way we request an abort of
|
||||
// a download, which mean we can get the mutex and ask the service
|
||||
// thread here to cancel properly.
|
||||
cancelAllDownloads();
|
||||
addRequest(new Request(true, 9999, Request::RT_QUIT));
|
||||
} // stopNetworkThread
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Signals to the progress function to request any ongoing download to be
|
||||
* cancelled. This function can also be called if there is actually no
|
||||
* download atm. The function progressDownload checks m_abort and will
|
||||
* return a non-zero value which causes libcurl to abort. */
|
||||
void HTTPManager::cancelAllDownloads()
|
||||
{
|
||||
m_abort.setAtomic(true);
|
||||
} // cancelAllDownloads
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Inserts a request into the queue of all requests. The request will be
|
||||
* sorted by priority.
|
||||
* \param request The pointer to the new request to insert.
|
||||
*/
|
||||
void HTTPManager::addRequest(Request *request)
|
||||
{
|
||||
assert(request->isAllowedToAdd());
|
||||
m_request_queue.lock();
|
||||
m_request_queue.getData().push(request);
|
||||
// Wake up the network http thread
|
||||
pthread_cond_signal(&m_cond_request);
|
||||
m_request_queue.unlock();
|
||||
} // addRequest
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Immediately performs a request synchronously
|
||||
* \param request The pointer to the new request to insert.
|
||||
*/
|
||||
void HTTPManager::synchronousRequest(Request *request)
|
||||
{
|
||||
assert(request->isAllowedToAdd());
|
||||
request->execute();
|
||||
} // synchronousRequest
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
/** The actual main loop, which is started as a separate thread from the
|
||||
* constructor. After testing for a new server, fetching news, the list
|
||||
* of packages to download, it will wait for commands to be issued.
|
||||
* \param obj: A pointer to this object, passed on by pthread_create
|
||||
*/
|
||||
void *HTTPManager::mainLoop(void *obj)
|
||||
{
|
||||
HTTPManager *me = (HTTPManager*) obj;
|
||||
|
||||
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
|
||||
|
||||
me->m_current_request = NULL;
|
||||
me->m_request_queue.lock();
|
||||
while( me->m_request_queue.getData().empty() || me->m_request_queue.getData().top()->getType() != Request::RT_QUIT)
|
||||
{
|
||||
bool empty = me->m_request_queue.getData().empty();
|
||||
// Wait in cond_wait for a request to arrive. The 'while' is necessary
|
||||
// since "spurious wakeups from the pthread_cond_wait ... may occur"
|
||||
// (pthread_cond_wait man page)!
|
||||
while(empty)
|
||||
{
|
||||
pthread_cond_wait(&me->m_cond_request, me->m_request_queue.getMutex());
|
||||
empty = me->m_request_queue.getData().empty();
|
||||
}
|
||||
me->m_current_request = me->m_request_queue.getData().top();
|
||||
me->m_request_queue.getData().pop();
|
||||
me->m_request_queue.unlock();
|
||||
me->m_current_request->execute();
|
||||
if(me->m_current_request->manageMemory())
|
||||
{
|
||||
delete me->m_current_request;
|
||||
me->m_current_request = NULL;
|
||||
}
|
||||
me->m_request_queue.lock();
|
||||
} // while
|
||||
|
||||
// At this stage we have the lock for m_request_queue
|
||||
while(!me->m_request_queue.getData().empty())
|
||||
{
|
||||
Online::Request * request = me->m_request_queue.getData().top();
|
||||
me->m_request_queue.getData().pop();
|
||||
// Manage memory can be ignored here, all requests
|
||||
// need to be freed.
|
||||
delete request;
|
||||
}
|
||||
me->m_request_queue.unlock();
|
||||
|
||||
pthread_exit(NULL);
|
||||
return 0;
|
||||
} // mainLoop
|
||||
} // namespace Online
|
||||
|
||||
|
||||
|
||||
|
98
src/online/http_manager.hpp
Normal file
98
src/online/http_manager.hpp
Normal file
@ -0,0 +1,98 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2013 Glenn De Jonghe
|
||||
//
|
||||
// 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 HTTP_MANAGER_HPP
|
||||
#define HTTP_MANAGER_HPP
|
||||
|
||||
#include <string>
|
||||
#include <curl/curl.h>
|
||||
#include <irrString.h>
|
||||
#include <queue>
|
||||
#include <pthread.h>
|
||||
|
||||
#ifdef WIN32
|
||||
# include <winsock2.h>
|
||||
#endif
|
||||
|
||||
#include "io/xml_node.hpp"
|
||||
#include "utils/string_utils.hpp"
|
||||
#include "utils/synchronised.hpp"
|
||||
#include "online/request.hpp"
|
||||
|
||||
namespace Online{
|
||||
|
||||
/**
|
||||
* \brief Class to connect with a server over HTTP
|
||||
* \ingroup online
|
||||
*/
|
||||
class HTTPManager
|
||||
{
|
||||
protected:
|
||||
|
||||
/** Ment for networking threads */
|
||||
|
||||
/** The current requested being worked on. */
|
||||
Online::Request * m_current_request;
|
||||
|
||||
/** A conditional variable to wake up the main loop. */
|
||||
pthread_cond_t m_cond_request;
|
||||
|
||||
/** Signal an abort in case that a download is still happening. */
|
||||
Synchronised<bool> m_abort;
|
||||
|
||||
/** Thread id of the thread running in this object. */
|
||||
Synchronised<pthread_t *> m_thread_id;
|
||||
|
||||
/** The list of pointers to all requests that still need to be handled. */
|
||||
Synchronised< std::priority_queue <
|
||||
Online::Request*,
|
||||
std::vector<Online::Request*>,
|
||||
Online::Request::Compare
|
||||
>
|
||||
> m_request_queue;
|
||||
|
||||
static void *mainLoop(void *obj);
|
||||
void startNetworkThread();
|
||||
|
||||
HTTPManager(); //const std::string &url
|
||||
~HTTPManager();
|
||||
|
||||
public:
|
||||
|
||||
// singleton
|
||||
static HTTPManager* get();
|
||||
static void deallocate();
|
||||
static bool isRunning();
|
||||
|
||||
//Execute
|
||||
std::string getPage(Online::Request * request);
|
||||
XMLNode * getXMLFromPage(Online::Request * request);
|
||||
|
||||
void synchronousRequest(Online::Request *request);
|
||||
void addRequest(Online::Request *request);
|
||||
void cancelAllDownloads();
|
||||
void stopNetworkThread();
|
||||
|
||||
bool getAbort(){ return m_abort.getAtomic(); };
|
||||
|
||||
}; //class HTTPManager
|
||||
} // namespace Online
|
||||
|
||||
#endif // HTTP_MANAGER_HPP
|
||||
|
||||
/*EOF*/
|
78
src/online/messages.cpp
Normal file
78
src/online/messages.cpp
Normal file
@ -0,0 +1,78 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2013 Glenn De Jonghe
|
||||
//
|
||||
// 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 "online/messages.hpp"
|
||||
#include "utils/translation.hpp"
|
||||
#include "utils/time.hpp"
|
||||
|
||||
namespace Online
|
||||
{
|
||||
namespace Messages
|
||||
{
|
||||
irr::core::stringw signingIn()
|
||||
{
|
||||
return irr::core::stringw(_("Signing in")) + loadingDots();
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
irr::core::stringw signingOut()
|
||||
{
|
||||
return irr::core::stringw(_("Signing out")) + loadingDots();
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
irr::core::stringw signingUp()
|
||||
{
|
||||
return irr::core::stringw(_("Validating registration info")) + loadingDots();
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
irr::core::stringw signedInAs(const irr::core::stringw & name)
|
||||
{
|
||||
return irr::core::stringw(_("Signed in as : ")) + name + ".";
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
irr::core::stringw joiningServer()
|
||||
{
|
||||
return irr::core::stringw(_("Joining server")) + loadingDots();
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
irr::core::stringw creatingServer()
|
||||
{
|
||||
return irr::core::stringw(_("Creating server")) + loadingDots();
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
irr::core::stringw fetchingServers()
|
||||
{
|
||||
return irr::core::stringw(_("Fetching servers")) + loadingDots();
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
irr::core::stringw loadingDots(bool spaces, float interval, int max_dots)
|
||||
{
|
||||
int nr_dots = int(floor(Time::getRealTime() * (1 / interval))) % (max_dots+1);
|
||||
return irr::core::stringw((std::string(nr_dots,'.') + std::string(max_dots-nr_dots,' ')).c_str());
|
||||
}
|
||||
} // namespace messages
|
||||
} // namespace Online
|
||||
|
||||
|
||||
/* EOF */
|
41
src/online/messages.hpp
Normal file
41
src/online/messages.hpp
Normal file
@ -0,0 +1,41 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2013 Glenn De Jonghe
|
||||
//
|
||||
// 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_ONLINE_MESSAGES_HPP
|
||||
#define HEADER_ONLINE_MESSAGES_HPP
|
||||
|
||||
#include <string>
|
||||
#include <irrString.h>
|
||||
|
||||
namespace Online
|
||||
{
|
||||
namespace Messages
|
||||
{
|
||||
irr::core::stringw loadingDots (bool spaces = true, float interval = 0.5f, int max_dots = 3);
|
||||
irr::core::stringw signingIn ();
|
||||
irr::core::stringw signingOut ();
|
||||
irr::core::stringw signingUp ();
|
||||
irr::core::stringw joiningServer ();
|
||||
irr::core::stringw creatingServer ();
|
||||
irr::core::stringw fetchingServers ();
|
||||
irr::core::stringw signedInAs (const irr::core::stringw & name);
|
||||
} // namespace Messages
|
||||
}// namespace Online
|
||||
#endif
|
||||
|
||||
/* EOF */
|
234
src/online/request.cpp
Normal file
234
src/online/request.cpp
Normal file
@ -0,0 +1,234 @@
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2013 Glenn De Jonghe
|
||||
// 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 "online/request.hpp"
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include <assert.h>
|
||||
#include <online/http_manager.hpp>
|
||||
#include <utils/translation.hpp>
|
||||
|
||||
|
||||
namespace Online{
|
||||
|
||||
class HTTPManager;
|
||||
|
||||
// =========================================================================================
|
||||
|
||||
Request::Request(int type, bool manage_memory, int priority)
|
||||
: m_type(type), m_manage_memory(manage_memory), m_priority(priority)
|
||||
{
|
||||
m_cancel.setAtomic(false);
|
||||
m_done.setAtomic(false);
|
||||
} // Request
|
||||
|
||||
Request::~Request()
|
||||
{
|
||||
}
|
||||
|
||||
void Request::execute()
|
||||
{
|
||||
beforeOperation();
|
||||
operation();
|
||||
afterOperation();
|
||||
}
|
||||
|
||||
void Request::afterOperation()
|
||||
{
|
||||
m_done.setAtomic(true);
|
||||
}
|
||||
|
||||
// =========================================================================================
|
||||
|
||||
HTTPRequest::HTTPRequest(int type, bool manage_memory, int priority)
|
||||
: Request(priority, manage_memory, type)
|
||||
{
|
||||
//Negative numbers are reserved for special requests ment for the HTTP Manager
|
||||
assert(type >= 0);
|
||||
m_url.setAtomic("");
|
||||
m_parameters = new Parameters;
|
||||
m_progress.setAtomic(0);
|
||||
}
|
||||
|
||||
HTTPRequest::~HTTPRequest()
|
||||
{
|
||||
delete m_parameters;
|
||||
}
|
||||
|
||||
bool HTTPRequest::isAllowedToAdd()
|
||||
{
|
||||
bool ok = true;
|
||||
m_url.lock();
|
||||
if (m_url.getData().size() > 5 && ( m_url.getData().substr(0, 5) != "http:"))
|
||||
ok = false;
|
||||
m_url.unlock();
|
||||
return ok;
|
||||
}
|
||||
|
||||
void HTTPRequest::afterOperation()
|
||||
{
|
||||
callback();
|
||||
Request::afterOperation();
|
||||
}
|
||||
|
||||
std::string HTTPRequest::downloadPage()
|
||||
{
|
||||
CURL * curl_session;
|
||||
curl_session = curl_easy_init();
|
||||
if(!curl_session)
|
||||
{
|
||||
Log::error("online/http_functions", "Error while initialising libCurl session");
|
||||
return "";
|
||||
}
|
||||
curl_easy_setopt(curl_session, CURLOPT_URL, m_url.getAtomic().c_str());
|
||||
Parameters::iterator iter;
|
||||
std::string postString = "";
|
||||
for (iter = m_parameters->begin(); iter != m_parameters->end(); ++iter)
|
||||
{
|
||||
if(iter != m_parameters->begin())
|
||||
postString.append("&");
|
||||
char * escaped = curl_easy_escape(curl_session , iter->first.c_str(), iter->first.size());
|
||||
postString.append(escaped);
|
||||
curl_free(escaped);
|
||||
postString.append("=");
|
||||
escaped = curl_easy_escape(curl_session , iter->second.c_str(), iter->second.size());
|
||||
postString.append(escaped);
|
||||
curl_free(escaped);
|
||||
}
|
||||
curl_easy_setopt(curl_session, CURLOPT_POSTFIELDS, postString.c_str());
|
||||
std::string readBuffer;
|
||||
curl_easy_setopt(curl_session, CURLOPT_WRITEFUNCTION, &HTTPRequest::WriteCallback);
|
||||
curl_easy_setopt(curl_session, CURLOPT_NOPROGRESS, 0);
|
||||
curl_easy_setopt(curl_session, CURLOPT_PROGRESSDATA, this);
|
||||
curl_easy_setopt(curl_session, CURLOPT_PROGRESSFUNCTION, &HTTPRequest::progressDownload);
|
||||
curl_easy_setopt(curl_session, CURLOPT_FILE, &readBuffer);
|
||||
// Timeout
|
||||
// Reduce the connection phase timeout (it's 300 by default).
|
||||
// Add a low speed limit to have a sort of timeout in the
|
||||
// download phase. Being under 10 B/s during a certain time will
|
||||
// probably only happen when no access to the net is available.
|
||||
// The timeout is set to 20s, it should be enough to not produce
|
||||
// false positive error.
|
||||
curl_easy_setopt(curl_session, CURLOPT_CONNECTTIMEOUT, 20);
|
||||
curl_easy_setopt(curl_session, CURLOPT_LOW_SPEED_LIMIT, 10);
|
||||
curl_easy_setopt(curl_session, CURLOPT_LOW_SPEED_TIME, 20);
|
||||
CURLcode res = curl_easy_perform(curl_session);
|
||||
if(res == CURLE_OK)
|
||||
{
|
||||
Log::info("online/http_functions", "Received : %s", readBuffer.c_str());
|
||||
setProgress(1.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
Log::error("HTTPRequest::downloadPage", "curl_easy_perform() failed: %s", curl_easy_strerror(res));
|
||||
setProgress(-1.0f);
|
||||
}
|
||||
curl_easy_cleanup(curl_session);
|
||||
return readBuffer;
|
||||
}
|
||||
|
||||
|
||||
size_t HTTPRequest::WriteCallback(void *contents, size_t size, size_t nmemb, void *userp)
|
||||
{
|
||||
((std::string*)userp)->append((char*)contents, size * nmemb);
|
||||
return size * nmemb;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Callback function from curl: inform about progress.
|
||||
* \param clientp
|
||||
* \param download_total Total size of data to download.
|
||||
* \param download_now How much has been downloaded so far.
|
||||
* \param upload_total Total amount of upload.
|
||||
* \param upload_now How muc has been uploaded so far.
|
||||
*/
|
||||
int HTTPRequest::progressDownload(void *clientp,
|
||||
double download_total, double download_now,
|
||||
double upload_total, double upload_now)
|
||||
{
|
||||
HTTPRequest *request = (HTTPRequest *)clientp;
|
||||
|
||||
HTTPManager* http_manager = HTTPManager::get();
|
||||
|
||||
// Check if we are asked to abort the download. If so, signal this
|
||||
// back to libcurl by returning a non-zero status.
|
||||
if(http_manager->getAbort() || request->isCancelled() )
|
||||
{
|
||||
// Indicates to abort the current download, which means that this
|
||||
// thread will go back to the mainloop and handle the next request.
|
||||
return 1;
|
||||
}
|
||||
|
||||
float f;
|
||||
if(download_now < download_total)
|
||||
{
|
||||
f = (float)download_now / (float)download_total;
|
||||
// In case of floating point rouding errors make sure that
|
||||
// 1.0 is only reached when downloadFileInternal is finished
|
||||
if (f>=1.0f) f=0.99f;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Don't set progress to 1.0f; this is done in loadFileInternal
|
||||
// after checking curls return code!
|
||||
f= download_total==0 ? 0 : 0.99f;
|
||||
}
|
||||
request->setProgress(f);
|
||||
return 0;
|
||||
} // progressDownload
|
||||
|
||||
|
||||
|
||||
// =========================================================================================
|
||||
|
||||
XMLRequest::XMLRequest(int type, bool manage_memory, int priority)
|
||||
: HTTPRequest(priority, manage_memory, type)
|
||||
{
|
||||
m_info.setAtomic("");
|
||||
m_success.setAtomic(false);
|
||||
m_result = NULL;
|
||||
}
|
||||
|
||||
XMLRequest::~XMLRequest()
|
||||
{
|
||||
delete m_result;
|
||||
}
|
||||
|
||||
|
||||
void XMLRequest::operation()
|
||||
{
|
||||
m_result = file_manager->createXMLTreeFromString(downloadPage());
|
||||
}
|
||||
|
||||
void XMLRequest::afterOperation()
|
||||
{
|
||||
const XMLNode * xml = this->getResult();
|
||||
bool success = false;
|
||||
irr::core::stringw info;
|
||||
std::string rec_success;
|
||||
if(xml->get("success", &rec_success))
|
||||
{
|
||||
if (rec_success =="yes")
|
||||
success = true;
|
||||
xml->get("info", &info);
|
||||
}
|
||||
else
|
||||
info = _("Unable to connect to the server. Check your internet connection or try again later.");
|
||||
m_info.setAtomic(info);
|
||||
m_success.setAtomic(success);
|
||||
HTTPRequest::afterOperation();
|
||||
}
|
||||
} // namespace Online
|
208
src/online/request.hpp
Normal file
208
src/online/request.hpp
Normal file
@ -0,0 +1,208 @@
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2013 Glenn De Jonghe
|
||||
// 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_ONLINE_REQUEST_HPP
|
||||
#define HEADER_ONLINE_REQUEST_HPP
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "utils/cpp2011.h"
|
||||
#include "utils/string_utils.hpp"
|
||||
#include "utils/synchronised.hpp"
|
||||
#include "io/file_manager.hpp"
|
||||
|
||||
namespace Online{
|
||||
|
||||
/**
|
||||
* Stores a request for the HTTP Manager. They will be sorted by priorities.
|
||||
* \ingroup online
|
||||
*/
|
||||
class Request
|
||||
{
|
||||
private:
|
||||
/** Can be used as identifier for the user.
|
||||
* Has 0 as default value.
|
||||
* Only requests ment to control the HTTP Manager should use negative values, for all other uses positive values are obliged
|
||||
* */
|
||||
const int m_type;
|
||||
/** True if the memory for this Request should be managed by
|
||||
* http connector (i.e. this object is freed once the request
|
||||
* is handled). Otherwise the memory is not freed, so it must
|
||||
* be freed by the calling function. */
|
||||
const bool m_manage_memory;
|
||||
/** The priority of this request. The higher the value the more
|
||||
important this request is. */
|
||||
const int m_priority;
|
||||
|
||||
protected:
|
||||
|
||||
/** Cancel this request if it is active. */
|
||||
Synchronised<bool> m_cancel;
|
||||
/** Set to though if the reply of the request is in and callbacks are executed */
|
||||
Synchronised<bool> m_done;
|
||||
|
||||
virtual void beforeOperation() {}
|
||||
virtual void operation() {};
|
||||
virtual void afterOperation();
|
||||
|
||||
public:
|
||||
/** Negative numbers are reserved for requests that are special for the HTTP Manager*/
|
||||
enum RequestType
|
||||
{
|
||||
RT_QUIT = -1
|
||||
};
|
||||
|
||||
Request(int type, bool manage_memory, int priority);
|
||||
virtual ~Request();
|
||||
|
||||
void execute();
|
||||
int getType() const { return m_type; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns if the memory for this object should be managed by
|
||||
* by network_http (i.e. freed once the request is handled). */
|
||||
bool manageMemory() const { return m_manage_memory; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the priority of this request. */
|
||||
int getPriority() const { return m_priority; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Signals that this request should be canceled. */
|
||||
void cancel() { m_cancel.setAtomic(true); }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns if this request is to be canceled. */
|
||||
bool isCancelled() const { return m_cancel.getAtomic(); }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns if this request is done. */
|
||||
bool isDone() const { return m_done.getAtomic(); }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Virtual method to check if a request has initialized all needed members to a valid value. */
|
||||
virtual bool isAllowedToAdd() const { return true; }
|
||||
|
||||
/** This class is used by the priority queue to sort requests by priority.
|
||||
*/
|
||||
class Compare
|
||||
{
|
||||
public:
|
||||
/** Compares two requests, returns if the first request has a lower
|
||||
* priority than the second one. */
|
||||
bool operator() (const Request *a, const Request *b) const
|
||||
{
|
||||
return a->getPriority() < b->getPriority();
|
||||
}
|
||||
}; // Compare
|
||||
}; // Request
|
||||
|
||||
|
||||
// ========================================================================
|
||||
|
||||
|
||||
class HTTPRequest : public Request
|
||||
{
|
||||
|
||||
protected :
|
||||
|
||||
typedef std::map<std::string, std::string> Parameters;
|
||||
|
||||
|
||||
/** The progress indicator. 0 untill it is started and the first
|
||||
* packet is downloaded. At the end either -1 (error) or 1
|
||||
* (everything ok) at the end. */
|
||||
Synchronised<float> m_progress;
|
||||
Synchronised<std::string> m_url;
|
||||
Parameters * m_parameters;
|
||||
|
||||
virtual void afterOperation() OVERRIDE;
|
||||
/** Executed when a request has finished. */
|
||||
virtual void callback() {}
|
||||
/**
|
||||
* Performs a POST request to the website with URL m_url using the parameters given in m_parameters.
|
||||
* Returns the page as a string.
|
||||
**/
|
||||
std::string downloadPage();
|
||||
|
||||
static int progressDownload( void *clientp,
|
||||
double dltotal,
|
||||
double dlnow,
|
||||
double ultotal,
|
||||
double ulnow);
|
||||
|
||||
static size_t WriteCallback( void *contents,
|
||||
size_t size,
|
||||
size_t nmemb,
|
||||
void *userp);
|
||||
|
||||
|
||||
public :
|
||||
HTTPRequest(int type = 0, bool manage_memory = false, int priority = 1);
|
||||
virtual ~HTTPRequest();
|
||||
|
||||
void setParameter(const std::string & name, const std::string &value){
|
||||
(*m_parameters)[name] = value;
|
||||
};
|
||||
void setParameter(const std::string & name, const irr::core::stringw &value){
|
||||
(*m_parameters)[name] = irr::core::stringc(value.c_str()).c_str();
|
||||
}
|
||||
template <typename T>
|
||||
void setParameter(const std::string & name, const T& value){
|
||||
(*m_parameters)[name] = StringUtils::toString(value);
|
||||
}
|
||||
|
||||
/** Returns the current progress. */
|
||||
float getProgress() const { return m_progress.getAtomic(); }
|
||||
/** Sets the current progress. */
|
||||
void setProgress(float f) { m_progress.setAtomic(f); }
|
||||
|
||||
const std::string getURL() {
|
||||
m_url.lock();
|
||||
const std::string url = m_url.getData();
|
||||
m_url.unlock();
|
||||
return url;
|
||||
}
|
||||
|
||||
void setURL(const std::string & url) { m_url.setAtomic(url);}
|
||||
|
||||
virtual bool isAllowedToAdd() OVERRIDE;
|
||||
|
||||
};
|
||||
|
||||
class XMLRequest : public HTTPRequest
|
||||
{
|
||||
protected :
|
||||
|
||||
XMLNode * m_result;
|
||||
Synchronised<irr::core::stringw> m_info;
|
||||
Synchronised<bool> m_success;
|
||||
|
||||
virtual void operation() OVERRIDE;
|
||||
virtual void afterOperation() OVERRIDE;
|
||||
|
||||
public :
|
||||
XMLRequest(int type = 0, bool manage_memory = false, int priority = 1);
|
||||
virtual ~XMLRequest();
|
||||
|
||||
virtual XMLNode * getResult() const { return m_result; }
|
||||
const irr::core::stringw getInfo() {
|
||||
m_info.lock();
|
||||
const irr::core::stringw info = m_info.getData();
|
||||
m_info.unlock();
|
||||
return info;
|
||||
}
|
||||
bool isSuccess() const { return m_success.getAtomic(); }
|
||||
|
||||
};
|
||||
} //namespace Online
|
||||
|
||||
#endif
|
||||
|
75
src/online/server.cpp
Normal file
75
src/online/server.cpp
Normal file
@ -0,0 +1,75 @@
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2013 Glenn De Jonghe
|
||||
//
|
||||
// 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.
|
||||
/**
|
||||
\page online Online
|
||||
*/
|
||||
|
||||
#include "online/server.hpp"
|
||||
|
||||
#include "io/xml_node.hpp"
|
||||
#include "utils/constants.hpp"
|
||||
#include "utils/string_utils.hpp"
|
||||
|
||||
namespace Online{
|
||||
Server::SortOrder Server::m_sort_order=Server::SO_NAME; //FIXME change to some other default
|
||||
|
||||
Server::Server(const XMLNode & xml)
|
||||
{
|
||||
assert(xml.getName() == "server");
|
||||
m_name = "";
|
||||
m_satisfaction_score = 0;
|
||||
m_server_id = 0;
|
||||
m_current_players = 0;
|
||||
m_max_players = 0;
|
||||
|
||||
xml.get("name", &m_lower_case_name);
|
||||
m_name = StringUtils::decodeFromHtmlEntities(m_lower_case_name);
|
||||
m_lower_case_name = StringUtils::toLowerCase(m_lower_case_name);
|
||||
|
||||
xml.get("id", &m_server_id);
|
||||
xml.get("hostid", &m_host_id);
|
||||
xml.get("max_players", &m_max_players);
|
||||
xml.get("current_players", &m_current_players);
|
||||
|
||||
}; // Server(const XML&)
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/**
|
||||
* \brief Filter the add-on with a list of words.
|
||||
* \param words A list of words separated by ' '.
|
||||
* \return true if the add-on contains one of the words, otherwise false.
|
||||
*/
|
||||
bool Server::filterByWords(const core::stringw words) const
|
||||
{
|
||||
if (words == NULL || words.empty())
|
||||
return true;
|
||||
|
||||
std::vector<core::stringw> list = StringUtils::split(words, ' ', false);
|
||||
|
||||
for (unsigned int i = 0; i < list.size(); i++)
|
||||
{
|
||||
list[i].make_lower();
|
||||
|
||||
if ((core::stringw(m_name).make_lower()).find(list[i].c_str()) != -1)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
} // filterByWords
|
||||
} // namespace Online
|
136
src/online/server.hpp
Normal file
136
src/online/server.hpp
Normal file
@ -0,0 +1,136 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2013 Glenn De Jonghe
|
||||
//
|
||||
// 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_SERVER_HPP
|
||||
#define HEADER_SERVER_HPP
|
||||
|
||||
/**
|
||||
* \defgroup onlinegroup Online
|
||||
* Represents a server that is joinable
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <irrString.h>
|
||||
#include "io/xml_node.hpp"
|
||||
#include "utils/types.hpp"
|
||||
|
||||
class XMLNode;
|
||||
|
||||
namespace Online{
|
||||
/**
|
||||
* \ingroup online
|
||||
*/
|
||||
class Server
|
||||
{
|
||||
public:
|
||||
|
||||
/** Set the sort order used in the comparison function. */
|
||||
enum SortOrder { SO_SCORE = 1, // Sorted on satisfaction score
|
||||
SO_NAME = 2, // Sorted alphabetically by name
|
||||
SO_PLAYERS = 4
|
||||
};
|
||||
|
||||
protected:
|
||||
/** The name to be displayed. */
|
||||
irr::core::stringw m_name;
|
||||
std::string m_lower_case_name; //Used for comparison
|
||||
|
||||
uint32_t m_server_id;
|
||||
uint32_t m_host_id;
|
||||
|
||||
int m_max_players;
|
||||
|
||||
int m_current_players;
|
||||
|
||||
float m_satisfaction_score;
|
||||
|
||||
/** The sort order to be used in the comparison. */
|
||||
static SortOrder m_sort_order;
|
||||
|
||||
Server() {};
|
||||
|
||||
public:
|
||||
|
||||
/** Initialises the object from an XML node. */
|
||||
Server(const XMLNode & xml);
|
||||
// ------------------------------------------------------------------------
|
||||
/** Sets the sort order used in the comparison function. It is static, so
|
||||
* that each instance can access the sort order. */
|
||||
static void setSortOrder(SortOrder so) { m_sort_order = so; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the name of the server. */
|
||||
const irr::core::stringw& getName() const { return m_name; }
|
||||
const std::string & getLowerCaseName() const { return m_lower_case_name; }
|
||||
// ------------------------------------------------------------------------
|
||||
const float getScore() const { return m_satisfaction_score; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the ID of this server. */
|
||||
const uint32_t getServerId() const { return m_server_id; }
|
||||
const int getMaxPlayers() const { return m_max_players; }
|
||||
const int getCurrentPlayers() const { return m_current_players; }
|
||||
// ------------------------------------------------------------------------
|
||||
bool filterByWords(const irr::core::stringw words) const;
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/** Compares two servers according to the sort order currently defined.
|
||||
* \param a The addon to compare this addon to.
|
||||
*/
|
||||
bool operator<(const Server &server) const
|
||||
{
|
||||
switch(m_sort_order)
|
||||
{
|
||||
case SO_SCORE:
|
||||
return m_satisfaction_score < server.getScore();
|
||||
break;
|
||||
case SO_NAME:
|
||||
// m_id is the lower case name
|
||||
return m_name < server.getName();
|
||||
break;
|
||||
case SO_PLAYERS:
|
||||
return m_current_players < server.getCurrentPlayers();
|
||||
break;
|
||||
} // switch
|
||||
return true;
|
||||
} // operator<
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Compares two addons according to the sort order currently defined.
|
||||
* Comparison is done for sorting in descending order.
|
||||
* \param a The addon to compare this addon to.
|
||||
*/
|
||||
bool operator>(const Server &server) const
|
||||
{
|
||||
switch(m_sort_order)
|
||||
{
|
||||
case SO_SCORE:
|
||||
return m_satisfaction_score > server.getScore();
|
||||
break;
|
||||
case SO_NAME:
|
||||
return m_lower_case_name > server.getLowerCaseName();
|
||||
break;
|
||||
case SO_PLAYERS:
|
||||
return m_current_players > server.getCurrentPlayers();
|
||||
break;
|
||||
} // switch
|
||||
return true;
|
||||
} // operator>
|
||||
|
||||
}; // Server
|
||||
} // namespace Online
|
||||
|
||||
#endif
|
165
src/online/servers_manager.cpp
Normal file
165
src/online/servers_manager.cpp
Normal file
@ -0,0 +1,165 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2013 Glenn De Jonghe
|
||||
//
|
||||
// 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 "online/servers_manager.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <irrString.h>
|
||||
#include <assert.h>
|
||||
#include "config/user_config.hpp"
|
||||
#include "utils/translation.hpp"
|
||||
#include "utils/time.hpp"
|
||||
|
||||
#define SERVER_REFRESH_INTERVAL 5.0f
|
||||
|
||||
namespace Online{
|
||||
|
||||
static Synchronised<ServersManager*> manager_singleton(NULL);
|
||||
|
||||
ServersManager* ServersManager::acquire()
|
||||
{
|
||||
manager_singleton.lock();
|
||||
ServersManager * manager = manager_singleton.getData();
|
||||
if (manager == NULL)
|
||||
{
|
||||
manager_singleton.unlock();
|
||||
manager = new ServersManager();
|
||||
manager_singleton.setAtomic(manager);
|
||||
manager_singleton.lock();
|
||||
}
|
||||
return manager;
|
||||
}
|
||||
|
||||
void ServersManager::release()
|
||||
{
|
||||
manager_singleton.unlock();
|
||||
}
|
||||
|
||||
void ServersManager::deallocate()
|
||||
{
|
||||
manager_singleton.lock();
|
||||
ServersManager* manager = manager_singleton.getData();
|
||||
delete manager;
|
||||
manager = NULL;
|
||||
manager_singleton.unlock();
|
||||
} // deallocate
|
||||
|
||||
// ============================================================================
|
||||
ServersManager::ServersManager(){
|
||||
m_info_message = "";
|
||||
m_last_load_time = 0.0f;
|
||||
m_joined_server = NULL;
|
||||
}
|
||||
|
||||
ServersManager::~ServersManager(){
|
||||
cleanUpServers();
|
||||
delete m_joined_server;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
void ServersManager::cleanUpServers()
|
||||
{
|
||||
m_sorted_servers.clearAndDeleteAll();
|
||||
m_mapped_servers.clear();
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
ServersManager::RefreshRequest * ServersManager::refreshRequest()
|
||||
{
|
||||
RefreshRequest * request = NULL;
|
||||
if(Time::getRealTime() - m_last_load_time > SERVER_REFRESH_INTERVAL)
|
||||
{
|
||||
request = new RefreshRequest();
|
||||
request->setURL((std::string)UserConfigParams::m_server_multiplayer + "client-user.php");
|
||||
request->setParameter("action",std::string("get_server_list"));
|
||||
HTTPManager::get()->addRequest(request);
|
||||
}
|
||||
return request;
|
||||
}
|
||||
|
||||
void ServersManager::refresh(RefreshRequest * input)
|
||||
{
|
||||
if (input->isSuccess())
|
||||
{
|
||||
const XMLNode * servers_xml = input->getResult()->getNode("servers");
|
||||
cleanUpServers();
|
||||
for (unsigned int i = 0; i < servers_xml->getNumNodes(); i++)
|
||||
{
|
||||
addServer(new Server(*servers_xml->getNode(i)));
|
||||
}
|
||||
m_last_load_time = Time::getRealTime();
|
||||
}
|
||||
m_info_message = input->getInfo();
|
||||
//FIXME error message
|
||||
}
|
||||
|
||||
void ServersManager::RefreshRequest::callback()
|
||||
{
|
||||
ServersManager::acquire()->refresh(this);
|
||||
ServersManager::release();
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
Server * ServersManager::getQuickPlay()
|
||||
{
|
||||
if(m_sorted_servers.size() > 0)
|
||||
return getServerBySort(0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
void ServersManager::setJoinedServer(uint32_t id)
|
||||
{
|
||||
delete m_joined_server;
|
||||
//It's a copy!
|
||||
m_joined_server = new Server(*getServerByID(id));
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
void ServersManager::unsetJoinedServer()
|
||||
{
|
||||
delete m_joined_server;
|
||||
m_joined_server = NULL;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
void ServersManager::addServer(Server * server)
|
||||
{
|
||||
m_sorted_servers.push_back(server);
|
||||
m_mapped_servers[server->getServerId()] = server;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
int ServersManager::getNumServers ()
|
||||
{
|
||||
return m_sorted_servers.size();
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
Server * ServersManager::getServerBySort (int index)
|
||||
{
|
||||
return m_sorted_servers.get(index);
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
Server * ServersManager::getServerByID (uint32_t id)
|
||||
{
|
||||
return m_mapped_servers[id];
|
||||
}
|
||||
} // namespace Online
|
91
src/online/servers_manager.hpp
Normal file
91
src/online/servers_manager.hpp
Normal file
@ -0,0 +1,91 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2013 Glenn De Jonghe
|
||||
//
|
||||
// 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_SERVERS_MANAGER_HPP
|
||||
#define HEADER_SERVERS_MANAGER_HPP
|
||||
|
||||
#include "utils/ptr_vector.hpp"
|
||||
#include "utils/types.hpp"
|
||||
#include "online/server.hpp"
|
||||
#include "http_manager.hpp"
|
||||
|
||||
|
||||
|
||||
namespace Online {
|
||||
|
||||
/**
|
||||
* \brief
|
||||
* \ingroup online
|
||||
*/
|
||||
class ServersManager
|
||||
{
|
||||
public:
|
||||
enum RequestType
|
||||
{
|
||||
RT_REFRESH = 1
|
||||
};
|
||||
|
||||
class RefreshRequest : public XMLRequest
|
||||
{
|
||||
virtual void callback ();
|
||||
public:
|
||||
RefreshRequest() : XMLRequest(RT_REFRESH) {}
|
||||
};
|
||||
|
||||
private:
|
||||
ServersManager();
|
||||
~ServersManager();
|
||||
/** Sorted vector of servers */
|
||||
PtrVector<Server> m_sorted_servers;
|
||||
/** Maps server id's to the same servers*/
|
||||
std::map<uint32_t, Server*> m_mapped_servers;
|
||||
/** This is a pointer to a copy of the server, the moment it got joined */
|
||||
Server * m_joined_server;
|
||||
|
||||
bool m_not_fetched;
|
||||
irr::core::stringw m_info_message;
|
||||
float m_last_load_time;
|
||||
void refresh(RefreshRequest * input);
|
||||
void cleanUpServers();
|
||||
|
||||
public:
|
||||
// Singleton
|
||||
static ServersManager* acquire();
|
||||
static void release();
|
||||
static void deallocate();
|
||||
|
||||
RefreshRequest * refreshRequest();
|
||||
void setJoinedServer(uint32_t server_id);
|
||||
void unsetJoinedServer();
|
||||
void addServer(Server * server);
|
||||
int getNumServers ();
|
||||
Server * getServerByID (uint32_t server_id);
|
||||
Server * getServerBySort (int index);
|
||||
void sort(bool sort_desc) { m_sorted_servers.insertionSort(0, sort_desc); }
|
||||
Server * getJoinedServer() { return m_joined_server; }
|
||||
//Returns the best server to join
|
||||
Server * getQuickPlay();
|
||||
}; // class ServersManager
|
||||
|
||||
|
||||
} // namespace Online
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
/*EOF*/
|
@ -17,22 +17,20 @@
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
|
||||
#include "online/online_user.hpp"
|
||||
#include "online/user.hpp"
|
||||
|
||||
#include <sstream>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
// ============================================================================
|
||||
OnlineUser::OnlineUser(const irr::core::stringw &username)
|
||||
{
|
||||
m_name = username;
|
||||
} // OnlineUser
|
||||
|
||||
// ============================================================================
|
||||
OnlineUser::OnlineUser(const uint32_t& id)
|
||||
{
|
||||
m_id = id;
|
||||
} // OnlineUser
|
||||
|
||||
|
||||
namespace Online{
|
||||
// ============================================================================
|
||||
User::User(const irr::core::stringw &username)
|
||||
{
|
||||
m_name = username;
|
||||
}
|
||||
// ============================================================================
|
||||
User::User(uint32_t id)
|
||||
{
|
||||
m_id = id;
|
||||
}
|
||||
} // namespace Online
|
@ -21,38 +21,35 @@
|
||||
|
||||
#include <irrString.h>
|
||||
#include "utils/types.hpp"
|
||||
#include "utils/synchronised.hpp"
|
||||
|
||||
// ============================================================================
|
||||
namespace Online{
|
||||
|
||||
/**
|
||||
* \brief Class that represents an online registered user
|
||||
* \ingroup online
|
||||
*/
|
||||
class OnlineUser
|
||||
{
|
||||
private:
|
||||
/**
|
||||
* \brief Class that represents an online registered user
|
||||
* \ingroup online
|
||||
*/
|
||||
class User
|
||||
{
|
||||
private:
|
||||
|
||||
protected:
|
||||
protected:
|
||||
irr::core::stringw m_name;
|
||||
uint32_t m_id;
|
||||
User(){}
|
||||
|
||||
irr::core::stringw m_name;
|
||||
uint32_t m_id;
|
||||
OnlineUser(){}
|
||||
public:
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
OnlineUser(const irr::core::stringw &username);
|
||||
OnlineUser(const uint32_t& id);
|
||||
|
||||
/** Returns the username. */
|
||||
irr::core::stringw getUserName() const { return m_name; }
|
||||
uint32_t getUserID() const { return m_id; }
|
||||
User(const irr::core::stringw &username);
|
||||
User(uint32_t id);
|
||||
|
||||
|
||||
}; // class OnlineUser
|
||||
irr::core::stringw getUserName() const { return m_name; }
|
||||
uint32_t getUserID() const { return m_id; }
|
||||
|
||||
|
||||
}; // class User
|
||||
} // namespace Online
|
||||
#endif
|
||||
|
||||
/*EOF*/
|
@ -104,7 +104,7 @@ void AddonsScreen::beforeAddingWidget()
|
||||
getWidget<GUIEngine::ListWidget>("list_addons");
|
||||
assert(w_list != NULL);
|
||||
w_list->clearColumns();
|
||||
w_list->addColumn( _("Add-on name"), 2 );
|
||||
w_list->addColumn( _("Add-on name"), 3 );
|
||||
w_list->addColumn( _("Updated date"), 1 );
|
||||
|
||||
GUIEngine::SpinnerWidget* w_filter_date =
|
||||
@ -140,8 +140,6 @@ void AddonsScreen::init()
|
||||
|
||||
getWidget<GUIEngine::RibbonWidget>("category")->setDeactivated();
|
||||
|
||||
GUIEngine::getFont()->setTabStop(0.66f);
|
||||
|
||||
if(UserConfigParams::logAddons())
|
||||
std::cout << "[addons] Using directory <" + file_manager->getAddonsDir()
|
||||
<< ">\n";
|
||||
@ -188,8 +186,6 @@ void AddonsScreen::unloaded()
|
||||
|
||||
void AddonsScreen::tearDown()
|
||||
{
|
||||
// return tab stop to the center when leaving this screen!!
|
||||
GUIEngine::getFont()->setTabStop(0.5f);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -279,10 +275,13 @@ void AddonsScreen::loadList()
|
||||
s = (addon->getName()+L"\t" +
|
||||
core::stringc(addon->getDateAsString().c_str())).c_str();
|
||||
|
||||
gui::IGUIFont* font = GUIEngine::getFont();
|
||||
//FIXME I'd like to move this to CGUISTKListBox.cpp
|
||||
|
||||
/* gui::IGUIFont* font = GUIEngine::getFont();
|
||||
|
||||
// first column is 0.666% of the list's width.
|
||||
// and icon width == icon height.
|
||||
|
||||
const unsigned int available_width = (int)(w_list->m_w*0.6666f
|
||||
- m_icon_height);
|
||||
if (font->getDimension(s.c_str()).Width > available_width)
|
||||
@ -291,7 +290,7 @@ void AddonsScreen::loadList()
|
||||
s.append("...");
|
||||
}
|
||||
else
|
||||
{
|
||||
{*/
|
||||
if (addon->getDesigner().size() == 0)
|
||||
{
|
||||
s = addon->getName();
|
||||
@ -302,7 +301,7 @@ void AddonsScreen::loadList()
|
||||
s = _C("addons", "%s by %s", addon->getName().c_str(),
|
||||
addon->getDesigner().c_str());
|
||||
}
|
||||
|
||||
/*
|
||||
// check if text is too long to fit
|
||||
if (font->getDimension(s.c_str()).Width > available_width)
|
||||
{
|
||||
@ -342,10 +341,9 @@ void AddonsScreen::loadList()
|
||||
} // for nlines.size()
|
||||
|
||||
s = final_string;
|
||||
} // if
|
||||
s.append("\t");
|
||||
s.append(addon->getDateAsString().c_str());
|
||||
}
|
||||
*/
|
||||
//} // if
|
||||
//}
|
||||
|
||||
// we have no icon for featured+updateme, so if an add-on is updatable
|
||||
// forget about the featured icon
|
||||
@ -355,7 +353,10 @@ void AddonsScreen::loadList()
|
||||
icon += 2;
|
||||
}
|
||||
|
||||
w_list->addItem(addon->getId(), s.c_str(), icon);
|
||||
PtrVector<GUIEngine::ListWidget::ListCell> * row = new PtrVector<GUIEngine::ListWidget::ListCell>;
|
||||
row->push_back(new GUIEngine::ListWidget::ListCell(s.c_str(), icon, 3, false));
|
||||
row->push_back(new GUIEngine::ListWidget::ListCell(addon->getDateAsString().c_str(), -1, 1, true));
|
||||
w_list->addItem(addon->getId(), row);
|
||||
|
||||
// Highlight if it's not approved in artists debug mode.
|
||||
if(UserConfigParams::m_artist_debug_mode &&
|
||||
@ -365,16 +366,16 @@ void AddonsScreen::loadList()
|
||||
}
|
||||
}
|
||||
|
||||
getWidget<GUIEngine::RibbonWidget>("category")->setActivated();
|
||||
if(m_type == "kart")
|
||||
getWidget<GUIEngine::RibbonWidget>("category")->select("tab_kart",
|
||||
PLAYER_ID_GAME_MASTER);
|
||||
else if(m_type == "track")
|
||||
getWidget<GUIEngine::RibbonWidget>("category")->select("tab_track",
|
||||
PLAYER_ID_GAME_MASTER);
|
||||
getWidget<GUIEngine::RibbonWidget>("category")->setActivated();
|
||||
if(m_type == "kart")
|
||||
getWidget<GUIEngine::RibbonWidget>("category")->select("tab_kart",
|
||||
PLAYER_ID_GAME_MASTER);
|
||||
else if(m_type == "track")
|
||||
getWidget<GUIEngine::RibbonWidget>("category")->select("tab_track",
|
||||
PLAYER_ID_GAME_MASTER);
|
||||
else
|
||||
getWidget<GUIEngine::RibbonWidget>("category")->select("tab_update",
|
||||
PLAYER_ID_GAME_MASTER);
|
||||
getWidget<GUIEngine::RibbonWidget>("category")->select("tab_update",
|
||||
PLAYER_ID_GAME_MASTER);
|
||||
} // loadList
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -384,7 +385,7 @@ void AddonsScreen::onColumnClicked(int column_id)
|
||||
{
|
||||
case 0: Addon::setSortOrder(Addon::SO_NAME); break;
|
||||
case 1: Addon::setSortOrder(Addon::SO_DATE); break;
|
||||
default: assert(0);
|
||||
default: assert(0); break;
|
||||
} // switch
|
||||
/** \brief Toggle the sort order after column click **/
|
||||
m_sort_desc = !m_sort_desc;
|
||||
@ -412,9 +413,7 @@ void AddonsScreen::eventCallback(GUIEngine::Widget* widget,
|
||||
w_list->clear();
|
||||
|
||||
w_list->addItem("spacer", L"");
|
||||
w_list->addItem("loading",
|
||||
_("Please wait while addons are updated"),
|
||||
m_icon_loading);
|
||||
w_list->addItem("loading",_("Please wait while addons are updated"), m_icon_loading);
|
||||
}
|
||||
}
|
||||
|
||||
|
187
src/states_screens/create_server_screen.cpp
Normal file
187
src/states_screens/create_server_screen.cpp
Normal file
@ -0,0 +1,187 @@
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2013 Glenn De Jonghe
|
||||
//
|
||||
// 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.
|
||||
|
||||
#define DEBUG_MENU_ITEM 0
|
||||
|
||||
#include "states_screens/create_server_screen.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
#include "challenges/game_slot.hpp"
|
||||
#include "challenges/unlock_manager.hpp"
|
||||
#include "audio/sfx_manager.hpp"
|
||||
#include "states_screens/online_screen.hpp"
|
||||
#include "states_screens/state_manager.hpp"
|
||||
#include "states_screens/dialogs/message_dialog.hpp"
|
||||
#include "modes/demo_world.hpp"
|
||||
#include "utils/translation.hpp"
|
||||
#include "states_screens/networking_lobby.hpp"
|
||||
#include "states_screens/dialogs/server_info_dialog.hpp"
|
||||
#include "online/servers_manager.hpp"
|
||||
#include "online/messages.hpp"
|
||||
|
||||
|
||||
using namespace GUIEngine;
|
||||
using namespace Online;
|
||||
|
||||
DEFINE_SCREEN_SINGLETON( CreateServerScreen );
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
CreateServerScreen::CreateServerScreen() : Screen("online/create_server.stkgui")
|
||||
{
|
||||
m_server_creation_request = NULL;
|
||||
} // CreateServerScreen
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void CreateServerScreen::loadedFromFile()
|
||||
{
|
||||
|
||||
|
||||
m_name_widget = getWidget<TextBoxWidget>("name");
|
||||
assert(m_name_widget != NULL);
|
||||
m_name_widget->setText(CurrentUser::acquire()->getUserName() + _("'s server"));
|
||||
CurrentUser::release();
|
||||
m_max_players_widget = getWidget<SpinnerWidget>("max_players");
|
||||
assert(m_max_players_widget != NULL);
|
||||
m_max_players_widget->setValue(8);
|
||||
|
||||
m_info_widget = getWidget<LabelWidget>("info");
|
||||
assert(m_info_widget != NULL);
|
||||
|
||||
m_options_widget = getWidget<RibbonWidget>("options");
|
||||
assert(m_options_widget != NULL);
|
||||
m_create_widget = getWidget<IconButtonWidget>("create");
|
||||
assert(m_create_widget != NULL);
|
||||
m_cancel_widget = getWidget<IconButtonWidget>("cancel");
|
||||
assert(m_cancel_widget != NULL);
|
||||
|
||||
} // loadedFromFile
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void CreateServerScreen::beforeAddingWidget()
|
||||
{
|
||||
|
||||
} // beforeAddingWidget
|
||||
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void CreateServerScreen::init()
|
||||
{
|
||||
Screen::init();
|
||||
setInitialFocus();
|
||||
DemoWorld::resetIdleTime();
|
||||
m_info_widget->setText("", false);
|
||||
}
|
||||
// ----------------------------------------------------------------------------
|
||||
void CreateServerScreen::onUpdate(float delta, irr::video::IVideoDriver* driver)
|
||||
{
|
||||
if(m_server_creation_request != NULL)
|
||||
{
|
||||
if(m_server_creation_request->isDone())
|
||||
{
|
||||
if(m_server_creation_request->isSuccess())
|
||||
{
|
||||
new ServerInfoDialog(m_server_creation_request->getCreatedServerID(), true);
|
||||
}
|
||||
else
|
||||
{
|
||||
sfx_manager->quickSound( "anvil" );
|
||||
m_info_widget->setErrorColor();
|
||||
m_info_widget->setText(m_server_creation_request->getInfo(), false);
|
||||
}
|
||||
delete m_server_creation_request;
|
||||
m_server_creation_request = NULL;
|
||||
//m_options_widget->setActivated();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_info_widget->setDefaultColor();
|
||||
m_info_widget->setText(Online::Messages::creatingServer(), false);
|
||||
}
|
||||
}
|
||||
} // onUpdate
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void CreateServerScreen::serverCreationRequest()
|
||||
{
|
||||
const stringw name = m_name_widget->getText().trim();
|
||||
const int max_players = m_max_players_widget->getValue();
|
||||
m_info_widget->setErrorColor();
|
||||
if (name.size() < 4 || name.size() > 30)
|
||||
{
|
||||
m_info_widget->setText(_("Name has to be between 4 and 30 characters long!"), false);
|
||||
}
|
||||
else if (max_players < 2 || max_players > 12)
|
||||
{
|
||||
m_info_widget->setText(_("The maxinum number of players has to be between 2 and 12."), false);
|
||||
}
|
||||
else
|
||||
{
|
||||
//m_options_widget->setDeactivated();
|
||||
m_server_creation_request = Online::CurrentUser::acquire()->requestServerCreation(name, max_players);
|
||||
Online::CurrentUser::release();
|
||||
return;
|
||||
}
|
||||
sfx_manager->quickSound("anvil");
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void CreateServerScreen::eventCallback(Widget* widget, const std::string& name, const int playerID)
|
||||
{
|
||||
if (name == m_options_widget->m_properties[PROP_ID])
|
||||
{
|
||||
const std::string& selection = m_options_widget->getSelectionIDString(PLAYER_ID_GAME_MASTER);
|
||||
if (selection == m_cancel_widget->m_properties[PROP_ID])
|
||||
{
|
||||
StateManager::get()->escapePressed();
|
||||
}
|
||||
else if (selection == m_create_widget->m_properties[PROP_ID])
|
||||
{
|
||||
serverCreationRequest();
|
||||
}
|
||||
}
|
||||
} // eventCallback
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void CreateServerScreen::tearDown()
|
||||
{
|
||||
delete m_server_creation_request;
|
||||
m_server_creation_request = NULL;
|
||||
} // tearDown
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void CreateServerScreen::onDisabledItemClicked(const std::string& item)
|
||||
{
|
||||
|
||||
} // onDisabledItemClicked
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void CreateServerScreen::setInitialFocus()
|
||||
{
|
||||
} // setInitialFocus
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void CreateServerScreen::onDialogClose()
|
||||
{
|
||||
setInitialFocus();
|
||||
} // onDialogClose()
|
83
src/states_screens/create_server_screen.hpp
Normal file
83
src/states_screens/create_server_screen.hpp
Normal file
@ -0,0 +1,83 @@
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2013 Glenn De Jonghe
|
||||
//
|
||||
// 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_CREATE_SERVER_SCREEN_HPP
|
||||
#define HEADER_CREATE_SERVER_SCREEN_HPP
|
||||
|
||||
#include "guiengine/screen.hpp"
|
||||
#include "guiengine/widgets.hpp"
|
||||
#include "online/current_user.hpp"
|
||||
|
||||
|
||||
namespace GUIEngine { class Widget; class ListWidget; }
|
||||
|
||||
/**
|
||||
* \brief Handles the main menu
|
||||
* \ingroup states_screens
|
||||
*/
|
||||
class CreateServerScreen : public GUIEngine::Screen,
|
||||
public GUIEngine::ScreenSingleton<CreateServerScreen>
|
||||
{
|
||||
private:
|
||||
friend class GUIEngine::ScreenSingleton<CreateServerScreen>;
|
||||
|
||||
CreateServerScreen();
|
||||
|
||||
GUIEngine::TextBoxWidget * m_name_widget;
|
||||
GUIEngine::SpinnerWidget * m_max_players_widget;
|
||||
|
||||
GUIEngine::LabelWidget * m_info_widget;
|
||||
|
||||
GUIEngine::RibbonWidget * m_options_widget;
|
||||
GUIEngine::IconButtonWidget * m_create_widget;
|
||||
GUIEngine::IconButtonWidget * m_cancel_widget;
|
||||
|
||||
Online::CurrentUser::ServerCreationRequest * m_server_creation_request;
|
||||
|
||||
/** \brief Sets which widget has to be focused. Depends on the user state. */
|
||||
void setInitialFocus();
|
||||
|
||||
void serverCreationRequest();
|
||||
|
||||
public:
|
||||
|
||||
virtual void onUpdate(float delta, irr::video::IVideoDriver* driver) OVERRIDE;
|
||||
|
||||
/** \brief implement callback from parent class GUIEngine::Screen */
|
||||
virtual void loadedFromFile() OVERRIDE;
|
||||
|
||||
/** \brief implement callback from parent class GUIEngine::Screen */
|
||||
virtual void eventCallback(GUIEngine::Widget* widget, const std::string& name,
|
||||
const int playerID) OVERRIDE;
|
||||
|
||||
/** \brief implement callback from parent class GUIEngine::Screen */
|
||||
virtual void beforeAddingWidget() OVERRIDE;
|
||||
|
||||
/** \brief implement callback from parent class GUIEngine::Screen */
|
||||
virtual void init() OVERRIDE;
|
||||
|
||||
/** \brief implement callback from parent class GUIEngine::Screen */
|
||||
virtual void tearDown() OVERRIDE;
|
||||
|
||||
/** \brief implement callback from parent class GUIEngine::Screen */
|
||||
virtual void onDisabledItemClicked(const std::string& item) OVERRIDE;
|
||||
|
||||
/** \brief Implements the callback when a dialog gets closed. */
|
||||
virtual void onDialogClose() OVERRIDE;
|
||||
};
|
||||
|
||||
#endif
|
@ -25,39 +25,41 @@
|
||||
#include "states_screens/state_manager.hpp"
|
||||
#include "utils/translation.hpp"
|
||||
#include "utils/string_utils.hpp"
|
||||
#include "online/current_online_user.hpp"
|
||||
#include "states_screens/dialogs/registration_dialog.hpp"
|
||||
#include "online/messages.hpp"
|
||||
|
||||
|
||||
using namespace GUIEngine;
|
||||
using namespace irr;
|
||||
using namespace irr::gui;
|
||||
using namespace Online;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
LoginDialog::LoginDialog(const Message message_type) :
|
||||
ModalDialog(0.8f,0.8f)
|
||||
ModalDialog(0.8f,0.9f)
|
||||
{
|
||||
m_self_destroy = false;
|
||||
m_open_registration_dialog = false;
|
||||
m_sign_in_request = NULL;
|
||||
loadFromFile("online/login_dialog.stkgui");
|
||||
|
||||
m_info_widget = getWidget<LabelWidget>("info");
|
||||
assert(m_info_widget != NULL);
|
||||
irr::core::stringw info;
|
||||
m_message_widget = getWidget<LabelWidget>("message");
|
||||
assert(m_message_widget != NULL);
|
||||
irr::core::stringw message;
|
||||
if (message_type == Normal)
|
||||
info = _("Fill in your username and password. ");
|
||||
message = _("Fill in your username and password. ");
|
||||
else if (message_type == Signing_In_Required)
|
||||
info = _("You need to sign in to be able to use this feature. ");
|
||||
message = _("You need to sign in to be able to use this feature. ");
|
||||
else if (message_type == Registration_Required)
|
||||
info = _("You need to be a registered user to enjoy this feature! "
|
||||
message = _("You need to be a registered user to enjoy this feature! "
|
||||
"If you do not have an account yet, you can sign up using the register icon at the bottom.");
|
||||
else
|
||||
info = "";
|
||||
message = "";
|
||||
if (message_type == Normal || message_type == Signing_In_Required)
|
||||
info += _("If you do not have an account yet, you can choose to sign in as a guest "
|
||||
message += _("If you do not have an account yet, you can choose to sign in as a guest "
|
||||
"or press the register icon at the bottom to gain access to all the features!");
|
||||
m_info_widget->setText(info, false);
|
||||
m_message_widget->setText(message, false);
|
||||
|
||||
m_username_widget = getWidget<TextBoxWidget>("username");
|
||||
assert(m_username_widget != NULL);
|
||||
@ -67,8 +69,12 @@ LoginDialog::LoginDialog(const Message message_type) :
|
||||
assert(m_password_widget != NULL);
|
||||
m_password_widget->setPasswordBox(true,L'*');
|
||||
|
||||
m_message_widget = getWidget<LabelWidget>("message");
|
||||
assert(m_message_widget != NULL);
|
||||
m_remember_widget = getWidget<CheckBoxWidget>("remember");
|
||||
assert(m_remember_widget != NULL);
|
||||
m_remember_widget->setState(false);
|
||||
|
||||
m_info_widget = getWidget<LabelWidget>("info");
|
||||
assert(m_info_widget != NULL);
|
||||
|
||||
m_options_widget = getWidget<RibbonWidget>("options");
|
||||
assert(m_options_widget != NULL);
|
||||
@ -82,12 +88,15 @@ LoginDialog::LoginDialog(const Message message_type) :
|
||||
assert(m_as_guest_widget != NULL);
|
||||
m_cancel_widget = getWidget<IconButtonWidget>("cancel");
|
||||
assert(m_cancel_widget != NULL);
|
||||
|
||||
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
LoginDialog::~LoginDialog()
|
||||
{
|
||||
delete m_sign_in_request;
|
||||
}
|
||||
|
||||
|
||||
@ -97,16 +106,17 @@ void LoginDialog::login()
|
||||
{
|
||||
const stringw username = m_username_widget->getText().trim();
|
||||
const stringw password = m_password_widget->getText().trim();
|
||||
stringw info = "";
|
||||
if(CurrentOnlineUser::get()->signIn(username,password,info))
|
||||
if (username.size() < 4 || username.size() > 30 || password.size() < 8 || password.size() > 30)
|
||||
{
|
||||
m_self_destroy = true;
|
||||
sfx_manager->quickSound("anvil");
|
||||
m_info_widget->setErrorColor();
|
||||
m_info_widget->setText(_("Username and/or password invalid."), false);
|
||||
}
|
||||
else
|
||||
{
|
||||
sfx_manager->quickSound( "anvil" );
|
||||
m_message_widget->setColor(irr::video::SColor(255, 255, 0, 0));
|
||||
m_message_widget->setText(info, false);
|
||||
m_options_widget->setDeactivated();
|
||||
m_sign_in_request = Online::CurrentUser::acquire()->requestSignIn(username,password, m_remember_widget->getState());
|
||||
Online::CurrentUser::release();
|
||||
}
|
||||
}
|
||||
|
||||
@ -145,13 +155,43 @@ void LoginDialog::onEnterPressedInternal()
|
||||
const int playerID = PLAYER_ID_GAME_MASTER;
|
||||
if (GUIEngine::isFocusedForPlayer(m_options_widget, playerID))
|
||||
return;
|
||||
login();
|
||||
if (m_sign_in_widget->isActivated())
|
||||
login();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
bool LoginDialog::onEscapePressed()
|
||||
{
|
||||
return m_cancel_widget->isActivated();
|
||||
}
|
||||
|
||||
void LoginDialog::onUpdate(float dt)
|
||||
{
|
||||
if(m_sign_in_request != NULL)
|
||||
{
|
||||
if(m_sign_in_request->isDone())
|
||||
{
|
||||
if(m_sign_in_request->isSuccess())
|
||||
{
|
||||
m_self_destroy = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
sfx_manager->quickSound( "anvil" );
|
||||
m_info_widget->setErrorColor();
|
||||
m_info_widget->setText(m_sign_in_request->getInfo(), false);
|
||||
}
|
||||
delete m_sign_in_request;
|
||||
m_sign_in_request = NULL;
|
||||
m_options_widget->setActivated();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_info_widget->setDefaultColor();
|
||||
m_info_widget->setText(Online::Messages::signingIn(), false);
|
||||
}
|
||||
}
|
||||
//If we want to open the registration dialog, we need to close this one first
|
||||
m_open_registration_dialog && (m_self_destroy = true);
|
||||
|
||||
@ -160,9 +200,7 @@ void LoginDialog::onUpdate(float dt)
|
||||
{
|
||||
ModalDialog::dismiss();
|
||||
if (m_open_registration_dialog)
|
||||
new RegistrationDialog(0.8f, 0.9f);
|
||||
|
||||
new RegistrationDialog();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -21,11 +21,10 @@
|
||||
|
||||
#include <irrString.h>
|
||||
|
||||
#include "online/current_user.hpp"
|
||||
|
||||
#include "guiengine/modaldialog.hpp"
|
||||
#include "guiengine/widgets/text_box_widget.hpp"
|
||||
#include "guiengine/widgets/icon_button_widget.hpp"
|
||||
#include "guiengine/widgets/ribbon_widget.hpp"
|
||||
#include "guiengine/widgets/label_widget.hpp"
|
||||
#include "guiengine/widgets.hpp"
|
||||
|
||||
/**
|
||||
* \brief Dialog that allows a user to sign in
|
||||
@ -38,11 +37,12 @@ private:
|
||||
|
||||
bool m_self_destroy;
|
||||
bool m_open_registration_dialog;
|
||||
|
||||
GUIEngine::LabelWidget * m_info_widget;
|
||||
Online::CurrentUser::SignInRequest * m_sign_in_request;
|
||||
GUIEngine::LabelWidget * m_message_widget;
|
||||
GUIEngine::TextBoxWidget * m_username_widget;
|
||||
GUIEngine::TextBoxWidget * m_password_widget;
|
||||
GUIEngine::LabelWidget * m_message_widget;
|
||||
GUIEngine::CheckBoxWidget * m_remember_widget;
|
||||
GUIEngine::LabelWidget * m_info_widget;
|
||||
|
||||
GUIEngine::RibbonWidget * m_options_widget;
|
||||
GUIEngine::IconButtonWidget * m_sign_in_widget;
|
||||
@ -69,8 +69,10 @@ public:
|
||||
~LoginDialog();
|
||||
|
||||
void onEnterPressedInternal();
|
||||
|
||||
GUIEngine::EventPropagation processEvent(const std::string& eventSource);
|
||||
|
||||
virtual bool onEscapePressed();
|
||||
virtual void onUpdate(float dt);
|
||||
//virtual void onTextUpdated();
|
||||
};
|
||||
|
@ -22,25 +22,24 @@
|
||||
#include "audio/sfx_manager.hpp"
|
||||
#include "config/player.hpp"
|
||||
#include "guiengine/engine.hpp"
|
||||
#include "guiengine/widgets/button_widget.hpp"
|
||||
#include "guiengine/widgets/label_widget.hpp"
|
||||
#include "guiengine/widgets/text_box_widget.hpp"
|
||||
#include "guiengine/widgets/check_box_widget.hpp"
|
||||
#include "states_screens/state_manager.hpp"
|
||||
#include "utils/translation.hpp"
|
||||
#include "utils/string_utils.hpp"
|
||||
#include "online/current_online_user.hpp"
|
||||
#include "online/messages.hpp"
|
||||
|
||||
|
||||
using namespace GUIEngine;
|
||||
using namespace irr;
|
||||
using namespace irr::gui;
|
||||
using namespace Online;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
RegistrationDialog::RegistrationDialog(const float w, const float h, const Phase phase) :
|
||||
ModalDialog(w,h)
|
||||
RegistrationDialog::RegistrationDialog(const Phase phase) :
|
||||
ModalDialog(0.8f,0.9f)
|
||||
{
|
||||
m_sign_up_request = NULL;
|
||||
m_activation_request = NULL;
|
||||
m_self_destroy = false;
|
||||
m_show_registration_info = false;
|
||||
m_show_registration_terms = false;
|
||||
@ -62,6 +61,8 @@ RegistrationDialog::RegistrationDialog(const float w, const float h, const Phase
|
||||
|
||||
RegistrationDialog::~RegistrationDialog()
|
||||
{
|
||||
delete m_sign_up_request;
|
||||
delete m_activation_request;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@ -76,38 +77,38 @@ void RegistrationDialog::showRegistrationInfo(){
|
||||
m_password = "";
|
||||
m_password_confirm = "";
|
||||
|
||||
TextBoxWidget* textBox = getWidget<TextBoxWidget>("username");
|
||||
assert(textBox != NULL);
|
||||
textBox->setText(m_username);
|
||||
textBox->setFocusForPlayer(PLAYER_ID_GAME_MASTER);
|
||||
m_username_widget = getWidget<TextBoxWidget>("username");
|
||||
assert(m_username_widget != NULL);
|
||||
m_username_widget->setText(m_username);
|
||||
m_username_widget->setFocusForPlayer(PLAYER_ID_GAME_MASTER);
|
||||
|
||||
textBox = getWidget<TextBoxWidget>("password");
|
||||
assert(textBox != NULL);
|
||||
textBox->setPasswordBox(true,L'*');
|
||||
m_password_widget = getWidget<TextBoxWidget>("password");
|
||||
assert(m_password_widget != NULL);
|
||||
m_password_widget->setPasswordBox(true,L'*');
|
||||
|
||||
textBox = getWidget<TextBoxWidget>("password_confirm");
|
||||
assert(textBox != NULL);
|
||||
textBox->setPasswordBox(true,L'*');
|
||||
m_password_confirm_widget = getWidget<TextBoxWidget>("password_confirm");
|
||||
assert(m_password_confirm_widget != NULL);
|
||||
m_password_confirm_widget->setPasswordBox(true,L'*');
|
||||
|
||||
textBox = getWidget<TextBoxWidget>("email");
|
||||
assert(textBox != NULL);
|
||||
textBox->setText(m_email);
|
||||
m_email_widget = getWidget<TextBoxWidget>("email");
|
||||
assert(m_email_widget != NULL);
|
||||
m_email_widget->setText(m_email);
|
||||
|
||||
textBox = getWidget<TextBoxWidget>("email_confirm");
|
||||
assert(textBox != NULL);
|
||||
textBox->setText(m_email_confirm);
|
||||
m_email_confirm_widget = getWidget<TextBoxWidget>("email_confirm");
|
||||
assert(m_email_confirm_widget != NULL);
|
||||
m_email_confirm_widget->setText(m_email_confirm);
|
||||
|
||||
LabelWidget * label = getWidget<LabelWidget>("info");
|
||||
assert(label != NULL);
|
||||
label->setColor(irr::video::SColor(255, 255, 0, 0));
|
||||
label->setText(m_registration_error, false);
|
||||
|
||||
ButtonWidget * button = getWidget<ButtonWidget>("next");
|
||||
assert(button != NULL);
|
||||
|
||||
button = getWidget<ButtonWidget>("cancel");
|
||||
assert(button != NULL);
|
||||
m_info_widget = getWidget<LabelWidget>("info");
|
||||
assert(m_info_widget != NULL);
|
||||
m_info_widget->setErrorColor();
|
||||
m_info_widget->setText(m_registration_error, false);
|
||||
|
||||
m_options_widget = getWidget<RibbonWidget>("options");
|
||||
assert(m_options_widget != NULL);
|
||||
m_next_widget = getWidget<IconButtonWidget>("next");
|
||||
assert(m_next_widget != NULL);
|
||||
m_cancel_widget = getWidget<IconButtonWidget>("cancel");
|
||||
assert(m_cancel_widget != NULL);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@ -117,13 +118,23 @@ void RegistrationDialog::showRegistrationTerms(){
|
||||
clearWindow();
|
||||
m_phase = Terms;
|
||||
loadFromFile("online/registration_terms.stkgui");
|
||||
CheckBoxWidget * checkbox = getWidget<CheckBoxWidget>("accepted");
|
||||
assert(checkbox != NULL);
|
||||
checkbox->setState(false);
|
||||
checkbox->setFocusForPlayer(PLAYER_ID_GAME_MASTER); //FIXME set focus on the terms
|
||||
ButtonWidget * submitButton = getWidget<ButtonWidget>("next");
|
||||
assert(submitButton != NULL);
|
||||
submitButton->setDeactivated();
|
||||
m_accept_terms_widget = getWidget<CheckBoxWidget>("accepted");
|
||||
assert(m_accept_terms_widget != NULL);
|
||||
m_accept_terms_widget->setState(false);
|
||||
m_accept_terms_widget->setFocusForPlayer(PLAYER_ID_GAME_MASTER); //FIXME set focus on the terms
|
||||
|
||||
m_info_widget = getWidget<LabelWidget>("info");
|
||||
assert(m_info_widget != NULL);
|
||||
|
||||
m_options_widget = getWidget<RibbonWidget>("options");
|
||||
assert(m_options_widget != NULL);
|
||||
m_previous_widget = getWidget<IconButtonWidget>("previous");
|
||||
assert(m_previous_widget != NULL);
|
||||
m_next_widget = getWidget<IconButtonWidget>("next");
|
||||
assert(m_next_widget != NULL);
|
||||
m_cancel_widget = getWidget<IconButtonWidget>("cancel");
|
||||
assert(m_cancel_widget != NULL);
|
||||
m_next_widget->setDeactivated();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@ -133,6 +144,17 @@ void RegistrationDialog::showRegistrationActivation(){
|
||||
clearWindow();
|
||||
m_phase = Activation;
|
||||
loadFromFile("online/registration_activation.stkgui");
|
||||
|
||||
m_info_widget = getWidget<LabelWidget>("info");
|
||||
assert(m_info_widget != NULL);
|
||||
m_info_widget->setText(m_registration_error, false);
|
||||
|
||||
m_options_widget = getWidget<RibbonWidget>("options");
|
||||
assert(m_options_widget != NULL);
|
||||
m_next_widget = getWidget<IconButtonWidget>("next");
|
||||
assert(m_next_widget != NULL);
|
||||
m_cancel_widget = getWidget<IconButtonWidget>("cancel");
|
||||
assert(m_cancel_widget != NULL);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@ -140,43 +162,41 @@ void RegistrationDialog::showRegistrationActivation(){
|
||||
bool RegistrationDialog::processInfoEvent(const std::string& eventSource){
|
||||
if (m_phase == Info)
|
||||
{
|
||||
if (eventSource == "next")
|
||||
if (eventSource == m_next_widget->m_properties[PROP_ID])
|
||||
{
|
||||
m_username = getWidget<TextBoxWidget>("username")->getText().trim();
|
||||
m_password = getWidget<TextBoxWidget>("password")->getText().trim();
|
||||
m_password_confirm = getWidget<TextBoxWidget>("password_confirm")->getText().trim();
|
||||
m_email = getWidget<TextBoxWidget>("email")->getText().trim();
|
||||
m_email_confirm = getWidget<TextBoxWidget>("email_confirm")->getText().trim();
|
||||
m_username = m_username_widget->getText().trim();
|
||||
m_password = m_password_widget->getText().trim();
|
||||
m_password_confirm = m_password_confirm_widget->getText().trim();
|
||||
m_email = m_email_widget->getText().trim();
|
||||
m_email_confirm = m_email_confirm_widget->getText().trim();
|
||||
//FIXME More validation of registration information
|
||||
m_info_widget->setErrorColor();
|
||||
if (m_password != m_password_confirm)
|
||||
{
|
||||
getWidget<LabelWidget>("info")->setText(_("Passwords don't match!"), false);
|
||||
sfx_manager->quickSound( "anvil" );
|
||||
m_info_widget->setText(_("Passwords don't match!"), false);
|
||||
}
|
||||
else if (m_email != m_email_confirm)
|
||||
{
|
||||
getWidget<LabelWidget>("info")->setText(_("Emails don't match!"), false);
|
||||
sfx_manager->quickSound( "anvil" );
|
||||
m_info_widget->setText(_("Emails don't match!"), false);
|
||||
}
|
||||
else if (m_username.size() < 5 || m_username.size() > 30)
|
||||
else if (m_username.size() < 4 || m_username.size() > 30)
|
||||
{
|
||||
getWidget<LabelWidget>("info")->setText(_("Username has to be between 5 and 30 characters long!"), false);
|
||||
sfx_manager->quickSound( "anvil" );
|
||||
m_info_widget->setText(_("Username has to be between 4 and 30 characters long!"), false);
|
||||
}
|
||||
else if (m_password.size() < 8 || m_password.size() > 30)
|
||||
{
|
||||
getWidget<LabelWidget>("info")->setText(_("Password has to be between 5 and 30 characters long!"), false);
|
||||
sfx_manager->quickSound( "anvil" );
|
||||
m_info_widget->setText(_("Password has to be between 8 and 30 characters long!"), false);
|
||||
}
|
||||
else if (m_email.size() < 5 || m_email.size() > 50)
|
||||
else if (m_email.size() < 4 || m_email.size() > 50)
|
||||
{
|
||||
getWidget<LabelWidget>("info")->setText(_("Email has to be between 5 and 50 characters long!"), false);
|
||||
sfx_manager->quickSound( "anvil" );
|
||||
m_info_widget->setText(_("Email has to be between 4 and 50 characters long!"), false);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_show_registration_terms = true;
|
||||
return true;
|
||||
}
|
||||
sfx_manager->quickSound( "anvil" );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -188,34 +208,27 @@ bool RegistrationDialog::processInfoEvent(const std::string& eventSource){
|
||||
bool RegistrationDialog::processTermsEvent(const std::string& eventSource){
|
||||
if (m_phase == Terms)
|
||||
{
|
||||
if (eventSource == "next")
|
||||
if (eventSource == m_next_widget->m_properties[PROP_ID])
|
||||
{
|
||||
assert(getWidget<CheckBoxWidget>("accepted")->getState());
|
||||
m_agreement = true;
|
||||
if(CurrentOnlineUser::get()->signUp(m_username, m_password, m_password_confirm, m_email, true, m_registration_error))
|
||||
{
|
||||
m_show_registration_activation = true;
|
||||
m_registration_error = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
m_show_registration_info = true;
|
||||
}
|
||||
assert(m_accept_terms_widget->getState());
|
||||
m_options_widget->setDeactivated();
|
||||
m_info_widget->setDefaultColor();
|
||||
m_info_widget->setText(Messages::signingUp(), false);
|
||||
m_sign_up_request = CurrentUser::acquire()->requestSignUp(m_username, m_password, m_password_confirm, m_email, true);
|
||||
CurrentUser::release();
|
||||
return true;
|
||||
}
|
||||
else if (eventSource == "accepted")
|
||||
else if (eventSource == m_accept_terms_widget->m_properties[PROP_ID])
|
||||
{
|
||||
CheckBoxWidget * checkbox = getWidget<CheckBoxWidget>("accepted");
|
||||
bool new_state = !checkbox->getState();
|
||||
checkbox->setState(new_state);
|
||||
ButtonWidget * submitButton = getWidget<ButtonWidget>("next");
|
||||
bool new_state = !m_accept_terms_widget->getState();
|
||||
m_accept_terms_widget->setState(new_state);
|
||||
if(new_state)
|
||||
submitButton->setActivated();
|
||||
m_next_widget->setActivated();
|
||||
else
|
||||
submitButton->setDeactivated();
|
||||
m_next_widget->setDeactivated();
|
||||
return true;
|
||||
}
|
||||
else if (eventSource == "previous")
|
||||
else if (eventSource == m_previous_widget->m_properties[PROP_ID])
|
||||
{
|
||||
m_show_registration_info = true;
|
||||
return true;
|
||||
@ -229,7 +242,7 @@ bool RegistrationDialog::processTermsEvent(const std::string& eventSource){
|
||||
bool RegistrationDialog::processActivationEvent(const std::string& eventSource){
|
||||
if (m_phase == Activation)
|
||||
{
|
||||
if (eventSource == "next")
|
||||
if (eventSource == m_next_widget->m_properties[PROP_ID])
|
||||
{
|
||||
//FIXME : activate
|
||||
m_self_destroy = true;
|
||||
@ -239,17 +252,28 @@ bool RegistrationDialog::processActivationEvent(const std::string& eventSource){
|
||||
return false;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
bool RegistrationDialog::onEscapePressed()
|
||||
{
|
||||
return m_cancel_widget->isActivated();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
GUIEngine::EventPropagation RegistrationDialog::processEvent(const std::string& eventSource)
|
||||
{
|
||||
if (eventSource == "cancel")
|
||||
std::string selection;
|
||||
if (eventSource == m_options_widget->m_properties[PROP_ID])
|
||||
selection = m_options_widget->getSelectionIDString(PLAYER_ID_GAME_MASTER);
|
||||
else
|
||||
selection = eventSource;
|
||||
if (selection == m_cancel_widget->m_properties[PROP_ID])
|
||||
{
|
||||
m_self_destroy = true;
|
||||
return GUIEngine::EVENT_BLOCK;
|
||||
}
|
||||
else if (processInfoEvent(eventSource) || processTermsEvent(eventSource) || processActivationEvent(eventSource))
|
||||
else if (processInfoEvent(selection) || processTermsEvent(selection) || processActivationEvent(selection))
|
||||
{
|
||||
return GUIEngine::EVENT_BLOCK;
|
||||
}
|
||||
@ -260,38 +284,72 @@ GUIEngine::EventPropagation RegistrationDialog::processEvent(const std::string&
|
||||
|
||||
void RegistrationDialog::onEnterPressedInternal()
|
||||
{
|
||||
//If enter was pressed while no button was focused, then interpret as "next" press.
|
||||
const int playerID = PLAYER_ID_GAME_MASTER;
|
||||
bool interpret_as_next = true;
|
||||
ButtonWidget * cancel_widget = getWidget<ButtonWidget>("cancel");
|
||||
ButtonWidget * next_widget = getWidget<ButtonWidget>("next");
|
||||
interpret_as_next = interpret_as_next &&
|
||||
!GUIEngine::isFocusedForPlayer(next_widget, playerID) &&
|
||||
!GUIEngine::isFocusedForPlayer(cancel_widget, playerID);
|
||||
if (interpret_as_next && m_phase == Terms)
|
||||
{
|
||||
ButtonWidget * previous_widget = getWidget<ButtonWidget>("previous");
|
||||
interpret_as_next = interpret_as_next && !GUIEngine::isFocusedForPlayer(previous_widget, playerID);
|
||||
}
|
||||
if (interpret_as_next)
|
||||
{
|
||||
|
||||
if (GUIEngine::isFocusedForPlayer(m_options_widget, PLAYER_ID_GAME_MASTER))
|
||||
return;
|
||||
if (m_next_widget->isActivated())
|
||||
processEvent("next");
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void RegistrationDialog::onUpdate(float dt)
|
||||
{
|
||||
if (m_phase == Terms)
|
||||
{
|
||||
if(m_sign_up_request != NULL)
|
||||
{
|
||||
if(m_sign_up_request->isDone())
|
||||
{
|
||||
if(m_sign_up_request->isSuccess())
|
||||
{
|
||||
m_show_registration_activation = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
sfx_manager->quickSound( "anvil" );
|
||||
m_show_registration_info = true;
|
||||
m_registration_error = m_sign_up_request->getInfo();
|
||||
}
|
||||
delete m_sign_up_request;
|
||||
m_sign_up_request = NULL;
|
||||
//FIXME m_options_widget->setActivated();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_info_widget->setDefaultColor();
|
||||
m_info_widget->setText(Messages::signingUp(), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (m_phase == Activation)
|
||||
{
|
||||
/*
|
||||
XMLRequest * sign_up_request = HTTPManager::get()->getXMLResponse(Request::RT_SIGN_UP);
|
||||
if(sign_up_request != NULL)
|
||||
{
|
||||
if(sign_up_request->isSuccess())
|
||||
{
|
||||
m_show_registration_activation = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
sfx_manager->quickSound( "anvil" );
|
||||
m_show_registration_info = true;
|
||||
m_registration_error = sign_up_request->getInfo();
|
||||
}
|
||||
delete sign_up_request;
|
||||
m_signing_up = false;
|
||||
//FIXME m_options_widget->setActivated();
|
||||
}*/
|
||||
}
|
||||
// It's unsafe to delete from inside the event handler so we do it here
|
||||
if (m_self_destroy)
|
||||
{
|
||||
ModalDialog::dismiss();
|
||||
}
|
||||
if (m_show_registration_info)
|
||||
else if (m_show_registration_info)
|
||||
showRegistrationInfo();
|
||||
if (m_show_registration_terms)
|
||||
else if (m_show_registration_terms)
|
||||
showRegistrationTerms();
|
||||
if (m_show_registration_activation)
|
||||
else if (m_show_registration_activation)
|
||||
showRegistrationActivation();
|
||||
}
|
||||
|
@ -22,6 +22,8 @@
|
||||
#include <irrString.h>
|
||||
|
||||
#include "guiengine/modaldialog.hpp"
|
||||
#include "guiengine/widgets.hpp"
|
||||
#include "online/current_user.hpp"
|
||||
/**
|
||||
* \brief Dialog that allows a user to register
|
||||
* \ingroup states_screens
|
||||
@ -37,21 +39,26 @@ public:
|
||||
Activation = 4
|
||||
};
|
||||
|
||||
RegistrationDialog(const float percentWidth, const float percentHeight, const Phase phase = Info);
|
||||
RegistrationDialog(const Phase phase = Info);
|
||||
~RegistrationDialog();
|
||||
|
||||
void onEnterPressedInternal();
|
||||
GUIEngine::EventPropagation processEvent(const std::string& eventSource);
|
||||
|
||||
virtual void onUpdate(float dt);
|
||||
virtual bool onEscapePressed();
|
||||
|
||||
private:
|
||||
|
||||
Phase m_phase;
|
||||
bool m_self_destroy;
|
||||
bool m_show_registration_info;
|
||||
bool m_show_registration_terms;
|
||||
bool m_show_registration_activation;
|
||||
|
||||
Online::XMLRequest * m_sign_up_request;
|
||||
Online::XMLRequest * m_activation_request;
|
||||
|
||||
//Saved user input :
|
||||
irr::core::stringw m_username;
|
||||
irr::core::stringw m_password;
|
||||
@ -61,6 +68,21 @@ private:
|
||||
irr::core::stringw m_registration_error;
|
||||
bool m_agreement;
|
||||
|
||||
GUIEngine::TextBoxWidget * m_username_widget;
|
||||
GUIEngine::TextBoxWidget * m_password_widget;
|
||||
GUIEngine::TextBoxWidget * m_password_confirm_widget;
|
||||
GUIEngine::TextBoxWidget * m_email_widget;
|
||||
GUIEngine::TextBoxWidget * m_email_confirm_widget;
|
||||
|
||||
GUIEngine::LabelWidget * m_info_widget;
|
||||
|
||||
GUIEngine::RibbonWidget * m_options_widget;
|
||||
GUIEngine::IconButtonWidget * m_previous_widget;
|
||||
GUIEngine::IconButtonWidget * m_next_widget;
|
||||
GUIEngine::IconButtonWidget * m_cancel_widget;
|
||||
|
||||
GUIEngine::CheckBoxWidget * m_accept_terms_widget;
|
||||
|
||||
void showRegistrationInfo();
|
||||
void showRegistrationTerms();
|
||||
void showRegistrationActivation();
|
||||
|
159
src/states_screens/dialogs/server_info_dialog.cpp
Normal file
159
src/states_screens/dialogs/server_info_dialog.cpp
Normal file
@ -0,0 +1,159 @@
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2013 Glenn De Jonghe
|
||||
//
|
||||
// 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 "states_screens/dialogs/server_info_dialog.hpp"
|
||||
|
||||
#include <IGUIEnvironment.h>
|
||||
|
||||
#include "audio/sfx_manager.hpp"
|
||||
#include "config/player.hpp"
|
||||
#include "guiengine/engine.hpp"
|
||||
#include "states_screens/state_manager.hpp"
|
||||
#include "utils/translation.hpp"
|
||||
#include "utils/string_utils.hpp"
|
||||
#include "online/current_user.hpp"
|
||||
#include "online/servers_manager.hpp"
|
||||
#include "online/messages.hpp"
|
||||
#include "states_screens/dialogs/registration_dialog.hpp"
|
||||
#include "states_screens/networking_lobby.hpp"
|
||||
|
||||
|
||||
|
||||
using namespace GUIEngine;
|
||||
using namespace irr;
|
||||
using namespace irr::gui;
|
||||
using namespace Online;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
ServerInfoDialog::ServerInfoDialog(uint32_t server_id, bool from_server_creation) :
|
||||
ModalDialog(0.8f,0.8f)
|
||||
{
|
||||
m_server_id = server_id;
|
||||
m_self_destroy = false;
|
||||
m_enter_lobby = false;
|
||||
m_from_server_creation = from_server_creation;
|
||||
m_server_join_request = NULL;
|
||||
|
||||
loadFromFile("online/server_info_dialog.stkgui");
|
||||
|
||||
m_name_widget = getWidget<LabelWidget>("name");
|
||||
assert(m_name_widget != NULL);
|
||||
Server * server = ServersManager::acquire()->getServerByID(m_server_id);
|
||||
m_name_widget->setText(server->getName(),false);
|
||||
ServersManager::release();
|
||||
m_info_widget = getWidget<LabelWidget>("info");
|
||||
assert(m_info_widget != NULL);
|
||||
if (m_from_server_creation)
|
||||
m_info_widget->setText(_("Server successfully created. You can now join it."), true);
|
||||
m_options_widget = getWidget<RibbonWidget>("options");
|
||||
assert(m_options_widget != NULL);
|
||||
m_join_widget = getWidget<IconButtonWidget>("join");
|
||||
assert(m_join_widget != NULL);
|
||||
m_cancel_widget = getWidget<IconButtonWidget>("cancel");
|
||||
assert(m_cancel_widget != NULL);
|
||||
m_options_widget->setFocusForPlayer(PLAYER_ID_GAME_MASTER);
|
||||
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
ServerInfoDialog::~ServerInfoDialog()
|
||||
{
|
||||
delete m_server_join_request;
|
||||
}
|
||||
// -----------------------------------------------------------------------------
|
||||
void ServerInfoDialog::requestJoin()
|
||||
{
|
||||
m_server_join_request = Online::CurrentUser::acquire()->requestServerJoin(m_server_id);
|
||||
Online::CurrentUser::release();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
GUIEngine::EventPropagation ServerInfoDialog::processEvent(const std::string& eventSource)
|
||||
{
|
||||
|
||||
if (eventSource == m_options_widget->m_properties[PROP_ID])
|
||||
{
|
||||
const std::string& selection = m_options_widget->getSelectionIDString(PLAYER_ID_GAME_MASTER);
|
||||
if (selection == m_cancel_widget->m_properties[PROP_ID])
|
||||
{
|
||||
m_self_destroy = true;
|
||||
return GUIEngine::EVENT_BLOCK;
|
||||
}
|
||||
else if(selection == m_join_widget->m_properties[PROP_ID])
|
||||
{
|
||||
requestJoin();
|
||||
return GUIEngine::EVENT_BLOCK;
|
||||
}
|
||||
}
|
||||
return GUIEngine::EVENT_LET;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void ServerInfoDialog::onEnterPressedInternal()
|
||||
{
|
||||
|
||||
//If enter was pressed while none of the buttons was focused interpret as join event
|
||||
const int playerID = PLAYER_ID_GAME_MASTER;
|
||||
if (GUIEngine::isFocusedForPlayer(m_options_widget, playerID))
|
||||
return;
|
||||
requestJoin();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void ServerInfoDialog::onUpdate(float dt)
|
||||
{
|
||||
if(m_server_join_request != NULL)
|
||||
{
|
||||
if(m_server_join_request->isDone())
|
||||
{
|
||||
if(m_server_join_request->isSuccess())
|
||||
{
|
||||
m_enter_lobby = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
sfx_manager->quickSound( "anvil" );
|
||||
m_info_widget->setErrorColor();
|
||||
m_info_widget->setText(m_server_join_request->getInfo(), false);
|
||||
}
|
||||
delete m_server_join_request;
|
||||
m_server_join_request = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_info_widget->setDefaultColor();
|
||||
m_info_widget->setText(Online::Messages::joiningServer(), false);
|
||||
}
|
||||
}
|
||||
|
||||
//If we want to open the registration dialog, we need to close this one first
|
||||
m_enter_lobby && (m_self_destroy = true);
|
||||
|
||||
// It's unsafe to delete from inside the event handler so we do it here
|
||||
if (m_self_destroy)
|
||||
{
|
||||
ModalDialog::dismiss();
|
||||
if (m_from_server_creation)
|
||||
StateManager::get()->popMenu();
|
||||
if (m_enter_lobby)
|
||||
StateManager::get()->pushScreen(NetworkingLobby::getInstance());
|
||||
return;
|
||||
}
|
||||
}
|
70
src/states_screens/dialogs/server_info_dialog.hpp
Normal file
70
src/states_screens/dialogs/server_info_dialog.hpp
Normal file
@ -0,0 +1,70 @@
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2013 Glenn De Jonghe
|
||||
//
|
||||
// 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_SERVER_INFO_DIALOG_HPP
|
||||
#define HEADER_SERVER_INFO_DIALOG_HPP
|
||||
|
||||
#include <irrString.h>
|
||||
|
||||
#include "guiengine/modaldialog.hpp"
|
||||
#include "guiengine/widgets/icon_button_widget.hpp"
|
||||
#include "guiengine/widgets/ribbon_widget.hpp"
|
||||
#include "guiengine/widgets/label_widget.hpp"
|
||||
#include "online/server.hpp"
|
||||
#include "online/current_user.hpp"
|
||||
#include "utils/types.hpp"
|
||||
|
||||
|
||||
/**
|
||||
* \brief Dialog that allows a user to sign in
|
||||
* \ingroup states_screens
|
||||
*/
|
||||
class ServerInfoDialog : public GUIEngine::ModalDialog
|
||||
{
|
||||
|
||||
private:
|
||||
|
||||
bool m_self_destroy;
|
||||
bool m_enter_lobby;
|
||||
bool m_from_server_creation;
|
||||
Online::CurrentUser::ServerJoinRequest * m_server_join_request;
|
||||
|
||||
float m_load_timer;
|
||||
|
||||
uint32_t m_server_id;
|
||||
|
||||
GUIEngine::LabelWidget * m_name_widget;
|
||||
GUIEngine::LabelWidget * m_info_widget;
|
||||
|
||||
GUIEngine::RibbonWidget * m_options_widget;
|
||||
GUIEngine::IconButtonWidget * m_join_widget;
|
||||
GUIEngine::IconButtonWidget * m_cancel_widget;
|
||||
|
||||
void requestJoin();
|
||||
|
||||
public:
|
||||
ServerInfoDialog(uint32_t server_id, bool just_created = false);
|
||||
~ServerInfoDialog();
|
||||
|
||||
void onEnterPressedInternal();
|
||||
GUIEngine::EventPropagation processEvent(const std::string& eventSource);
|
||||
|
||||
virtual void onUpdate(float dt);
|
||||
};
|
||||
|
||||
#endif
|
@ -35,10 +35,9 @@
|
||||
#include "states_screens/dialogs/message_dialog.hpp"
|
||||
#include "modes/demo_world.hpp"
|
||||
#include "utils/translation.hpp"
|
||||
#include "online/servers_manager.hpp"
|
||||
|
||||
#include "online/current_online_user.hpp"
|
||||
|
||||
|
||||
using namespace Online;
|
||||
using namespace GUIEngine;
|
||||
|
||||
DEFINE_SCREEN_SINGLETON( NetworkingLobby );
|
||||
@ -47,30 +46,30 @@ DEFINE_SCREEN_SINGLETON( NetworkingLobby );
|
||||
|
||||
NetworkingLobby::NetworkingLobby() : Screen("online/lobby.stkgui")
|
||||
{
|
||||
|
||||
m_server = NULL;
|
||||
} // NetworkingLobby
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void NetworkingLobby::loadedFromFile()
|
||||
{
|
||||
m_back_widget = getWidget<IconButtonWidget>("back");
|
||||
assert(m_back_widget != NULL);
|
||||
|
||||
m_server_name_widget = getWidget<LabelWidget>("server_name");
|
||||
assert(m_server_name_widget != NULL);
|
||||
|
||||
m_online_status_widget = getWidget<LabelWidget>("online_status");
|
||||
assert(m_online_status_widget != NULL);
|
||||
|
||||
m_bottom_menu_widget = getWidget<RibbonWidget>("menu_bottomrow");
|
||||
assert(m_bottom_menu_widget != NULL);
|
||||
/*m_sign_in_widget = (IconButtonWidget *) m_bottom_menu_widget->findWidgetNamed("sign_in");
|
||||
assert(m_sign_in_widget != NULL);*/
|
||||
|
||||
m_exit_widget = (IconButtonWidget *) m_bottom_menu_widget->findWidgetNamed("exit");
|
||||
assert(m_exit_widget != NULL);
|
||||
|
||||
} // loadedFromFile
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
bool NetworkingLobby::hasLostConnection()
|
||||
{
|
||||
return !CurrentOnlineUser::get()->isSignedIn();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void NetworkingLobby::beforeAddingWidget()
|
||||
{
|
||||
@ -85,7 +84,10 @@ void NetworkingLobby::init()
|
||||
Screen::init();
|
||||
setInitialFocus();
|
||||
DemoWorld::resetIdleTime(); //FIXME : what's this?
|
||||
m_online_status_widget->setText(irr::core::stringw(_("Signed in as : ")) + CurrentOnlineUser::get()->getUserName() + ".", false);
|
||||
m_server = ServersManager::acquire()->getJoinedServer();
|
||||
ServersManager::release();
|
||||
m_server_name_widget->setText(m_server->getName(),false);
|
||||
|
||||
} // init
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -97,7 +99,20 @@ void NetworkingLobby::onUpdate(float delta, irr::video::IVideoDriver* driver)
|
||||
|
||||
void NetworkingLobby::eventCallback(Widget* widget, const std::string& name, const int playerID)
|
||||
{
|
||||
if (name == m_back_widget->m_properties[PROP_ID])
|
||||
{
|
||||
StateManager::get()->escapePressed();
|
||||
return;
|
||||
}
|
||||
|
||||
RibbonWidget* ribbon = dynamic_cast<RibbonWidget*>(widget);
|
||||
if (ribbon == NULL) return;
|
||||
std::string selection = ribbon->getSelectionIDString(PLAYER_ID_GAME_MASTER);
|
||||
|
||||
if (selection == m_exit_widget->m_properties[PROP_ID])
|
||||
{
|
||||
StateManager::get()->escapePressed();
|
||||
}
|
||||
} // eventCallback
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "guiengine/widgets/label_widget.hpp"
|
||||
#include "guiengine/widgets/ribbon_widget.hpp"
|
||||
#include "guiengine/widgets/icon_button_widget.hpp"
|
||||
#include "online/server.hpp"
|
||||
|
||||
namespace GUIEngine { class Widget; class ListWidget; }
|
||||
|
||||
@ -35,17 +36,19 @@ class NetworkingLobby : public GUIEngine::Screen,
|
||||
private:
|
||||
friend class GUIEngine::ScreenSingleton<NetworkingLobby>;
|
||||
|
||||
Online::Server * m_server;
|
||||
|
||||
NetworkingLobby();
|
||||
|
||||
GUIEngine::IconButtonWidget * m_back_widget;
|
||||
|
||||
GUIEngine::LabelWidget * m_server_name_widget;
|
||||
|
||||
GUIEngine::LabelWidget * m_online_status_widget;
|
||||
|
||||
GUIEngine::RibbonWidget * m_bottom_menu_widget;
|
||||
GUIEngine::IconButtonWidget * m_sign_in_widget;
|
||||
GUIEngine::IconButtonWidget * m_register_widget;
|
||||
GUIEngine::IconButtonWidget * m_sign_out_widget;
|
||||
GUIEngine::IconButtonWidget * m_exit_widget;
|
||||
|
||||
/** \brief Checks if the user is still signed in. */
|
||||
bool hasLostConnection();
|
||||
/** \brief Sets which widget has to be focused. Depends on the user state. */
|
||||
void setInitialFocus();
|
||||
|
||||
|
@ -36,7 +36,7 @@
|
||||
#include "modes/demo_world.hpp"
|
||||
#include "utils/translation.hpp"
|
||||
|
||||
#include "online/current_online_user.hpp"
|
||||
#include "online/current_user.hpp"
|
||||
|
||||
|
||||
using namespace GUIEngine;
|
||||
@ -60,7 +60,7 @@ void NetworkingLobbySettings::loadedFromFile()
|
||||
// ----------------------------------------------------------------------------
|
||||
bool NetworkingLobbySettings::hasLostConnection()
|
||||
{
|
||||
return !CurrentOnlineUser::get()->isSignedIn();
|
||||
return !Online::CurrentUser::acquire()->isSignedIn();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -22,31 +22,31 @@
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
#include "challenges/game_slot.hpp"
|
||||
#include "challenges/unlock_manager.hpp"
|
||||
#include "audio/sfx_manager.hpp"
|
||||
#include "graphics/irr_driver.hpp"
|
||||
#include "guiengine/scalable_font.hpp"
|
||||
#include "input/device_manager.hpp"
|
||||
#include "input/input_manager.hpp"
|
||||
#include "io/file_manager.hpp"
|
||||
#include "main_loop.hpp"
|
||||
#include "states_screens/online_screen.hpp"
|
||||
#include "states_screens/state_manager.hpp"
|
||||
#include "states_screens/dialogs/message_dialog.hpp"
|
||||
#include "states_screens/dialogs/login_dialog.hpp"
|
||||
#include "states_screens/dialogs/registration_dialog.hpp"
|
||||
#include "states_screens/networking_lobby.hpp"
|
||||
#include "states_screens/networking_lobby_settings.hpp"
|
||||
#include "states_screens/server_selection.hpp"
|
||||
#include "states_screens/create_server_screen.hpp"
|
||||
#include "modes/demo_world.hpp"
|
||||
#include "utils/translation.hpp"
|
||||
#include "online/servers_manager.hpp"
|
||||
#include "online/messages.hpp"
|
||||
|
||||
#include "online/current_online_user.hpp"
|
||||
|
||||
#include "network/protocol_manager.hpp"
|
||||
#include "network/protocols/connect_to_server.hpp"
|
||||
|
||||
|
||||
using namespace GUIEngine;
|
||||
using namespace Online;
|
||||
|
||||
DEFINE_SCREEN_SINGLETON( OnlineScreen );
|
||||
|
||||
@ -54,11 +54,22 @@ DEFINE_SCREEN_SINGLETON( OnlineScreen );
|
||||
|
||||
OnlineScreen::OnlineScreen() : Screen("online/main.stkgui")
|
||||
{
|
||||
m_recorded_state = Not;
|
||||
m_recorded_state = CurrentUser::US_SIGNED_OUT;
|
||||
CurrentUser::SignInRequest * request = CurrentUser::acquire()->requestSavedSession();
|
||||
if(request != NULL)
|
||||
m_requests.push_back(request);
|
||||
CurrentUser::release();
|
||||
} // OnlineScreen
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
OnlineScreen::~OnlineScreen()
|
||||
{
|
||||
m_requests.clearAndDeleteAll();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void OnlineScreen::loadedFromFile()
|
||||
{
|
||||
//Box ? FIXME
|
||||
@ -88,16 +99,9 @@ void OnlineScreen::loadedFromFile()
|
||||
// ----------------------------------------------------------------------------
|
||||
bool OnlineScreen::hasStateChanged()
|
||||
{
|
||||
State previous_state = m_recorded_state;
|
||||
if(CurrentOnlineUser::get()->isSignedIn())
|
||||
{
|
||||
if(CurrentOnlineUser::get()->isGuest())
|
||||
m_recorded_state = Guest;
|
||||
else
|
||||
m_recorded_state = Registered;
|
||||
}
|
||||
else
|
||||
m_recorded_state = Not;
|
||||
CurrentUser::UserState previous_state = m_recorded_state;
|
||||
m_recorded_state = CurrentUser::acquire()->getUserState();
|
||||
CurrentUser::release();
|
||||
if (previous_state != m_recorded_state)
|
||||
return true;
|
||||
return false;
|
||||
@ -109,21 +113,25 @@ void OnlineScreen::beforeAddingWidget()
|
||||
//Set everything that could be set invisible or deactivated, to active and visible
|
||||
m_bottom_menu_widget->setVisible(true);
|
||||
m_top_menu_widget->setVisible(true);
|
||||
|
||||
hasStateChanged();
|
||||
if (m_recorded_state == Registered)
|
||||
if (m_recorded_state == CurrentUser::US_SIGNED_IN)
|
||||
{
|
||||
m_register_widget->setVisible(false);
|
||||
m_sign_in_widget->setVisible(false);
|
||||
}
|
||||
else if (m_recorded_state == Not)
|
||||
else if (m_recorded_state == CurrentUser::US_SIGNED_OUT || m_recorded_state == CurrentUser::US_SIGNING_IN || m_recorded_state == CurrentUser::US_SIGNING_OUT)
|
||||
{
|
||||
m_quick_play_widget->setDeactivated();
|
||||
m_find_server_widget->setDeactivated();
|
||||
m_create_server_widget->setDeactivated();
|
||||
m_sign_out_widget->setVisible(false);
|
||||
if(m_recorded_state == CurrentUser::US_SIGNING_IN || m_recorded_state == CurrentUser::US_SIGNING_OUT)
|
||||
{
|
||||
m_register_widget->setDeactivated();
|
||||
m_sign_in_widget->setDeactivated();
|
||||
}
|
||||
}
|
||||
else if (m_recorded_state == Guest)
|
||||
else if (m_recorded_state == CurrentUser::US_GUEST)
|
||||
{
|
||||
m_find_server_widget->setDeactivated();
|
||||
m_create_server_widget->setDeactivated();
|
||||
@ -139,8 +147,10 @@ void OnlineScreen::init()
|
||||
{
|
||||
Screen::init();
|
||||
setInitialFocus();
|
||||
DemoWorld::resetIdleTime(); //FIXME : what's this?
|
||||
m_online_status_widget->setText(irr::core::stringw(_("Signed in as : ")) + CurrentOnlineUser::get()->getUserName() + ".", false);
|
||||
DemoWorld::resetIdleTime();
|
||||
m_online_status_widget->setText(Messages::signedInAs(CurrentUser::acquire()->getUserName()), false);
|
||||
CurrentUser::release();
|
||||
|
||||
} // init
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -148,6 +158,36 @@ void OnlineScreen::onUpdate(float delta, irr::video::IVideoDriver* driver)
|
||||
{
|
||||
if (hasStateChanged())
|
||||
GUIEngine::reshowCurrentScreen();
|
||||
if (m_recorded_state == CurrentUser::US_SIGNING_IN)
|
||||
{
|
||||
m_online_status_widget->setText(Messages::signingIn(), false);
|
||||
}
|
||||
else if (m_recorded_state == CurrentUser::US_SIGNING_OUT)
|
||||
{
|
||||
m_online_status_widget->setText(Messages::signingOut(), false);
|
||||
}
|
||||
for(int i = m_requests.size()-1; i>=0; --i)
|
||||
{
|
||||
if(m_requests[i].isDone())
|
||||
{
|
||||
if(m_requests[i].getType() == CurrentUser::RT_SIGN_IN)
|
||||
{
|
||||
if(m_requests[i].isSuccess())
|
||||
{
|
||||
new MessageDialog(_("Signed in."));
|
||||
}
|
||||
else
|
||||
{
|
||||
sfx_manager->quickSound( "anvil" );
|
||||
new MessageDialog(m_requests[i].getInfo());
|
||||
}
|
||||
}else if(m_requests[i].getType() == CurrentUser::RT_SIGN_OUT)
|
||||
{
|
||||
new MessageDialog(_("Signed out successfully."));
|
||||
}
|
||||
m_requests.erase(i);
|
||||
}
|
||||
}
|
||||
} // onUpdate
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -157,10 +197,11 @@ void OnlineScreen::eventCallback(Widget* widget, const std::string& name, const
|
||||
if (name == "back")
|
||||
{
|
||||
StateManager::get()->escapePressed();
|
||||
return;
|
||||
}
|
||||
|
||||
RibbonWidget* ribbon = dynamic_cast<RibbonWidget*>(widget);
|
||||
if (ribbon == NULL) return; // what's that event??
|
||||
if (ribbon == NULL) return;
|
||||
std::string selection = ribbon->getSelectionIDString(PLAYER_ID_GAME_MASTER);
|
||||
|
||||
if (selection == "sign_in")
|
||||
@ -169,42 +210,45 @@ void OnlineScreen::eventCallback(Widget* widget, const std::string& name, const
|
||||
}
|
||||
else if (selection == "sign_out")
|
||||
{
|
||||
if (CurrentOnlineUser::get()->signOut())
|
||||
{
|
||||
new MessageDialog( _("Signed out successfully.") );
|
||||
//GUIEngine::reshowCurrentScreen();
|
||||
}
|
||||
else
|
||||
new MessageDialog( _("An error occured while signing out.") );
|
||||
CurrentUser::acquire()->requestSignOut();
|
||||
CurrentUser::release();
|
||||
}
|
||||
else if (selection == "register")
|
||||
{
|
||||
new RegistrationDialog(0.8f, 0.9f);
|
||||
new RegistrationDialog();
|
||||
}
|
||||
else if (selection == "find_server")
|
||||
{
|
||||
//if (m_recorded_state == Registered)
|
||||
new MessageDialog("Coming soon!");
|
||||
StateManager::get()->pushScreen(ServerSelection::getInstance());
|
||||
}
|
||||
else if (selection == "create_server")
|
||||
{
|
||||
//if (m_recorded_state == Registered)
|
||||
StateManager::get()->pushScreen(NetworkingLobbySettings::getInstance());
|
||||
StateManager::get()->pushScreen(CreateServerScreen::getInstance());
|
||||
}
|
||||
else if (selection == "quick_play")
|
||||
{
|
||||
//if (m_recorded_state == Registered || m_recorded_state == Guest) FIXME
|
||||
StateManager::get()->pushScreen(NetworkingLobby::getInstance());
|
||||
//FIXME temporary and the request join + join sequence should be placed in one method somewhere
|
||||
/*
|
||||
Server * server = ServersManager::get()->getQuickPlay();
|
||||
irr::core::stringw info;
|
||||
if (Online::CurrentUser::get()->requestJoin( server->getServerId(), info))
|
||||
{
|
||||
ServersManager::get()->setJoinedServer(server);
|
||||
StateManager::get()->pushScreen(NetworkingLobby::getInstance());
|
||||
}
|
||||
else
|
||||
{
|
||||
sfx_manager->quickSound( "anvil" );
|
||||
}*/
|
||||
ProtocolManager::getInstance()->requestStart(new ConnectToServer(7));
|
||||
}
|
||||
|
||||
} // eventCallback
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void OnlineScreen::tearDown()
|
||||
{
|
||||
} // tearDown
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void OnlineScreen::onDisabledItemClicked(const std::string& item)
|
||||
@ -215,23 +259,22 @@ void OnlineScreen::onDisabledItemClicked(const std::string& item)
|
||||
}
|
||||
else if (item =="create_server")
|
||||
{
|
||||
StateManager::get()->pushScreen(NetworkingLobbySettings::getInstance());
|
||||
// FIXME temporary; new LoginDialog(LoginDialog::Registration_Required);
|
||||
new LoginDialog(LoginDialog::Registration_Required);
|
||||
}
|
||||
else if (item == "quick_play")
|
||||
{
|
||||
StateManager::get()->pushScreen(NetworkingLobby::getInstance());
|
||||
// FIXME temporary; new LoginDialog(LoginDialog::Signing_In_Required);
|
||||
new LoginDialog(LoginDialog::Signing_In_Required);
|
||||
}
|
||||
} // onDisabledItemClicked
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void OnlineScreen::setInitialFocus()
|
||||
{
|
||||
if(m_recorded_state == Not)
|
||||
m_bottom_menu_widget->setFocusForPlayer(PLAYER_ID_GAME_MASTER);
|
||||
else
|
||||
if(m_recorded_state == CurrentUser::US_SIGNED_IN)
|
||||
m_top_menu_widget->setFocusForPlayer(PLAYER_ID_GAME_MASTER);
|
||||
else
|
||||
m_bottom_menu_widget->setFocusForPlayer(PLAYER_ID_GAME_MASTER);
|
||||
|
||||
} // setInitialFocus
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -242,3 +285,4 @@ void OnlineScreen::onDialogClose()
|
||||
else
|
||||
setInitialFocus();
|
||||
} // onDialogClose()
|
||||
|
||||
|
@ -22,6 +22,8 @@
|
||||
#include "guiengine/widgets/label_widget.hpp"
|
||||
#include "guiengine/widgets/ribbon_widget.hpp"
|
||||
#include "guiengine/widgets/icon_button_widget.hpp"
|
||||
#include "online/current_user.hpp"
|
||||
#include "utils/ptr_vector.hpp"
|
||||
|
||||
namespace GUIEngine { class Widget; class ListWidget; }
|
||||
|
||||
@ -36,6 +38,7 @@ private:
|
||||
friend class GUIEngine::ScreenSingleton<OnlineScreen>;
|
||||
|
||||
OnlineScreen();
|
||||
~OnlineScreen();
|
||||
|
||||
GUIEngine::RibbonWidget * m_top_menu_widget;
|
||||
GUIEngine::IconButtonWidget * m_quick_play_widget;
|
||||
@ -49,14 +52,9 @@ private:
|
||||
GUIEngine::IconButtonWidget * m_register_widget;
|
||||
GUIEngine::IconButtonWidget * m_sign_out_widget;
|
||||
|
||||
enum State
|
||||
{
|
||||
Not = 1,
|
||||
Guest = 2,
|
||||
Registered = 4
|
||||
};
|
||||
Online::CurrentUser::UserState m_recorded_state;
|
||||
|
||||
State m_recorded_state;
|
||||
PtrVector<Online::XMLRequest> m_requests;
|
||||
|
||||
/** \brief Checks if the recorded state differs from the actual state and sets it. */
|
||||
bool hasStateChanged();
|
||||
|
220
src/states_screens/server_selection.cpp
Normal file
220
src/states_screens/server_selection.cpp
Normal file
@ -0,0 +1,220 @@
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2010 Lucas Baudin, Joerg Henrichs
|
||||
//
|
||||
// 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 "states_screens/server_selection.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <assert.h>
|
||||
|
||||
#include "guiengine/modaldialog.hpp"
|
||||
#include "states_screens/dialogs/message_dialog.hpp"
|
||||
#include "states_screens/dialogs/server_info_dialog.hpp"
|
||||
#include "states_screens/state_manager.hpp"
|
||||
#include "utils/translation.hpp"
|
||||
#include "utils/string_utils.hpp"
|
||||
#include "online/messages.hpp"
|
||||
#include "audio/sfx_manager.hpp"
|
||||
|
||||
using namespace Online;
|
||||
|
||||
DEFINE_SCREEN_SINGLETON( ServerSelection );
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
ServerSelection::ServerSelection() : Screen("online/server_selection.stkgui")
|
||||
{
|
||||
m_selected_index = -1;
|
||||
m_refresh_request = NULL;
|
||||
|
||||
} // ServerSelection
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
ServerSelection::~ServerSelection()
|
||||
{
|
||||
} // ServerSelection
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void ServerSelection::tearDown()
|
||||
{
|
||||
delete m_refresh_request;
|
||||
} // tearDown
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void ServerSelection::refresh()
|
||||
{
|
||||
m_refresh_request = ServersManager::acquire()->refreshRequest();
|
||||
ServersManager::release();
|
||||
m_fake_refresh = (m_refresh_request == NULL ? true : false);
|
||||
m_server_list_widget->clear();
|
||||
m_server_list_widget->addItem("spacer", L"");
|
||||
m_server_list_widget->addItem("loading", Messages::fetchingServers());
|
||||
m_reload_widget->setDeactivated();
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void ServerSelection::loadedFromFile()
|
||||
{
|
||||
m_back_widget = getWidget<GUIEngine::IconButtonWidget>("back");
|
||||
assert(m_back_widget != NULL);
|
||||
m_reload_widget = getWidget<GUIEngine::IconButtonWidget>("reload");
|
||||
assert(m_reload_widget != NULL);
|
||||
m_server_list_widget = getWidget<GUIEngine::ListWidget>("server_list");
|
||||
assert(m_server_list_widget != NULL);
|
||||
m_server_list_widget->setColumnListener(this);
|
||||
} // loadedFromFile
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void ServerSelection::beforeAddingWidget()
|
||||
{
|
||||
m_server_list_widget->clearColumns();
|
||||
m_server_list_widget->addColumn( _("Name"), 3 );
|
||||
m_server_list_widget->addColumn( _("Players"), 1);
|
||||
}
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void ServerSelection::init()
|
||||
{
|
||||
Screen::init();
|
||||
m_sort_desc = true;
|
||||
|
||||
|
||||
// Set the default sort order
|
||||
Server::setSortOrder(Server::SO_NAME);
|
||||
refresh();
|
||||
} // init
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Loads the list of all servers. The gui element will be
|
||||
* updated.
|
||||
* \param type Must be 'kart' or 'track'.
|
||||
*/
|
||||
void ServerSelection::loadList()
|
||||
{
|
||||
m_server_list_widget->clear();
|
||||
ServersManager * manager = ServersManager::acquire();
|
||||
manager->sort(m_sort_desc);
|
||||
for(int i=0; i < manager->getNumServers(); i++)
|
||||
{
|
||||
Server * server = manager->getServerBySort(i);
|
||||
core::stringw num_players;
|
||||
num_players.append(StringUtils::toWString(server->getCurrentPlayers()));
|
||||
num_players.append("/");
|
||||
num_players.append(StringUtils::toWString(server->getMaxPlayers()));
|
||||
PtrVector<GUIEngine::ListWidget::ListCell> * row = new PtrVector<GUIEngine::ListWidget::ListCell>;
|
||||
row->push_back(new GUIEngine::ListWidget::ListCell(server->getName(),-1,3));
|
||||
row->push_back(new GUIEngine::ListWidget::ListCell(num_players,-1,1,true));
|
||||
m_server_list_widget->addItem("server", row);
|
||||
}
|
||||
ServersManager::release();
|
||||
} // loadList
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void ServerSelection::onColumnClicked(int column_id)
|
||||
{
|
||||
switch(column_id)
|
||||
{
|
||||
case 0: Server::setSortOrder(Server::SO_NAME); break;
|
||||
case 1: Server::setSortOrder(Server::SO_PLAYERS); break;
|
||||
default: assert(0); break;
|
||||
} // switch
|
||||
/** \brief Toggle the sort order after column click **/
|
||||
m_sort_desc = !m_sort_desc;
|
||||
loadList();
|
||||
} // onColumnClicked
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void ServerSelection::eventCallback( GUIEngine::Widget* widget,
|
||||
const std::string& name,
|
||||
const int playerID)
|
||||
{
|
||||
if (name == "back")
|
||||
{
|
||||
StateManager::get()->escapePressed();
|
||||
}
|
||||
|
||||
else if (name == "reload")
|
||||
{
|
||||
refresh();
|
||||
}
|
||||
|
||||
else if (name == m_server_list_widget->m_properties[GUIEngine::PROP_ID])
|
||||
{
|
||||
m_selected_index = m_server_list_widget->getSelectionID();
|
||||
uint32_t server_id = ServersManager::acquire()->getServerBySort(m_selected_index)->getServerId();
|
||||
ServersManager::release();
|
||||
new ServerInfoDialog(server_id);
|
||||
}
|
||||
|
||||
} // eventCallback
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Selects the last selected item on the list (which is the item that
|
||||
* is just being installed) again. This function is used from the
|
||||
* addons_loading screen: when it is closed, it will reset the
|
||||
* select item so that people can keep on installing from that
|
||||
* point on.
|
||||
*/
|
||||
void ServerSelection::setLastSelected()
|
||||
{
|
||||
if(m_selected_index>-1)
|
||||
{
|
||||
m_server_list_widget->setFocusForPlayer(PLAYER_ID_GAME_MASTER);
|
||||
m_server_list_widget->setSelectionID(m_selected_index);
|
||||
}
|
||||
} // setLastSelected
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void ServerSelection::onUpdate(float dt, irr::video::IVideoDriver*)
|
||||
{
|
||||
if(m_refresh_request != NULL)
|
||||
{
|
||||
if(m_refresh_request->isDone())
|
||||
{
|
||||
if(m_refresh_request->isSuccess())
|
||||
{
|
||||
loadList();
|
||||
}
|
||||
else
|
||||
{
|
||||
sfx_manager->quickSound( "anvil" );
|
||||
new MessageDialog(m_refresh_request->getInfo());
|
||||
}
|
||||
delete m_refresh_request;
|
||||
m_refresh_request = NULL;
|
||||
m_reload_widget->setActivated();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_server_list_widget->renameItem("loading", Messages::fetchingServers());
|
||||
}
|
||||
}
|
||||
else if(m_fake_refresh)
|
||||
{
|
||||
loadList();
|
||||
m_fake_refresh = false;
|
||||
m_reload_widget->setActivated();
|
||||
}
|
||||
} // onUpdate
|
88
src/states_screens/server_selection.hpp
Normal file
88
src/states_screens/server_selection.hpp
Normal file
@ -0,0 +1,88 @@
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2013 Glenn De Jonghe
|
||||
//
|
||||
// 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_SERVER_SELECTION_HPP
|
||||
#define HEADER_SERVER_SELECTION_HPP
|
||||
|
||||
#include "guiengine/screen.hpp"
|
||||
#include "guiengine/widgets.hpp"
|
||||
#include "online/servers_manager.hpp"
|
||||
|
||||
namespace GUIEngine { class Widget; }
|
||||
|
||||
/**
|
||||
* \brief ServerSelection
|
||||
* \ingroup states_screens
|
||||
*/
|
||||
class ServerSelection : public GUIEngine::Screen,
|
||||
public GUIEngine::ScreenSingleton<ServerSelection>,
|
||||
public GUIEngine::IListWidgetHeaderListener
|
||||
{
|
||||
friend class GUIEngine::ScreenSingleton<ServerSelection>;
|
||||
|
||||
private:
|
||||
ServerSelection();
|
||||
~ServerSelection();
|
||||
|
||||
GUIEngine::IconButtonWidget * m_back_widget;
|
||||
GUIEngine::IconButtonWidget * m_reload_widget;
|
||||
GUIEngine::LabelWidget * m_update_status;
|
||||
GUIEngine::ListWidget * m_server_list_widget;
|
||||
|
||||
/** Currently selected type. */
|
||||
std::string m_type;
|
||||
|
||||
/** The currently selected index, used to re-select this item after
|
||||
* addons_loading is being displayed. */
|
||||
int m_selected_index;
|
||||
|
||||
/** \brief To check (and set) if sort order is descending **/
|
||||
bool m_sort_desc;
|
||||
|
||||
Online::ServersManager::RefreshRequest * m_refresh_request;
|
||||
bool m_fake_refresh;
|
||||
void refresh();
|
||||
|
||||
public:
|
||||
|
||||
/** Load the addons into the main list.*/
|
||||
void loadList();
|
||||
|
||||
/** \brief implement callback from parent class GUIEngine::Screen */
|
||||
virtual void loadedFromFile() OVERRIDE;
|
||||
|
||||
/** \brief implement callback from parent class GUIEngine::Screen */
|
||||
virtual void eventCallback(GUIEngine::Widget* widget, const std::string& name,
|
||||
const int playerID) OVERRIDE;
|
||||
|
||||
/** \brief implement callback from parent class GUIEngine::Screen */
|
||||
virtual void beforeAddingWidget() OVERRIDE;
|
||||
|
||||
virtual void onColumnClicked(int columnId);
|
||||
|
||||
virtual void init() OVERRIDE;
|
||||
|
||||
virtual void tearDown() OVERRIDE;
|
||||
|
||||
/** \brief implement callback from parent class GUIEngine::Screen */
|
||||
virtual void onUpdate(float dt, irr::video::IVideoDriver*) OVERRIDE;
|
||||
|
||||
void setLastSelected();
|
||||
|
||||
};
|
||||
|
||||
#endif
|
@ -30,7 +30,7 @@
|
||||
#include "main_loop.hpp"
|
||||
#include "modes/profile_world.hpp"
|
||||
#include "modes/world.hpp"
|
||||
#include "online/online_user.hpp"
|
||||
#include "online/user.hpp"
|
||||
#include "utils/translation.hpp"
|
||||
#include "utils/log.hpp"
|
||||
|
||||
@ -103,7 +103,7 @@ void StateManager::updateActivePlayerIDs()
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
int StateManager::createActivePlayer(PlayerProfile *profile, InputDevice *device,
|
||||
OnlineUser* user)
|
||||
Online::User* user)
|
||||
{
|
||||
ActivePlayer *p;
|
||||
int i;
|
||||
@ -170,7 +170,8 @@ void StateManager::escapePressed()
|
||||
// when another modal dialog is visible
|
||||
else if(ModalDialog::isADialogActive())
|
||||
{
|
||||
ModalDialog::getCurrent()->escapePressed();
|
||||
if(ModalDialog::getCurrent()->onEscapePressed())
|
||||
ModalDialog::getCurrent()->dismiss();
|
||||
}
|
||||
// In-game
|
||||
else if(m_game_mode == GAME)
|
||||
@ -254,7 +255,7 @@ void StateManager::onStackEmptied()
|
||||
|
||||
StateManager::ActivePlayer::ActivePlayer(PlayerProfile* player,
|
||||
InputDevice *device,
|
||||
OnlineUser* user)
|
||||
Online::User* user)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
m_magic_number = 0xAC1EF1AE;
|
||||
|
@ -34,7 +34,10 @@
|
||||
class AbstractKart;
|
||||
class InputDevice;
|
||||
struct Input;
|
||||
class OnlineUser;
|
||||
namespace Online
|
||||
{
|
||||
class User;
|
||||
}
|
||||
|
||||
namespace GUIEngine
|
||||
{
|
||||
@ -73,7 +76,7 @@ public:
|
||||
{
|
||||
friend class StateManager;
|
||||
|
||||
OnlineUser *m_online_user;
|
||||
Online::User *m_online_user;
|
||||
PlayerProfile *m_player;
|
||||
InputDevice *m_device;
|
||||
|
||||
@ -83,7 +86,7 @@ public:
|
||||
/** ID of this player within the list of active players */
|
||||
int m_id;
|
||||
|
||||
ActivePlayer(PlayerProfile* player, InputDevice* device, OnlineUser* user);
|
||||
ActivePlayer(PlayerProfile* player, InputDevice* device, Online::User* user);
|
||||
|
||||
#ifdef DEBUG
|
||||
unsigned int m_magic_number;
|
||||
@ -125,14 +128,14 @@ public:
|
||||
void setPlayerProfile(PlayerProfile* player);
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
OnlineUser* getOnlineUser()
|
||||
Online::User* getOnlineUser()
|
||||
{
|
||||
return m_online_user;
|
||||
}
|
||||
// --------------------------------------------------------------------
|
||||
/** Call to change the identity of this player (useful when player is
|
||||
* selecting his identity) */
|
||||
void setOnlineUser(OnlineUser* user) { m_online_user = user; }
|
||||
void setOnlineUser(Online::User* user) { m_online_user = user; }
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
/** ID of this player within the list of active players */
|
||||
@ -190,7 +193,7 @@ public:
|
||||
*/
|
||||
const PlayerProfile* getActivePlayerProfile(const int id);
|
||||
|
||||
int createActivePlayer(PlayerProfile *profile, InputDevice *device, OnlineUser* use);
|
||||
int createActivePlayer(PlayerProfile *profile, InputDevice *device, Online::User* use);
|
||||
void removeActivePlayer(int id);
|
||||
|
||||
int activePlayerCount();
|
||||
|
Loading…
Reference in New Issue
Block a user