Merge branch 'master' into freetype_lazyloadchar
This commit is contained in:
commit
cee6d9d611
@ -416,7 +416,7 @@ if(MSVC OR MINGW)
|
||||
endif()
|
||||
|
||||
if(MINGW)
|
||||
find_library(LIBGCC NAMES "libgcc_s_dw2-1.dll" "libgcc_s_sjlj-1.dll" PATHS ${CMAKE_FIND_ROOT_PATH})
|
||||
find_library(LIBGCC NAMES "libgcc_s_dw2-1.dll" "libgcc_s_sjlj-1.dll" "libgcc_s_seh-1.dll" PATHS ${CMAKE_FIND_ROOT_PATH})
|
||||
if(LIBGCC)
|
||||
file(COPY ${LIBGCC} DESTINATION ${CMAKE_BINARY_DIR}/bin/)
|
||||
endif()
|
||||
|
20
cmake/Toolchain-mingw-64bit.cmake
Normal file
20
cmake/Toolchain-mingw-64bit.cmake
Normal file
@ -0,0 +1,20 @@
|
||||
# Usage:
|
||||
# cmake .. -DCMAKE_TOOLCHAIN_FILE=../cmake/Toolchain-mingw-64bit.cmake
|
||||
|
||||
# the name of the target operating system
|
||||
SET(CMAKE_SYSTEM_NAME Windows)
|
||||
|
||||
# which compilers to use for C and C++
|
||||
SET(CMAKE_C_COMPILER x86_64-w64-mingw32-gcc-posix)
|
||||
SET(CMAKE_CXX_COMPILER x86_64-w64-mingw32-g++-posix)
|
||||
SET(CMAKE_RC_COMPILER x86_64-w64-mingw32-windres)
|
||||
|
||||
# here is the target environment located
|
||||
SET(CMAKE_FIND_ROOT_PATH /usr/x86_64-w64-mingw32 /usr/lib/gcc/x86_64-w64-mingw32/4.9-posix ${PROJECT_SOURCE_DIR}/dependencies)
|
||||
|
||||
# adjust the default behaviour of the FIND_XXX() commands:
|
||||
# search headers and libraries in the target environment, search
|
||||
# programs in the host environment
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ALWAYS)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
@ -1,3 +1,6 @@
|
||||
# Usage:
|
||||
# cmake .. -DCMAKE_TOOLCHAIN_FILE=../cmake/Toolchain-mingw.cmake
|
||||
|
||||
# the name of the target operating system
|
||||
SET(CMAKE_SYSTEM_NAME Windows)
|
||||
|
||||
|
BIN
data/CREDITS
BIN
data/CREDITS
Binary file not shown.
@ -4,25 +4,27 @@
|
||||
<spreading angle="10" />
|
||||
|
||||
<velocity x="0.0"
|
||||
y="0.002"
|
||||
y="0.003"
|
||||
z="0.0" />
|
||||
|
||||
<material file="smoke_black.png" />
|
||||
|
||||
<!-- Amount of particles emitted per second -->
|
||||
<rate min="25"
|
||||
max="50" />
|
||||
<rate min="7"
|
||||
max="12" />
|
||||
|
||||
<!-- Minimal and maximal lifetime of a particle, in milliseconds. -->
|
||||
<lifetime min="2500"
|
||||
max="5000" />
|
||||
|
||||
<!-- Size of the particles -->
|
||||
<size min="0.6"
|
||||
max="1.5" />
|
||||
<size min="1.6"
|
||||
max="2.5"
|
||||
x-increase-factor="2.6"
|
||||
y-increase-factor="2.6" />
|
||||
|
||||
<color min="255 255 255"
|
||||
max="255 255 255" />
|
||||
<color min="50 50 50"
|
||||
max="100 100 100" />
|
||||
|
||||
<!-- How much time in milliseconds before the particle is fully faded out -->
|
||||
<fadeout time="1000" />
|
||||
|
@ -14,13 +14,13 @@
|
||||
max="100" />
|
||||
|
||||
<!-- Minimal and maximal lifetime of a particle, in milliseconds. -->
|
||||
<lifetime min="700"
|
||||
max="700" />
|
||||
<lifetime min="1700"
|
||||
max="1700" />
|
||||
|
||||
<!-- Size of the particles -->
|
||||
<size min="0.2"
|
||||
max="0.3"
|
||||
x-increase-factor="1.1"
|
||||
<size min="0.7"
|
||||
max="1.1"
|
||||
x-increase-factor="1.3"
|
||||
y-increase-factor="1.3"
|
||||
/>
|
||||
|
||||
|
33
data/gfx/gfx_fireworkGreen_a.xml
Normal file
33
data/gfx/gfx_fireworkGreen_a.xml
Normal file
@ -0,0 +1,33 @@
|
||||
<?xml version="1.0"?>
|
||||
<particles emitter="sphere" radius="0.5">
|
||||
|
||||
<spreading angle="180" />
|
||||
|
||||
<velocity x="0.03"
|
||||
y="0.003"
|
||||
z="0.03" />
|
||||
|
||||
<material file="gfx_sparkGreen_a.png" />
|
||||
|
||||
<!-- Amount of particles emitted per second -->
|
||||
<rate min="65"
|
||||
max="100" />
|
||||
|
||||
<!-- Minimal and maximal lifetime of a particle, in milliseconds. -->
|
||||
<lifetime min="2700"
|
||||
max="2700" />
|
||||
|
||||
<!-- Size of the particles -->
|
||||
<size min="0.5"
|
||||
max="0.8"
|
||||
x-increase-factor="1.1"
|
||||
y-increase-factor="1.3"
|
||||
/>
|
||||
|
||||
<color min="255 255 255"
|
||||
max="255 0 0" />
|
||||
|
||||
<!-- How much time in milliseconds before the particle is fully faded out -->
|
||||
<fadeout time="50" />
|
||||
|
||||
</particles>
|
@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<stkgui>
|
||||
<div x="0" y="0" width="100%" height="100%" layout="vertical-row" >
|
||||
<header text_align="center" width="80%" align="center" I18N="In the server creation screen" text="Server Creation"/>
|
||||
<header id="title" text_align="center" width="80%" align="center" I18N="In the server creation 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%">
|
||||
|
@ -1,46 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<stkgui>
|
||||
<div x="0" y="0" width="100%" height="100%" layout="vertical-row" >
|
||||
|
||||
<header text_align="center" width="80%" align="center" I18N="In the online multiplayer screen" text="Online Multiplayer"/>
|
||||
<spacer height="15" width="10"/>
|
||||
<box proportion="4" width="90%" layout="vertical-row" align="center">
|
||||
<div x="2%" y="2%" width="96%" height="96%" layout="vertical-row" id="outer_box" >
|
||||
<!-- TODO: Here will come some information.. or statistics.. or whatever. Yet to be filled in! It will change depending on state. And I'd also like a close button at the right top. -->
|
||||
<label I18N="In the online multiplayer screen" proportion="4"
|
||||
word_wrap="true" text="" align="center"/>
|
||||
</div>
|
||||
</box>
|
||||
|
||||
<buttonbar id="menu_toprow" proportion="3" width="90%" align="center">
|
||||
<icon-button id="quick_play" width="128" height="128"
|
||||
icon="gui/online/menu_quick_play.png" focus_icon="gui/online/menu_quick_play_hover.png"
|
||||
I18N="In the online multiplayer screen" text="Quick Play"/>
|
||||
<icon-button id="find_server" width="128" height="128"
|
||||
icon="gui/online/menu_find_server.png" focus_icon="gui/online/menu_find_server_hover.png"
|
||||
I18N="In the online multiplayer screen" text="Find Server"/>
|
||||
<icon-button id="create_server" width="128" height="128"
|
||||
icon="gui/online/menu_create_server.png" focus_icon="gui/online/menu_create_server_hover.png"
|
||||
I18N="In the online multiplayer screen" text="Create Server"/>
|
||||
</buttonbar>
|
||||
|
||||
<spacer width="10" height="7%"/>
|
||||
|
||||
<bottombar x="2%" width="96%" height="10%" layout="horizontal-row">
|
||||
<label text_align="left" align="center" height="100%" id="online_status" proportion="1" text=""/>
|
||||
|
||||
<spacer width="10" height="10" />
|
||||
|
||||
<buttonbar id="menu_bottomrow" x="0" y="0" width="12%" height="100%" align="center">
|
||||
<icon-button id="profile" width="64" height="64" icon="gui/green_check.png" extend_label="50"
|
||||
I18N="In the online multiplayer screen" text="Profile" label_location="hover"/>
|
||||
<icon-button id="sign_out" width="64" height="64" icon="gui/main_quit.png" extend_label="70"
|
||||
I18N="In the online multiplayer screen" text="Log Out" label_location="hover"/>
|
||||
</buttonbar>
|
||||
|
||||
</bottombar>
|
||||
|
||||
</div>
|
||||
|
||||
<icon-button id="back" x="0" y="0" height="8%" icon="gui/back.png"/>
|
||||
</stkgui>
|
63
data/gui/online/online_screen.stkgui
Normal file
63
data/gui/online/online_screen.stkgui
Normal file
@ -0,0 +1,63 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<stkgui>
|
||||
<div x="0" y="0" width="100%" height="fit" layout="vertical-row">
|
||||
<button id="user-id" width="20%" height="fit" align="right"/>
|
||||
</div>
|
||||
|
||||
<div x="2%" y="2%" width="96%" height="96%" layout="vertical-row" >
|
||||
|
||||
<header text_align="center" width="80%" align="center" I18N="In the online multiplayer screen" text="Online Multiplayer"/>
|
||||
|
||||
<spacer height="5%" width="25"/>
|
||||
<box width="100%" height="38%" padding="10" layout="vertical-row">
|
||||
<bright width="100%" text="Local Networking" align="center" text_align="left" />
|
||||
|
||||
<buttonbar id="lan" proportion="2" width="90%" align="center">
|
||||
<icon-button id="find_lan_server" width="128" height="128"
|
||||
icon="gui/online/menu_find_server.png" focus_icon="gui/online/menu_find_server_hover.png"
|
||||
I18N="In the online multiplayer screen" text="Find Server"/>
|
||||
<icon-button id="create_lan_server" width="128" height="128"
|
||||
icon="gui/online/menu_create_server.png" focus_icon="gui/online/menu_create_server_hover.png"
|
||||
I18N="In the online multiplayer screen" text="Create Server"/>
|
||||
<icon-button id="manage_user" width="128" height="128"
|
||||
icon="gui/options_players.png"
|
||||
I18N="In the online multiplayer screen" text="Users"/>
|
||||
</buttonbar>
|
||||
</box>
|
||||
|
||||
<spacer height="5%" width="25"/>
|
||||
|
||||
<box width="100%" height="38%" padding="10" layout="vertical-row">
|
||||
<bright width="100%" text="Global Networking" align="center" text_align="left" />
|
||||
|
||||
<buttonbar id="menu_top_row" proportion="2" width="90%" align="center">
|
||||
<icon-button id="find_wan_server" width="128" height="128"
|
||||
icon="gui/online/menu_find_server.png" focus_icon="gui/online/menu_find_server_hover.png"
|
||||
I18N="In the online multiplayer screen" text="Find Server"/>
|
||||
<icon-button id="create_wan_server" width="128" height="128"
|
||||
icon="gui/online/menu_create_server.png" focus_icon="gui/online/menu_create_server_hover.png"
|
||||
I18N="In the online multiplayer screen" text="Create Server"/>
|
||||
<icon-button id="quick_wan_play" width="128" height="128"
|
||||
icon="gui/online/menu_quick_play.png" focus_icon="gui/online/menu_quick_play_hover.png"
|
||||
I18N="In the online multiplayer screen" text="Quick Play"/>
|
||||
</buttonbar>
|
||||
</box>
|
||||
|
||||
<bottombar x="2%" width="96%" height="10%" layout="horizontal-row">
|
||||
<label text_align="left" align="center" height="100%" id="online_status" proportion="1" text=""/>
|
||||
|
||||
<spacer width="10" height="10" />
|
||||
|
||||
<buttonbar id="menu_bottomrow" x="0" y="0" width="12%" height="100%" align="center">
|
||||
<icon-button id="profile" width="64" height="64" icon="gui/green_check.png" extend_label="50"
|
||||
I18N="In the online multiplayer screen" text="Profile" label_location="hover"/>
|
||||
<icon-button id="sign_out" width="64" height="64" icon="gui/main_quit.png" extend_label="70"
|
||||
I18N="In the online multiplayer screen" text="Log Out" label_location="hover"/>
|
||||
</buttonbar>
|
||||
|
||||
</bottombar>
|
||||
|
||||
</div>
|
||||
|
||||
<icon-button id="back" x="0" y="0" height="8%" icon="gui/back.png"/>
|
||||
</stkgui>
|
@ -11,8 +11,8 @@ msgstr ""
|
||||
"Project-Id-Version: SuperTuxKart\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2015-09-26 00:20+1000\n"
|
||||
"PO-Revision-Date: 2015-09-26 09:35+0000\n"
|
||||
"Last-Translator: Auria <auria.mg@gmail.com>\n"
|
||||
"PO-Revision-Date: 2015-10-04 03:25+0000\n"
|
||||
"Last-Translator: صفا الفليج <safaalfulaij@hotmail.com>\n"
|
||||
"Language-Team: Arabic (http://www.transifex.com/supertuxkart/supertuxkart/language/ar/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
@ -353,7 +353,7 @@ msgstr "ضغط النّقوش"
|
||||
#. I18N: ./data/gui/custom_video_settings.stkgui
|
||||
#. I18N: Video settings
|
||||
msgid "Use high definition textures"
|
||||
msgstr ""
|
||||
msgstr "استخدم نقوشًا عالية الوضوح"
|
||||
|
||||
#. I18N: ./data/gui/custom_video_settings.stkgui
|
||||
#. I18N: Video settings
|
||||
@ -622,7 +622,7 @@ msgstr "* ربط المفتاح الحاليّ يمكن رؤيته/تغييره
|
||||
#. I18N: ./data/gui/help2.stkgui
|
||||
#. I18N: In the help menu
|
||||
msgid "To help you win, there are some powerups you can collect:"
|
||||
msgstr ""
|
||||
msgstr "لمساعدتك على الفوز، ثمّة بعض التّحسينات التي يمكنك التقاطها:"
|
||||
|
||||
#. I18N: ./data/gui/help2.stkgui
|
||||
msgid ""
|
||||
@ -1840,13 +1840,13 @@ msgstr "[لاشيء]"
|
||||
#: src/input/binding.cpp:114
|
||||
msgctxt "input_key"
|
||||
msgid "Left Mouse Button"
|
||||
msgstr ""
|
||||
msgstr "زرّ الفأرة الأيسر"
|
||||
|
||||
#. I18N: input configuration screen: mouse button
|
||||
#: src/input/binding.cpp:116
|
||||
msgctxt "input_key"
|
||||
msgid "Right Mouse Button"
|
||||
msgstr ""
|
||||
msgstr "زرّ الفأرة الأيمن"
|
||||
|
||||
#. I18N: input configuration screen: keyboard key
|
||||
#: src/input/binding.cpp:118
|
||||
@ -1858,7 +1858,7 @@ msgstr ""
|
||||
#: src/input/binding.cpp:120
|
||||
msgctxt "input_key"
|
||||
msgid "Middle Mouse Button"
|
||||
msgstr ""
|
||||
msgstr "زرّ الفأرة الأوسط"
|
||||
|
||||
#. I18N: input configuration screen: mouse button
|
||||
#: src/input/binding.cpp:122
|
||||
@ -2099,61 +2099,61 @@ msgstr ""
|
||||
#: src/input/binding.cpp:237
|
||||
msgctxt "input_key"
|
||||
msgid "Numpad 0"
|
||||
msgstr ""
|
||||
msgstr "لوحة الأرقام 0"
|
||||
|
||||
#. I18N: input configuration screen: keyboard key
|
||||
#: src/input/binding.cpp:239
|
||||
msgctxt "input_key"
|
||||
msgid "Numpad 1"
|
||||
msgstr ""
|
||||
msgstr "لوحة الأرقام 1"
|
||||
|
||||
#. I18N: input configuration screen: keyboard key
|
||||
#: src/input/binding.cpp:241
|
||||
msgctxt "input_key"
|
||||
msgid "Numpad 2"
|
||||
msgstr ""
|
||||
msgstr "لوحة الأرقام 2"
|
||||
|
||||
#. I18N: input configuration screen: keyboard key
|
||||
#: src/input/binding.cpp:243
|
||||
msgctxt "input_key"
|
||||
msgid "Numpad 3"
|
||||
msgstr ""
|
||||
msgstr "لوحة الأرقام 3"
|
||||
|
||||
#. I18N: input configuration screen: keyboard key
|
||||
#: src/input/binding.cpp:245
|
||||
msgctxt "input_key"
|
||||
msgid "Numpad 4"
|
||||
msgstr ""
|
||||
msgstr "لوحة الأرقام 4"
|
||||
|
||||
#. I18N: input configuration screen: keyboard key
|
||||
#: src/input/binding.cpp:247
|
||||
msgctxt "input_key"
|
||||
msgid "Numpad 5"
|
||||
msgstr ""
|
||||
msgstr "لوحة الأرقام 5"
|
||||
|
||||
#. I18N: input configuration screen: keyboard key
|
||||
#: src/input/binding.cpp:249
|
||||
msgctxt "input_key"
|
||||
msgid "Numpad 6"
|
||||
msgstr ""
|
||||
msgstr "لوحة الأرقام 6"
|
||||
|
||||
#. I18N: input configuration screen: keyboard key
|
||||
#: src/input/binding.cpp:251
|
||||
msgctxt "input_key"
|
||||
msgid "Numpad 7"
|
||||
msgstr ""
|
||||
msgstr "لوحة الأرقام 7"
|
||||
|
||||
#. I18N: input configuration screen: keyboard key
|
||||
#: src/input/binding.cpp:253
|
||||
msgctxt "input_key"
|
||||
msgid "Numpad 8"
|
||||
msgstr ""
|
||||
msgstr "لوحة الأرقام 8"
|
||||
|
||||
#. I18N: input configuration screen: keyboard key
|
||||
#: src/input/binding.cpp:255
|
||||
msgctxt "input_key"
|
||||
msgid "Numpad 9"
|
||||
msgstr ""
|
||||
msgstr "لوحة الأرقام 9"
|
||||
|
||||
#. I18N: input configuration screen: keyboard key
|
||||
#: src/input/binding.cpp:259
|
||||
@ -2442,7 +2442,7 @@ msgstr ""
|
||||
#: src/input/input_manager.cpp:751
|
||||
#, c-format
|
||||
msgid "Ignoring '%s'. You needed to join earlier to play!"
|
||||
msgstr ""
|
||||
msgstr "سأتجاهل '%s'. كان عليك الانضمام قبل الآن للعب!"
|
||||
|
||||
#: src/input/input_manager.cpp:781
|
||||
msgid "Only the Game Master may act at this point!"
|
||||
@ -2513,7 +2513,7 @@ msgstr "إصدارة مشغّلك قديمة جدًّا. فضلًا ثبّت أ
|
||||
msgid ""
|
||||
"Your OpenGL version appears to be too old. Please verify if an update for "
|
||||
"your video driver is available. SuperTuxKart requires OpenGL 3.1 or better."
|
||||
msgstr ""
|
||||
msgstr "إصدارتك من أوبنجيإل تبدو قديمة جدًّا. فضلًا تحقّق من وجود تحديث لمشغّل الفيديوهات لديك. تطلب سوبرتكسكارت أوبنجيإل 3.1 أو أعلى."
|
||||
|
||||
#: src/modes/easter_egg_hunt.cpp:202
|
||||
#, c-format
|
||||
@ -2844,12 +2844,12 @@ msgstr "يتحقّق من المعلومات"
|
||||
#, c-format
|
||||
msgid "Confirm resolution within %i second"
|
||||
msgid_plural "Confirm resolution within %i seconds"
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
msgstr[2] ""
|
||||
msgstr[3] ""
|
||||
msgstr[4] ""
|
||||
msgstr[5] ""
|
||||
msgstr[0] "أكّد الميز حالًا"
|
||||
msgstr[1] "أكّد الميز خلال ثانية واحدة"
|
||||
msgstr[2] "أكّد الميز خلال ثانيتين"
|
||||
msgstr[3] "أكّد الميز خلال %i ثوان"
|
||||
msgstr[4] "أكّد الميز خلال %i ثانية"
|
||||
msgstr[5] "أكّد الميز خلال %i ثانية"
|
||||
|
||||
#. I18N: in the graphical options tooltip;
|
||||
#. indicates a graphical feature is disabled
|
||||
|
@ -11,8 +11,8 @@ msgstr ""
|
||||
"Project-Id-Version: SuperTuxKart\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2015-09-26 00:20+1000\n"
|
||||
"PO-Revision-Date: 2015-09-26 09:35+0000\n"
|
||||
"Last-Translator: Auria <auria.mg@gmail.com>\n"
|
||||
"PO-Revision-Date: 2015-10-11 10:29+0000\n"
|
||||
"Last-Translator: Alan Monfort <alan.monfort@free.fr>\n"
|
||||
"Language-Team: Breton (http://www.transifex.com/supertuxkart/supertuxkart/language/br/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
@ -1043,7 +1043,7 @@ msgstr "Arventennoù ar gont"
|
||||
#. I18N: ./data/gui/online/profile_settings.stkgui
|
||||
#. I18N: In the online account settings screen
|
||||
msgid "Password:"
|
||||
msgstr ""
|
||||
msgstr "Ger-tremen :"
|
||||
|
||||
#. I18N: ./data/gui/online/profile_settings.stkgui
|
||||
msgid "Change"
|
||||
@ -1840,13 +1840,13 @@ msgstr "[hini ebet]"
|
||||
#: src/input/binding.cpp:114
|
||||
msgctxt "input_key"
|
||||
msgid "Left Mouse Button"
|
||||
msgstr ""
|
||||
msgstr "Afell gleiz al logodenn"
|
||||
|
||||
#. I18N: input configuration screen: mouse button
|
||||
#: src/input/binding.cpp:116
|
||||
msgctxt "input_key"
|
||||
msgid "Right Mouse Button"
|
||||
msgstr ""
|
||||
msgstr "Afell dehou al logodenn"
|
||||
|
||||
#. I18N: input configuration screen: keyboard key
|
||||
#: src/input/binding.cpp:118
|
||||
@ -1858,19 +1858,19 @@ msgstr "Nullañ"
|
||||
#: src/input/binding.cpp:120
|
||||
msgctxt "input_key"
|
||||
msgid "Middle Mouse Button"
|
||||
msgstr ""
|
||||
msgstr "Afell greiz al logodenn"
|
||||
|
||||
#. I18N: input configuration screen: mouse button
|
||||
#: src/input/binding.cpp:122
|
||||
msgctxt "input_key"
|
||||
msgid "X1 Mouse Button"
|
||||
msgstr ""
|
||||
msgstr "Afell X1 al logodenn"
|
||||
|
||||
#. I18N: input configuration screen: mouse button
|
||||
#: src/input/binding.cpp:124
|
||||
msgctxt "input_key"
|
||||
msgid "X2 Mouse Button"
|
||||
msgstr ""
|
||||
msgstr "Afell X2 al logodenn"
|
||||
|
||||
#. I18N: input configuration screen: keyboard key
|
||||
#: src/input/binding.cpp:126
|
||||
@ -1882,7 +1882,7 @@ msgstr "Kilesaouiñ"
|
||||
#: src/input/binding.cpp:128
|
||||
msgctxt "input_key"
|
||||
msgid "Tab"
|
||||
msgstr ""
|
||||
msgstr "Taolennata"
|
||||
|
||||
#. I18N: input configuration screen: keyboard key
|
||||
#: src/input/binding.cpp:130
|
||||
@ -1894,13 +1894,13 @@ msgstr "Skarzhañ"
|
||||
#: src/input/binding.cpp:132
|
||||
msgctxt "input_key"
|
||||
msgid "Return"
|
||||
msgstr ""
|
||||
msgstr "Distreiñ"
|
||||
|
||||
#. I18N: input configuration screen: keyboard key
|
||||
#: src/input/binding.cpp:134
|
||||
msgctxt "input_key"
|
||||
msgid "Shift"
|
||||
msgstr ""
|
||||
msgstr "Pennlizherenn"
|
||||
|
||||
#. I18N: input configuration screen: keyboard key
|
||||
#: src/input/binding.cpp:136
|
||||
@ -1912,13 +1912,13 @@ msgstr "Reolerezh"
|
||||
#: src/input/binding.cpp:138
|
||||
msgctxt "input_key"
|
||||
msgid "Alt/Menu"
|
||||
msgstr ""
|
||||
msgstr "Alt/Lañser"
|
||||
|
||||
#. I18N: input configuration screen: keyboard key
|
||||
#: src/input/binding.cpp:140
|
||||
msgctxt "input_key"
|
||||
msgid "Pause"
|
||||
msgstr ""
|
||||
msgstr "Ehan"
|
||||
|
||||
#. I18N: input configuration screen: keyboard key
|
||||
#: src/input/binding.cpp:142
|
||||
@ -1930,26 +1930,26 @@ msgstr "Prennañ ar pennlizherennoù"
|
||||
#: src/input/binding.cpp:144
|
||||
msgctxt "input_key"
|
||||
msgid "Kana"
|
||||
msgstr ""
|
||||
msgstr "Kana"
|
||||
|
||||
#. I18N: input configuration screen: keyboard key
|
||||
#: src/input/binding.cpp:146
|
||||
msgctxt "input_key"
|
||||
msgid "Junja"
|
||||
msgstr ""
|
||||
msgstr "Junja"
|
||||
|
||||
#. I18N: input configuration screen: keyboard key
|
||||
#. I18N: input configuration screen: keyboard key
|
||||
#: src/input/binding.cpp:149
|
||||
msgctxt "input_key"
|
||||
msgid "Final"
|
||||
msgstr ""
|
||||
msgstr "Diwezh"
|
||||
|
||||
#. I18N: input configuration screen: keyboard key
|
||||
#: src/input/binding.cpp:151
|
||||
msgctxt "input_key"
|
||||
msgid "Escape"
|
||||
msgstr ""
|
||||
msgstr "Achap"
|
||||
|
||||
#. I18N: input configuration screen: keyboard key
|
||||
#: src/input/binding.cpp:153
|
||||
@ -2057,7 +2057,7 @@ msgstr "Moullañ ar skramm"
|
||||
#: src/input/binding.cpp:187
|
||||
msgctxt "input_key"
|
||||
msgid "Insert"
|
||||
msgstr ""
|
||||
msgstr "Enlakaat"
|
||||
|
||||
#. I18N: input configuration screen: keyboard key
|
||||
#: src/input/binding.cpp:189
|
||||
@ -2093,73 +2093,73 @@ msgstr "Arloadoù"
|
||||
#: src/input/binding.cpp:235
|
||||
msgctxt "input_key"
|
||||
msgid "Sleep"
|
||||
msgstr ""
|
||||
msgstr "Kousket"
|
||||
|
||||
#. I18N: input configuration screen: keyboard key
|
||||
#: src/input/binding.cpp:237
|
||||
msgctxt "input_key"
|
||||
msgid "Numpad 0"
|
||||
msgstr ""
|
||||
msgstr "Nivdamer 0"
|
||||
|
||||
#. I18N: input configuration screen: keyboard key
|
||||
#: src/input/binding.cpp:239
|
||||
msgctxt "input_key"
|
||||
msgid "Numpad 1"
|
||||
msgstr ""
|
||||
msgstr "Nivdamer 1"
|
||||
|
||||
#. I18N: input configuration screen: keyboard key
|
||||
#: src/input/binding.cpp:241
|
||||
msgctxt "input_key"
|
||||
msgid "Numpad 2"
|
||||
msgstr ""
|
||||
msgstr "Nivdamer 2"
|
||||
|
||||
#. I18N: input configuration screen: keyboard key
|
||||
#: src/input/binding.cpp:243
|
||||
msgctxt "input_key"
|
||||
msgid "Numpad 3"
|
||||
msgstr ""
|
||||
msgstr "Nivdamer 3"
|
||||
|
||||
#. I18N: input configuration screen: keyboard key
|
||||
#: src/input/binding.cpp:245
|
||||
msgctxt "input_key"
|
||||
msgid "Numpad 4"
|
||||
msgstr ""
|
||||
msgstr "Nivdamer 4"
|
||||
|
||||
#. I18N: input configuration screen: keyboard key
|
||||
#: src/input/binding.cpp:247
|
||||
msgctxt "input_key"
|
||||
msgid "Numpad 5"
|
||||
msgstr ""
|
||||
msgstr "Nivdamer 5"
|
||||
|
||||
#. I18N: input configuration screen: keyboard key
|
||||
#: src/input/binding.cpp:249
|
||||
msgctxt "input_key"
|
||||
msgid "Numpad 6"
|
||||
msgstr ""
|
||||
msgstr "Nivdamer 6"
|
||||
|
||||
#. I18N: input configuration screen: keyboard key
|
||||
#: src/input/binding.cpp:251
|
||||
msgctxt "input_key"
|
||||
msgid "Numpad 7"
|
||||
msgstr ""
|
||||
msgstr "Nivdamer 7"
|
||||
|
||||
#. I18N: input configuration screen: keyboard key
|
||||
#: src/input/binding.cpp:253
|
||||
msgctxt "input_key"
|
||||
msgid "Numpad 8"
|
||||
msgstr ""
|
||||
msgstr "Nivdamer 8"
|
||||
|
||||
#. I18N: input configuration screen: keyboard key
|
||||
#: src/input/binding.cpp:255
|
||||
msgctxt "input_key"
|
||||
msgid "Numpad 9"
|
||||
msgstr ""
|
||||
msgstr "Nivdamer 9"
|
||||
|
||||
#. I18N: input configuration screen: keyboard key
|
||||
#: src/input/binding.cpp:259
|
||||
msgctxt "input_key"
|
||||
msgid "Separator"
|
||||
msgstr ""
|
||||
msgstr "Dispartier"
|
||||
|
||||
#. I18N: input configuration screen: keyboard key
|
||||
#: src/input/binding.cpp:261
|
||||
@ -2183,55 +2183,55 @@ msgstr "/ (Rannañ)"
|
||||
#: src/input/binding.cpp:291
|
||||
msgctxt "input_key"
|
||||
msgid "Num Lock"
|
||||
msgstr ""
|
||||
msgstr "Prennañ an niverennoù"
|
||||
|
||||
#. I18N: input configuration screen: keyboard key
|
||||
#: src/input/binding.cpp:293
|
||||
msgctxt "input_key"
|
||||
msgid "Scroll Lock"
|
||||
msgstr ""
|
||||
msgstr "Prennañ an dibuniñ"
|
||||
|
||||
#. I18N: input configuration screen: keyboard key
|
||||
#: src/input/binding.cpp:295
|
||||
msgctxt "input_key"
|
||||
msgid "Left Shift"
|
||||
msgstr ""
|
||||
msgstr "Pennlizherenn a-gleiz"
|
||||
|
||||
#. I18N: input configuration screen: keyboard key
|
||||
#: src/input/binding.cpp:297
|
||||
msgctxt "input_key"
|
||||
msgid "Right Shift"
|
||||
msgstr ""
|
||||
msgstr "Pennlizherenn a-zehou"
|
||||
|
||||
#. I18N: input configuration screen: keyboard key
|
||||
#: src/input/binding.cpp:299
|
||||
msgctxt "input_key"
|
||||
msgid "Left Control"
|
||||
msgstr ""
|
||||
msgstr "Reolerezh a-gleiz"
|
||||
|
||||
#. I18N: input configuration screen: keyboard key
|
||||
#: src/input/binding.cpp:301
|
||||
msgctxt "input_key"
|
||||
msgid "Right Control"
|
||||
msgstr ""
|
||||
msgstr "Reolerezh a-zehou"
|
||||
|
||||
#. I18N: input configuration screen: keyboard key
|
||||
#: src/input/binding.cpp:303
|
||||
msgctxt "input_key"
|
||||
msgid "Left Menu"
|
||||
msgstr ""
|
||||
msgstr "Lañser a-gleiz"
|
||||
|
||||
#. I18N: input configuration screen: keyboard key
|
||||
#: src/input/binding.cpp:305
|
||||
msgctxt "input_key"
|
||||
msgid "Right Menu"
|
||||
msgstr ""
|
||||
msgstr "Lañser a-zehou"
|
||||
|
||||
#. I18N: input configuration screen: keyboard key
|
||||
#: src/input/binding.cpp:311
|
||||
msgctxt "input_key"
|
||||
msgid "Attn"
|
||||
msgstr ""
|
||||
msgstr "Evezh"
|
||||
|
||||
#. I18N: input configuration screen: keyboard key
|
||||
#: src/input/binding.cpp:313
|
||||
|
@ -12,8 +12,8 @@ msgstr ""
|
||||
"Project-Id-Version: SuperTuxKart\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2015-09-26 00:20+1000\n"
|
||||
"PO-Revision-Date: 2015-09-26 09:36+0000\n"
|
||||
"Last-Translator: Auria <auria.mg@gmail.com>\n"
|
||||
"PO-Revision-Date: 2015-10-14 12:38+0000\n"
|
||||
"Last-Translator: ToMáš Marný\n"
|
||||
"Language-Team: Czech (http://www.transifex.com/supertuxkart/supertuxkart/language/cs/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
@ -2923,7 +2923,7 @@ msgid ""
|
||||
"the box below, you are confirming that you understand these terms. If you "
|
||||
"have any questions or comments regarding these terms, one of the members of "
|
||||
"the development team would gladly assist you."
|
||||
msgstr ""
|
||||
msgstr "Přečtěte si prosím podmínky použití pro SuperTuxKart na adrese '%s'. Před registrací účtu pro STK musíte s těmito podmínkami souhlasit. Zaškrtnutím políčka níže potvrzujete, že jste tyto podmínky pochopili. Máte-li jakékoli dotazy nebo připomínky týkající se těchto podmínek, některý z členů vývojového týmu vám rád pomůže."
|
||||
|
||||
#: src/states_screens/dialogs/select_challenge.cpp:53
|
||||
#, c-format
|
||||
|
@ -15,8 +15,8 @@ msgstr ""
|
||||
"Project-Id-Version: SuperTuxKart\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2015-09-26 00:20+1000\n"
|
||||
"PO-Revision-Date: 2015-09-26 09:36+0000\n"
|
||||
"Last-Translator: Auria <auria.mg@gmail.com>\n"
|
||||
"PO-Revision-Date: 2015-09-28 19:07+0000\n"
|
||||
"Last-Translator: Wuzzy <almikes@aol.com>\n"
|
||||
"Language-Team: German (http://www.transifex.com/supertuxkart/supertuxkart/language/de/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
@ -2922,7 +2922,7 @@ msgid ""
|
||||
"the box below, you are confirming that you understand these terms. If you "
|
||||
"have any questions or comments regarding these terms, one of the members of "
|
||||
"the development team would gladly assist you."
|
||||
msgstr ""
|
||||
msgstr "Bitte lies die Geschäftsbedingungen für SuperTuxKart auf „%s“. Du musst diesen Bedingungen zustimmen, um ein Benutzerkonto für STK anlegen zu können. Wenn du im untenstehenden Kästchen ein Häkchen setzt, bestätigst du damit, dass du diese Bedingungen verstehst. Falls du Fragen oder Kommentare bezüglich dieser Bedingungen hast, wird einer der Mitglieder des Entwicklungsteams dir gerne weiterhelfen."
|
||||
|
||||
#: src/states_screens/dialogs/select_challenge.cpp:53
|
||||
#, c-format
|
||||
|
@ -11,8 +11,8 @@ msgstr ""
|
||||
"Project-Id-Version: SuperTuxKart\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2015-09-26 00:20+1000\n"
|
||||
"PO-Revision-Date: 2015-09-26 09:36+0000\n"
|
||||
"Last-Translator: Auria <auria.mg@gmail.com>\n"
|
||||
"PO-Revision-Date: 2015-09-28 08:27+0000\n"
|
||||
"Last-Translator: GunChleoc\n"
|
||||
"Language-Team: Gaelic, Scottish (http://www.transifex.com/supertuxkart/supertuxkart/language/gd/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
@ -2926,7 +2926,7 @@ msgid ""
|
||||
"the box below, you are confirming that you understand these terms. If you "
|
||||
"have any questions or comments regarding these terms, one of the members of "
|
||||
"the development team would gladly assist you."
|
||||
msgstr ""
|
||||
msgstr "Feuch an leugh thu na teirmichean is cumhaichean airson SuperTuxKart air “%s”. Feumaidh tu aontachadh ris na teirmichean sin mus clàraich thu cunntas airson STK. Nuair a chuireas tu cromag sa bhogsa gu h-ìosal, dearbhaichidh tu gu bheil thu a’ tuigsinn nan teirmichean sin. Ma tha ceist no beachd sam bith agad mu na teirmichean sin, bidh ball dhen sgioba leasachaidh toilichte do chuideachadh."
|
||||
|
||||
#: src/states_screens/dialogs/select_challenge.cpp:53
|
||||
#, c-format
|
||||
|
@ -9,7 +9,7 @@ msgstr ""
|
||||
"Project-Id-Version: SuperTuxKart\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2015-09-26 00:20+1000\n"
|
||||
"PO-Revision-Date: 2015-09-27 19:23+0000\n"
|
||||
"PO-Revision-Date: 2015-10-03 11:54+0000\n"
|
||||
"Last-Translator: Karl Ove Hufthammer <karl@huftis.org>\n"
|
||||
"Language-Team: Norwegian Nynorsk (http://www.transifex.com/supertuxkart/supertuxkart/language/nn/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
@ -1140,7 +1140,7 @@ msgstr "Bruksvilkår"
|
||||
#. I18N: ./data/gui/online/registration_terms.stkgui
|
||||
#. I18N: In the registration dialog
|
||||
msgid "I agree to the above terms and am 13 years or older. "
|
||||
msgstr "I godtek vilkåra over, og er minst 13 år gammal. "
|
||||
msgstr "Eg godtek vilkåra over, og er minst 13 år gammal. "
|
||||
|
||||
#. I18N: ./data/gui/online/registration_terms.stkgui
|
||||
#. I18N: In the registration dialog
|
||||
|
3792
data/po/oc.po
Normal file
3792
data/po/oc.po
Normal file
File diff suppressed because it is too large
Load Diff
@ -10,7 +10,7 @@ msgstr ""
|
||||
"Project-Id-Version: SuperTuxKart\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2015-09-26 00:20+1000\n"
|
||||
"PO-Revision-Date: 2015-09-26 13:43+0000\n"
|
||||
"PO-Revision-Date: 2015-10-07 17:13+0000\n"
|
||||
"Last-Translator: Dawid Gan <deveee@gmail.com>\n"
|
||||
"Language-Team: Polish (http://www.transifex.com/supertuxkart/supertuxkart/language/pl/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
@ -65,7 +65,7 @@ msgstr "Złoty Kierowca"
|
||||
|
||||
#. I18N: ./data/achievements.xml
|
||||
msgid "Win against at least 3 opponents in all single player modes."
|
||||
msgstr "Wygraj z co najmniej 3 ptrzeciwnikami w każdym jednoosobowym trybie gry."
|
||||
msgstr "Wygraj z co najmniej 3 przeciwnikami w każdym jednoosobowym trybie gry."
|
||||
|
||||
#. I18N: ./data/achievements.xml
|
||||
msgid "Powerup Love"
|
||||
|
@ -11,8 +11,8 @@ msgstr ""
|
||||
"Project-Id-Version: SuperTuxKart\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2015-09-26 00:20+1000\n"
|
||||
"PO-Revision-Date: 2015-09-26 09:35+0000\n"
|
||||
"Last-Translator: Auria <auria.mg@gmail.com>\n"
|
||||
"PO-Revision-Date: 2015-10-06 00:02+0000\n"
|
||||
"Last-Translator: MiroslavR <miroslavr256@gmail.com>\n"
|
||||
"Language-Team: Slovak (http://www.transifex.com/supertuxkart/supertuxkart/language/sk/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
@ -661,7 +661,7 @@ msgstr "Menič - na krátku chvíľu sa darčekové škatule premenia na banány
|
||||
msgid ""
|
||||
"Basket Ball - bounces after the leader, and might squash and slow down karts"
|
||||
" down on the way."
|
||||
msgstr "Basketbalová lopta - skákaním prenasleduje motokáru na prvom mieste a môže rozpučiť a spomaliť aj iné motokáry stojace v jej ceste."
|
||||
msgstr "Basketbalová lopta - skákaním prenasleduje motokáru na prvom mieste, avšak môže rozpučiť a spomaliť aj iné motokáry stojace v jej ceste."
|
||||
|
||||
#. I18N: ./data/gui/help2.stkgui
|
||||
msgid "Swatter - will squash karts close by, slowing them down."
|
||||
@ -681,7 +681,7 @@ msgstr "Obyčajné preteky: Povoľujú sa všetky údery, tak sa chopte zbraní
|
||||
#. I18N: ./data/gui/help3.stkgui
|
||||
#. I18N: In the help menu
|
||||
msgid "Time Trial: Contains no powerups, so only your driving skills matter!"
|
||||
msgstr "Preteky na čas: neobsahuje žiadne bonusy, takže záleží len na vašich vodičských skúsenostiach!"
|
||||
msgstr "Preteky na čas: Neobsahuje žiadne bonusy, takže záleží len na vašich vodičských skúsenostiach!"
|
||||
|
||||
#. I18N: ./data/gui/help3.stkgui
|
||||
#. I18N: In the help menu
|
||||
@ -736,7 +736,7 @@ msgid ""
|
||||
"keyboard(s), however each player will need a different set of keys, and keep"
|
||||
" in mind that most keyboards are not appropriate for multiplayer gameplay "
|
||||
"because they do not support large number of keypresses."
|
||||
msgstr "Najprv budete potrebovať niekoľko vstupných zariadení (viac gamepadov alebo joystickov je najlepší spôsob, ako hrať s viacerými ľuďmi). Choďte do konfigurácie vstupov a nastavte gamepady. Je tiež možné hrať na klávesnici(ach), avšak každý hráč bude potrebovať iný súbor klávesov. Pamätajte si, že väčšina klávesníc nie je vhodná pre hru pre viacerých hráčov, pretože nepodporuje veľké množstvo stlačení klávesov."
|
||||
msgstr "Najprv budete potrebovať niekoľko vstupných zariadení (najlepším spôsobom, ako hrať s viacerými ľuďmi, je mať viacero gamepadov alebo joystickov). Prejdite na obrazovku konfigurácie vstupov a nastavte gamepady. Okrem toho možno hrať na klávesnici(ach), avšak každý hráč bude potrebovať iný súbor klávesov. Pamätajte si, že väčšina klávesníc nie je vhodná pre hru s viacerými hráčmi, pretože nepodporuje veľké množstvo stlačení klávesov."
|
||||
|
||||
#. I18N: ./data/gui/help4.stkgui
|
||||
#. I18N: In the help menu
|
||||
@ -747,7 +747,7 @@ msgid ""
|
||||
" the game. Each player can use their input device to select their kart. The "
|
||||
"game continues when everyone selected their kart. Note that the mouse may "
|
||||
"not be used for this operation."
|
||||
msgstr ""
|
||||
msgstr "Po nakonfigurovaní vstupných zariadení môžete začať hrať. V hlavnej ponuke vyberte ikonu pretekov pre viacerých hráčov. Keď príde na rad výber motokáry, každý hráč bude môcť vstúpiť do hry stlačením tlačidla/klávesu „útok“ na svojom gamepade alebo klávesnici. Každý hráč môže na výber motokáry použiť svoje vlastné vstupné zariadenie. Hra bude pokračovať, keď si všetci hráči vyberú motokáry. Všimnite si, že na vykonanie tejto činnosti nemožno použiť myš."
|
||||
|
||||
#. I18N: ./data/gui/karts.stkgui
|
||||
#. I18N: In the kart selection (player setup) screen
|
||||
@ -1852,7 +1852,7 @@ msgstr "Pravé tlačidlo myši"
|
||||
#: src/input/binding.cpp:118
|
||||
msgctxt "input_key"
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
msgstr "Cancel"
|
||||
|
||||
#. I18N: input configuration screen: mouse button
|
||||
#: src/input/binding.cpp:120
|
||||
@ -1888,7 +1888,7 @@ msgstr "Tab"
|
||||
#: src/input/binding.cpp:130
|
||||
msgctxt "input_key"
|
||||
msgid "Clear"
|
||||
msgstr ""
|
||||
msgstr "Clear"
|
||||
|
||||
#. I18N: input configuration screen: keyboard key
|
||||
#: src/input/binding.cpp:132
|
||||
@ -1943,7 +1943,7 @@ msgstr "Junja"
|
||||
#: src/input/binding.cpp:149
|
||||
msgctxt "input_key"
|
||||
msgid "Final"
|
||||
msgstr ""
|
||||
msgstr "Final"
|
||||
|
||||
#. I18N: input configuration screen: keyboard key
|
||||
#: src/input/binding.cpp:151
|
||||
@ -1967,7 +1967,7 @@ msgstr "Nonconvert"
|
||||
#: src/input/binding.cpp:157
|
||||
msgctxt "input_key"
|
||||
msgid "Accept"
|
||||
msgstr ""
|
||||
msgstr "Accept"
|
||||
|
||||
#. I18N: input configuration screen: keyboard key
|
||||
#: src/input/binding.cpp:159
|
||||
@ -2033,13 +2033,13 @@ msgstr "Šípka nadol"
|
||||
#: src/input/binding.cpp:179
|
||||
msgctxt "input_key"
|
||||
msgid "Select"
|
||||
msgstr ""
|
||||
msgstr "Select"
|
||||
|
||||
#. I18N: input configuration screen: keyboard key
|
||||
#: src/input/binding.cpp:181
|
||||
msgctxt "input_key"
|
||||
msgid "Print"
|
||||
msgstr ""
|
||||
msgstr "Print"
|
||||
|
||||
#. I18N: input configuration screen: keyboard key
|
||||
#: src/input/binding.cpp:183
|
||||
@ -2069,7 +2069,7 @@ msgstr "Delete"
|
||||
#: src/input/binding.cpp:191
|
||||
msgctxt "input_key"
|
||||
msgid "Help"
|
||||
msgstr ""
|
||||
msgstr "Help"
|
||||
|
||||
#. I18N: input configuration screen: keyboard key
|
||||
#: src/input/binding.cpp:229
|
||||
@ -2087,7 +2087,7 @@ msgstr "Pravé logo"
|
||||
#: src/input/binding.cpp:233
|
||||
msgctxt "input_key"
|
||||
msgid "Apps"
|
||||
msgstr ""
|
||||
msgstr "Apps"
|
||||
|
||||
#. I18N: input configuration screen: keyboard key
|
||||
#: src/input/binding.cpp:235
|
||||
@ -2159,7 +2159,7 @@ msgstr "9 na num. klávesnici"
|
||||
#: src/input/binding.cpp:259
|
||||
msgctxt "input_key"
|
||||
msgid "Separator"
|
||||
msgstr ""
|
||||
msgstr "Separator"
|
||||
|
||||
#. I18N: input configuration screen: keyboard key
|
||||
#: src/input/binding.cpp:261
|
||||
@ -2171,7 +2171,7 @@ msgstr "- (odčítanie)"
|
||||
#: src/input/binding.cpp:263
|
||||
msgctxt "input_key"
|
||||
msgid "Decimal"
|
||||
msgstr ""
|
||||
msgstr "Decimal"
|
||||
|
||||
#. I18N: input configuration screen: keyboard key
|
||||
#: src/input/binding.cpp:265
|
||||
@ -2231,7 +2231,7 @@ msgstr "Pravé menu"
|
||||
#: src/input/binding.cpp:311
|
||||
msgctxt "input_key"
|
||||
msgid "Attn"
|
||||
msgstr ""
|
||||
msgstr "Attn"
|
||||
|
||||
#. I18N: input configuration screen: keyboard key
|
||||
#: src/input/binding.cpp:313
|
||||
@ -2255,13 +2255,13 @@ msgstr "Ereof"
|
||||
#: src/input/binding.cpp:319
|
||||
msgctxt "input_key"
|
||||
msgid "Play"
|
||||
msgstr ""
|
||||
msgstr "Play"
|
||||
|
||||
#. I18N: input configuration screen: keyboard key
|
||||
#: src/input/binding.cpp:321
|
||||
msgctxt "input_key"
|
||||
msgid "Zoom"
|
||||
msgstr ""
|
||||
msgstr "Zoom"
|
||||
|
||||
#. I18N: input configuration screen: keyboard key
|
||||
#: src/input/binding.cpp:323
|
||||
@ -2713,7 +2713,7 @@ msgstr "štandardné"
|
||||
#: src/states_screens/kart_selection.cpp:1452
|
||||
#: src/states_screens/race_setup_screen.cpp:214
|
||||
msgid "Locked : solve active challenges to gain access to more!"
|
||||
msgstr "Uzamknuté: vyriešte aktívne úlohy, aby ste získali prístup k ďalším!"
|
||||
msgstr "Uzamknuté: ak chcete získať prístup k ďalším, vyriešte aktívne výzvy!"
|
||||
|
||||
#: src/states_screens/arenas_screen.cpp:277
|
||||
msgid "Random Arena"
|
||||
@ -2726,7 +2726,7 @@ msgstr ""
|
||||
|
||||
#: src/states_screens/create_server_screen.cpp:117
|
||||
msgid "Creating server"
|
||||
msgstr ""
|
||||
msgstr "Vytvára sa server"
|
||||
|
||||
#: src/states_screens/create_server_screen.cpp:132
|
||||
msgid "Name has to be between 4 and 30 characters long!"
|
||||
@ -2922,7 +2922,7 @@ msgid ""
|
||||
"the box below, you are confirming that you understand these terms. If you "
|
||||
"have any questions or comments regarding these terms, one of the members of "
|
||||
"the development team would gladly assist you."
|
||||
msgstr ""
|
||||
msgstr "Prečítajte si podmienky a požiadavky SuperTuxKart na stránke '%s'. Ak chcete zaregistrovať svoj účet, musíte súhlasiť s týmito podmienkami. Začiarknutím dolného políčka potvrdíte, že s týmito podmienkami súhlasíte. Ak máte akékoľvek otázky alebo pripomienky týkajúce sa týchto podmienok, môžete sa obrátiť na niektorého člena nášho tímu, ktorý vám s radosťou pomôže."
|
||||
|
||||
#: src/states_screens/dialogs/select_challenge.cpp:53
|
||||
#, c-format
|
||||
@ -2954,7 +2954,7 @@ msgstr ""
|
||||
|
||||
#: src/states_screens/dialogs/server_info_dialog.cpp:155
|
||||
msgid "Joining server"
|
||||
msgstr ""
|
||||
msgstr "Pripája sa na server"
|
||||
|
||||
#: src/states_screens/dialogs/user_info_dialog.cpp:56
|
||||
msgid "Cancel Request"
|
||||
@ -3206,15 +3206,15 @@ msgstr "Offline"
|
||||
#: src/states_screens/online_screen.cpp:139
|
||||
#, c-format
|
||||
msgid "Logged in as: %s."
|
||||
msgstr ""
|
||||
msgstr "Ste prihlásený/-á ako: %s."
|
||||
|
||||
#: src/states_screens/online_screen.cpp:155
|
||||
msgid "Logging in"
|
||||
msgstr ""
|
||||
msgstr "Prihlasuje sa"
|
||||
|
||||
#: src/states_screens/online_screen.cpp:160
|
||||
msgid "Logging out"
|
||||
msgstr ""
|
||||
msgstr "Odhlasuje sa"
|
||||
|
||||
#: src/states_screens/online_user_search.cpp:208
|
||||
#: src/states_screens/online_user_search.cpp:288
|
||||
@ -3677,7 +3677,7 @@ msgstr "Uzamknuté!"
|
||||
|
||||
#: src/states_screens/tracks_screen.cpp:285
|
||||
msgid "Locked: solve active challenges to gain access to more!"
|
||||
msgstr ""
|
||||
msgstr "Uzamknuté: ak chcete získať prístup k ďalším, vyriešte aktívne výzvy!"
|
||||
|
||||
#. I18N: when showing who is the author of track '%s'
|
||||
#. I18N: (place %s where the name of the author should appear)
|
||||
|
@ -10,8 +10,8 @@ msgstr ""
|
||||
"Project-Id-Version: SuperTuxKart\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2015-09-26 00:20+1000\n"
|
||||
"PO-Revision-Date: 2015-09-26 09:35+0000\n"
|
||||
"Last-Translator: Auria <auria.mg@gmail.com>\n"
|
||||
"PO-Revision-Date: 2015-10-13 18:00+0000\n"
|
||||
"Last-Translator: Max Lyashuk <m_lyashuk@ukr.net>\n"
|
||||
"Language-Team: Ukrainian (http://www.transifex.com/supertuxkart/supertuxkart/language/uk/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
@ -2936,7 +2936,7 @@ msgstr "Необхідний час: %i"
|
||||
#: src/states_screens/dialogs/select_challenge.cpp:64
|
||||
#, c-format
|
||||
msgid "Required Nitro Points: %i"
|
||||
msgstr ""
|
||||
msgstr "Необхідна кількість азоту: %i"
|
||||
|
||||
#: src/states_screens/dialogs/select_challenge.cpp:68
|
||||
#, c-format
|
||||
|
@ -72,20 +72,18 @@ if __name__ == "__main__":
|
||||
all_authors = old_authors + new_authors;
|
||||
all_authors = sorted(all_authors, key=lambda x: x.lower())
|
||||
all_authors_string = reduce(lambda x,y: x+"\\n"+y, all_authors, "")
|
||||
|
||||
|
||||
credits_line = "msgstr \"Launchpad Contributions:%s\"\n"%all_authors_string
|
||||
# If no old authors exists, write a new entry:
|
||||
if contributions==-1:
|
||||
lines.append("\n")
|
||||
lines.append("#: src/states_screens/credits.cpp:209\n")
|
||||
lines.append("msgid \"translator-credits\"\n")
|
||||
|
||||
lines.append(credits_line)
|
||||
else:
|
||||
# Otherwise just delete the old contribution string
|
||||
# so that the new one can be appended below.
|
||||
del lines[contributions]
|
||||
# Otherwise just replace the old contribution string
|
||||
lines[contributions] = credits_line
|
||||
|
||||
# Append new author list
|
||||
lines.append("msgstr \"Launchpad Contributions:%s\"\n"%all_authors_string)
|
||||
|
||||
# Overwrite old file
|
||||
f = open(sys.argv[1], "w")
|
||||
|
@ -11,8 +11,8 @@ msgstr ""
|
||||
"Project-Id-Version: SuperTuxKart\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2015-09-26 00:20+1000\n"
|
||||
"PO-Revision-Date: 2015-09-26 09:36+0000\n"
|
||||
"Last-Translator: Auria <auria.mg@gmail.com>\n"
|
||||
"PO-Revision-Date: 2015-09-28 02:11+0000\n"
|
||||
"Last-Translator: Ben Au\n"
|
||||
"Language-Team: Chinese (China) (http://www.transifex.com/supertuxkart/supertuxkart/language/zh_CN/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
@ -2914,7 +2914,7 @@ msgid ""
|
||||
"the box below, you are confirming that you understand these terms. If you "
|
||||
"have any questions or comments regarding these terms, one of the members of "
|
||||
"the development team would gladly assist you."
|
||||
msgstr ""
|
||||
msgstr "请在“%s”阅读 SuperTuxKart 的服务条款。您必须同意这些条款以在 STK 上注册帐号。在勾选了下面的单选框后,您就确认您已经了解了这些条款。若您对这些条款有任何问题或意见,开发人员都会很乐意为您服务。"
|
||||
|
||||
#: src/states_screens/dialogs/select_challenge.cpp:53
|
||||
#, c-format
|
||||
|
@ -14,8 +14,8 @@ msgstr ""
|
||||
"Project-Id-Version: SuperTuxKart\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2015-09-26 00:20+1000\n"
|
||||
"PO-Revision-Date: 2015-09-27 04:03+0000\n"
|
||||
"Last-Translator: Jeff Huang <s8321414@gmail.com>\n"
|
||||
"PO-Revision-Date: 2015-10-08 17:31+0000\n"
|
||||
"Last-Translator: V字龍(Vdragon) <Vdragon.Taiwan@gmail.com>\n"
|
||||
"Language-Team: Chinese (Taiwan) (http://www.transifex.com/supertuxkart/supertuxkart/language/zh_TW/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
@ -1057,7 +1057,7 @@ msgstr "變更"
|
||||
#. I18N: ./data/gui/online/recovery_input.stkgui
|
||||
#. I18N: In the recovery dialog
|
||||
msgid "Account Recovery"
|
||||
msgstr "帳號恢復"
|
||||
msgstr "帳號救援"
|
||||
|
||||
#. I18N: ./data/gui/online/recovery_info.stkgui
|
||||
#. I18N: In the recovery dialog
|
||||
|
@ -2,9 +2,7 @@ layout(triangles) in;
|
||||
layout(triangle_strip, max_vertices=3) out;
|
||||
|
||||
in int layer[3];
|
||||
in vec2 uv_in[3];
|
||||
flat out int slice;
|
||||
out vec2 uv;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
@ -12,7 +10,6 @@ void main(void)
|
||||
for(int i=0; i<3; i++)
|
||||
{
|
||||
slice = layer[0];
|
||||
uv = uv_in[i];
|
||||
gl_Position = gl_in[i].gl_Position;
|
||||
EmitVertex();
|
||||
}
|
||||
|
@ -6,3 +6,4 @@ stk release svn version of assets
|
||||
0.8.2-beta2 needs r15985
|
||||
0.9 needs r16279
|
||||
0.9.1-rc1 needs r16470
|
||||
0.9.1 needs r16503
|
||||
|
@ -58,15 +58,24 @@ static inline void btAlignedFreeDefault(void *ptr)
|
||||
free(ptr);
|
||||
}
|
||||
#else
|
||||
|
||||
static inline void *btAlignedAllocDefault(size_t size, int alignment)
|
||||
{
|
||||
void *ret;
|
||||
char *real;
|
||||
#ifdef __MINGW64__
|
||||
uintptr_t offset;
|
||||
#else
|
||||
unsigned long offset;
|
||||
#endif
|
||||
|
||||
real = (char *)sAllocFunc(size + sizeof(void *) + (alignment-1));
|
||||
if (real) {
|
||||
#ifdef __MINGW64__
|
||||
offset = (alignment - (uintptr_t)(real + sizeof(void *))) & (alignment-1);
|
||||
#else
|
||||
offset = (alignment - (unsigned long)(real + sizeof(void *))) & (alignment-1);
|
||||
#endif
|
||||
ret = (void *)((real + sizeof(void *)) + offset);
|
||||
*((void **)(ret)-1) = (void *)(real);
|
||||
} else {
|
||||
|
@ -213,7 +213,11 @@ protected:
|
||||
|
||||
int *intPtr=0;
|
||||
short *shtPtr=0;
|
||||
#ifdef __MINGW64__
|
||||
char *cp = 0;int dataLen =0;intptr_t nr=0;
|
||||
#else
|
||||
char *cp = 0;int dataLen =0;long nr=0;
|
||||
#endif
|
||||
intPtr = (int*)m_dna;
|
||||
|
||||
/*
|
||||
@ -247,7 +251,11 @@ protected:
|
||||
cp++;
|
||||
}
|
||||
{
|
||||
#ifdef __MINGW64__
|
||||
nr= (intptr_t)cp;
|
||||
#else
|
||||
nr= (long)cp;
|
||||
#endif
|
||||
// long mask=3;
|
||||
nr= ((nr+3)&~3)-nr;
|
||||
while (nr--)
|
||||
@ -282,7 +290,11 @@ protected:
|
||||
}
|
||||
|
||||
{
|
||||
#ifdef __MINGW64__
|
||||
nr= (intptr_t)cp;
|
||||
#else
|
||||
nr= (long)cp;
|
||||
#endif
|
||||
// long mask=3;
|
||||
nr= ((nr+3)&~3)-nr;
|
||||
while (nr--)
|
||||
|
@ -501,7 +501,7 @@ if(APPLE)
|
||||
set_source_files_properties(source/Irrlicht/MacOSX/OSXClipboard.mm PROPERTIES LANGUAGE C)
|
||||
endif()
|
||||
|
||||
add_library(stkirrlicht ${IRRLICHT_SOURCES})
|
||||
add_library(stkirrlicht STATIC ${IRRLICHT_SOURCES})
|
||||
target_link_libraries(stkirrlicht ${PNG_LIBRARY} ${JPEG_LIBRARY} ${ZLIB_LIBRARY})
|
||||
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Modify this file to change the last-modified date when you add/remove a file.
|
||||
# This will then trigger a new cmake run automatically.
|
||||
# This will then trigger a new cmake run automatically.
|
||||
file(GLOB_RECURSE STK_HEADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "src/*.hpp")
|
||||
file(GLOB_RECURSE STK_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "src/*.cpp")
|
||||
file(GLOB_RECURSE STK_SHADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "data/shaders/*")
|
||||
|
@ -626,12 +626,12 @@ namespace UserConfigParams
|
||||
PARAM_DEFAULT( BoolUserConfigParam(true, "weather_gfx",
|
||||
&m_graphics_quality, "Weather effects") );
|
||||
PARAM_PREFIX IntUserConfigParam m_show_steering_animations
|
||||
PARAM_DEFAULT( IntUserConfigParam(ANIMS_ALL,
|
||||
PARAM_DEFAULT( IntUserConfigParam(ANIMS_PLAYERS_ONLY,
|
||||
"steering_animations", &m_graphics_quality,
|
||||
"Whether to display kart animations (0=disabled for all; "
|
||||
"1=enabled for humans, disabled for AIs; 2=enabled for all") );
|
||||
PARAM_PREFIX IntUserConfigParam m_anisotropic
|
||||
PARAM_DEFAULT( IntUserConfigParam(8, "anisotropic",
|
||||
PARAM_DEFAULT( IntUserConfigParam(4, "anisotropic",
|
||||
&m_graphics_quality,
|
||||
"Quality of anisotropic filtering (usual values include 2-4-8-16; 0 to disable)") );
|
||||
PARAM_PREFIX BoolUserConfigParam m_trilinear
|
||||
@ -666,7 +666,7 @@ namespace UserConfigParams
|
||||
"shadows_resoltion", &m_graphics_quality,
|
||||
"Shadow resolution (0 = disabled") );
|
||||
PARAM_PREFIX BoolUserConfigParam m_degraded_IBL
|
||||
PARAM_DEFAULT(BoolUserConfigParam(false,
|
||||
PARAM_DEFAULT(BoolUserConfigParam(true,
|
||||
"Degraded_IBL", &m_graphics_quality,
|
||||
"Disable specular IBL"));
|
||||
|
||||
|
@ -96,6 +96,7 @@ GPUTimer m_perf_query[Q_LAST];
|
||||
|
||||
const int MIN_SUPPORTED_HEIGHT = 768;
|
||||
const int MIN_SUPPORTED_WIDTH = 1024;
|
||||
const bool ALLOW_1280_X_720 = true;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** The constructor creates the irrlicht device. It first creates a NULL
|
||||
@ -327,8 +328,9 @@ void IrrDriver::createListOfVideoModes()
|
||||
{
|
||||
const int w = modes->getVideoModeResolution(i).Width;
|
||||
const int h = modes->getVideoModeResolution(i).Height;
|
||||
if ( (h < MIN_SUPPORTED_HEIGHT || w < MIN_SUPPORTED_WIDTH) &&
|
||||
( ! (h==600 && w==800 && UserConfigParams::m_artist_debug_mode) ) )
|
||||
if ((h < MIN_SUPPORTED_HEIGHT || w < MIN_SUPPORTED_WIDTH) &&
|
||||
(!(h==600 && w==800 && UserConfigParams::m_artist_debug_mode) &&
|
||||
(!(h==720 && w==1280 && ALLOW_1280_X_720 == true))))
|
||||
continue;
|
||||
|
||||
VideoMode mode(w, h);
|
||||
|
@ -39,8 +39,9 @@
|
||||
#include "replay/replay_recorder.hpp"
|
||||
#include "states_screens/kart_selection.hpp"
|
||||
#include "states_screens/main_menu_screen.hpp"
|
||||
#include "states_screens/options_screen_input2.hpp"
|
||||
#include "states_screens/options_screen_device.hpp"
|
||||
#include "states_screens/state_manager.hpp"
|
||||
#include "utils/debug.hpp"
|
||||
#include "utils/string_utils.hpp"
|
||||
|
||||
#include <ISceneManager.h>
|
||||
@ -109,6 +110,14 @@ void InputManager::handleStaticAction(int key, int value)
|
||||
}
|
||||
|
||||
|
||||
if (world != NULL && UserConfigParams::m_artist_debug_mode &&
|
||||
control_is_pressed && value > 0)
|
||||
{
|
||||
if (Debug::handleStaticAction(key))
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: move debug shortcuts to Debug::handleStaticAction
|
||||
switch (key)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
@ -131,6 +140,7 @@ void InputManager::handleStaticAction(int key, int value)
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
case KEY_CONTROL:
|
||||
case KEY_RCONTROL:
|
||||
case KEY_LCONTROL:
|
||||
@ -425,7 +435,7 @@ void InputManager::inputSensing(Input::InputType type, int deviceID,
|
||||
sensed_input.m_device_id = deviceID;
|
||||
sensed_input.m_button_id = button;
|
||||
sensed_input.m_character = deviceID;
|
||||
OptionsScreenInput2::getInstance()->gotSensedInput(sensed_input);
|
||||
OptionsScreenDevice::getInstance()->gotSensedInput(sensed_input);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
@ -437,7 +447,7 @@ void InputManager::inputSensing(Input::InputType type, int deviceID,
|
||||
sensed_input.m_device_id = deviceID;
|
||||
sensed_input.m_button_id = button;
|
||||
sensed_input.m_character = deviceID;
|
||||
OptionsScreenInput2::getInstance()->gotSensedInput(sensed_input);
|
||||
OptionsScreenDevice::getInstance()->gotSensedInput(sensed_input);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
@ -472,7 +482,7 @@ void InputManager::inputSensing(Input::InputType type, int deviceID,
|
||||
: Input::AD_NEGATIVE;
|
||||
sensed_input.m_axis_range = Input::AR_FULL;
|
||||
sensed_input.m_character = deviceID;
|
||||
OptionsScreenInput2::getInstance()->gotSensedInput(sensed_input);
|
||||
OptionsScreenDevice::getInstance()->gotSensedInput(sensed_input);
|
||||
|
||||
}
|
||||
else m_sensed_input_high_gamepad.insert(input_id);
|
||||
@ -494,7 +504,7 @@ void InputManager::inputSensing(Input::InputType type, int deviceID,
|
||||
sensed_input.m_axis_range = id_was_zero ? Input::AR_HALF
|
||||
: Input::AR_FULL;
|
||||
sensed_input.m_character = deviceID;
|
||||
OptionsScreenInput2::getInstance()->gotSensedInput(sensed_input);
|
||||
OptionsScreenDevice::getInstance()->gotSensedInput(sensed_input);
|
||||
}
|
||||
else if( inverse_id_was_high )
|
||||
{
|
||||
@ -510,7 +520,7 @@ void InputManager::inputSensing(Input::InputType type, int deviceID,
|
||||
sensed_input.m_axis_range = id_was_zero ? Input::AR_HALF
|
||||
: Input::AR_FULL;
|
||||
sensed_input.m_character = deviceID;
|
||||
OptionsScreenInput2::getInstance()->gotSensedInput(sensed_input);
|
||||
OptionsScreenDevice::getInstance()->gotSensedInput(sensed_input);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -921,20 +931,8 @@ EventPropagation InputManager::input(const SEvent& event)
|
||||
// escape is a little special
|
||||
if (key == KEY_ESCAPE)
|
||||
{
|
||||
// Exit from first person view if activated
|
||||
if (!GUIEngine::ModalDialog::isADialogActive() &&
|
||||
StateManager::get()->getGameState() == GUIEngine::GAME &&
|
||||
UserConfigParams::m_camera_debug == 3)
|
||||
{
|
||||
UserConfigParams::m_camera_debug = 0;
|
||||
irr_driver->getDevice()->getCursorControl()->setVisible(true);
|
||||
return EVENT_BLOCK;
|
||||
}
|
||||
else
|
||||
{
|
||||
StateManager::get()->escapePressed();
|
||||
return EVENT_BLOCK;
|
||||
}
|
||||
StateManager::get()->escapePressed();
|
||||
return EVENT_BLOCK;
|
||||
}
|
||||
// 'backspace' in a text control must never be mapped, since user
|
||||
// can be in a text area trying to erase text (and if it's mapped
|
||||
|
@ -1013,7 +1013,7 @@ int handleCmdLine()
|
||||
// Demo mode
|
||||
if(CommandLine::has("--demo-mode", &s))
|
||||
{
|
||||
float t;
|
||||
float t = 0;
|
||||
StringUtils::fromString(s, t);
|
||||
DemoWorld::enableDemoMode(t);
|
||||
// The default number of laps is taken from ProfileWorld and
|
||||
|
@ -101,7 +101,7 @@ void* waitInput(void* data)
|
||||
else if (NetworkManager::getInstance() &&
|
||||
NetworkManager::getInstance()->getPeers().size() > 0)
|
||||
{
|
||||
NetworkString msg;
|
||||
NetworkString msg(1+str.size());
|
||||
msg.ai8(0);
|
||||
msg += str;
|
||||
NetworkManager::getInstance()->getPeers()[0]->sendPacket(msg);
|
||||
|
@ -61,7 +61,7 @@ Event::Event(ENetEvent* event)
|
||||
if (peers[i]->m_peer == event->peer)
|
||||
{
|
||||
*peer = peers[i];
|
||||
Log::verbose("Event", "The peer you sought has been found on %lx", (long int)(peer));
|
||||
Log::verbose("Event", "The peer you sought has been found on %p", peer);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -70,7 +70,7 @@ Event::Event(ENetEvent* event)
|
||||
STKPeer* new_peer = new STKPeer();
|
||||
new_peer->m_peer = event->peer;
|
||||
*peer = new_peer;
|
||||
Log::debug("Event", "Creating a new peer, address are STKPeer:%lx, Peer:%lx", (long int)(new_peer), (long int)(event->peer));
|
||||
Log::debug("Event", "Creating a new peer, address are STKPeer:%p, Peer:%p", new_peer, event->peer);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -35,8 +35,7 @@
|
||||
|
||||
NetworkManager::NetworkManager()
|
||||
{
|
||||
m_public_address.ip = 0;
|
||||
m_public_address.port = 0;
|
||||
m_public_address.clear();
|
||||
m_localhost = NULL;
|
||||
m_game_setup = NULL;
|
||||
}
|
||||
@ -87,7 +86,7 @@ void NetworkManager::abort()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool NetworkManager::connect(TransportAddress peer)
|
||||
bool NetworkManager::connect(const TransportAddress& peer)
|
||||
{
|
||||
if (peerExists(peer))
|
||||
return isConnectedTo(peer);
|
||||
@ -194,9 +193,9 @@ void NetworkManager::setLogin(std::string username, std::string password)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void NetworkManager::setPublicAddress(TransportAddress addr)
|
||||
void NetworkManager::setPublicAddress(const TransportAddress& addr)
|
||||
{
|
||||
m_public_address = addr;
|
||||
m_public_address.copy(addr);
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
@ -234,14 +233,14 @@ void NetworkManager::removePeer(STKPeer* peer)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool NetworkManager::peerExists(TransportAddress peer)
|
||||
bool NetworkManager::peerExists(const TransportAddress& peer)
|
||||
{
|
||||
return m_localhost->peerExists(peer);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool NetworkManager::isConnectedTo(TransportAddress peer)
|
||||
bool NetworkManager::isConnectedTo(const TransportAddress& peer)
|
||||
{
|
||||
return m_localhost->isConnectedTo(peer);
|
||||
}
|
||||
|
@ -64,7 +64,7 @@ class NetworkManager : public AbstractSingleton<NetworkManager>
|
||||
* \param peer : The transport address which you want to connect to.
|
||||
* \return True if we're successfully connected. False elseway.
|
||||
*/
|
||||
virtual bool connect(TransportAddress peer);
|
||||
virtual bool connect(const TransportAddress& peer);
|
||||
/** \brief Changes the socket working mode.
|
||||
* Sockets can be in two modes : The ENet mode and a mode we will call
|
||||
* the 'Raw' mode. In the ENet mode, the socket will be read as
|
||||
@ -90,12 +90,12 @@ class NetworkManager : public AbstractSingleton<NetworkManager>
|
||||
|
||||
// raw data management
|
||||
void setLogin(std::string username, std::string password);
|
||||
void setPublicAddress(TransportAddress addr);
|
||||
void setPublicAddress(const TransportAddress& addr);
|
||||
void removePeer(STKPeer* peer);
|
||||
|
||||
// getters
|
||||
virtual bool peerExists(TransportAddress peer);
|
||||
virtual bool isConnectedTo(TransportAddress peer);
|
||||
virtual bool peerExists(const TransportAddress& peer);
|
||||
virtual bool isConnectedTo(const TransportAddress& peer);
|
||||
|
||||
virtual bool isServer() = 0;
|
||||
inline bool isClient() { return !isServer(); }
|
||||
@ -103,7 +103,7 @@ class NetworkManager : public AbstractSingleton<NetworkManager>
|
||||
STKHost* getHost() { return m_localhost; }
|
||||
std::vector<STKPeer*> getPeers() { return m_peers; }
|
||||
unsigned int getPeerCount() { return (int)m_peers.size(); }
|
||||
TransportAddress getPublicAddress() { return m_public_address; }
|
||||
const TransportAddress& getPublicAddress() { return m_public_address; }
|
||||
GameSetup* getGameSetup() { return m_game_setup; }
|
||||
|
||||
protected:
|
||||
|
@ -38,238 +38,457 @@ typedef unsigned char uchar;
|
||||
*/
|
||||
class NetworkString
|
||||
{
|
||||
private:
|
||||
union {
|
||||
float f;
|
||||
uint8_t i[4];
|
||||
float f;
|
||||
uint8_t i[4];
|
||||
} f_as_i; // float as integer
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
union {
|
||||
double d;
|
||||
uint8_t i[8];
|
||||
double d;
|
||||
uint8_t i[8];
|
||||
} d_as_i; // double as integer
|
||||
public:
|
||||
NetworkString() { }
|
||||
NetworkString(const uint8_t& value) { m_string.push_back(value); }
|
||||
NetworkString(NetworkString const& copy) { m_string = copy.m_string; }
|
||||
NetworkString(const std::string & value) { m_string = std::vector<uint8_t>(value.begin(), value.end()); }
|
||||
|
||||
NetworkString& removeFront(int size)
|
||||
{
|
||||
m_string.erase(m_string.begin(), m_string.begin()+size);
|
||||
return *this;
|
||||
}
|
||||
NetworkString& remove(int pos, int size)
|
||||
{
|
||||
m_string.erase(m_string.begin()+pos, m_string.begin()+pos+size);
|
||||
return *this;
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
uint8_t operator[](const int& pos) const
|
||||
{
|
||||
return getUInt8(pos);
|
||||
}
|
||||
std::vector<uint8_t> m_string;
|
||||
|
||||
NetworkString& addUInt8(const uint8_t& value)
|
||||
{
|
||||
m_string.push_back(value);
|
||||
return *this;
|
||||
}
|
||||
inline NetworkString& ai8(const uint8_t& value) { return addUInt8(value); }
|
||||
NetworkString& addUInt16(const uint16_t& value)
|
||||
{
|
||||
m_string.push_back((value>>8)&0xff);
|
||||
m_string.push_back(value&0xff);
|
||||
return *this;
|
||||
}
|
||||
inline NetworkString& ai16(const uint16_t& value) { return addUInt16(value); }
|
||||
NetworkString& addUInt32(const uint32_t& value)
|
||||
{
|
||||
m_string.push_back((value>>24)&0xff);
|
||||
m_string.push_back((value>>16)&0xff);
|
||||
m_string.push_back((value>>8)&0xff);
|
||||
m_string.push_back(value&0xff);
|
||||
return *this;
|
||||
}
|
||||
inline NetworkString& ai32(const uint32_t& value) { return addUInt32(value); }
|
||||
NetworkString& addInt(const int& value)
|
||||
{
|
||||
m_string.push_back((value>>24)&0xff);
|
||||
m_string.push_back((value>>16)&0xff);
|
||||
m_string.push_back((value>>8)&0xff);
|
||||
m_string.push_back(value&0xff);
|
||||
return *this;
|
||||
}
|
||||
inline NetworkString& ai(const int& value) { return addInt(value); }
|
||||
NetworkString& addFloat(const float& value) //!< BEWARE OF PRECISION
|
||||
{
|
||||
assert(sizeof(float)==4);
|
||||
f_as_i.f = value;
|
||||
m_string.push_back(f_as_i.i[0]);
|
||||
m_string.push_back(f_as_i.i[1]);
|
||||
m_string.push_back(f_as_i.i[2]);
|
||||
m_string.push_back(f_as_i.i[3]);
|
||||
return *this;
|
||||
}
|
||||
inline NetworkString& af(const float& value) { return addFloat(value); }
|
||||
NetworkString& addDouble(const double& value) //!< BEWARE OF PRECISION
|
||||
{
|
||||
assert(sizeof(double)==8);
|
||||
d_as_i.d = value;
|
||||
m_string.push_back(d_as_i.i[0]);
|
||||
m_string.push_back(d_as_i.i[1]);
|
||||
m_string.push_back(d_as_i.i[2]);
|
||||
m_string.push_back(d_as_i.i[3]);
|
||||
m_string.push_back(d_as_i.i[4]);
|
||||
m_string.push_back(d_as_i.i[5]);
|
||||
m_string.push_back(d_as_i.i[6]);
|
||||
m_string.push_back(d_as_i.i[7]);
|
||||
return *this;
|
||||
}
|
||||
inline NetworkString& ad(const double& value) { return addDouble(value); }
|
||||
NetworkString& addChar(const char& value)
|
||||
{
|
||||
m_string.push_back((uint8_t)(value));
|
||||
return *this;
|
||||
}
|
||||
inline NetworkString& ac(const char& value) { return addChar(value); }
|
||||
public:
|
||||
/** Dummy constructor. */
|
||||
NetworkString() { }
|
||||
|
||||
NetworkString& addString(const std::string& value)
|
||||
// ------------------------------------------------------------------------
|
||||
/** Constructor to store one byte. */
|
||||
NetworkString(int len)
|
||||
{
|
||||
m_string.reserve(len);
|
||||
} // NetworkString(int)
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Copy constructor. */
|
||||
NetworkString(NetworkString const& copy) { m_string = copy.m_string; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Copy the data from a string. */
|
||||
NetworkString(const std::string & value)
|
||||
{
|
||||
m_string = std::vector<uint8_t>(value.begin(), value.end());
|
||||
} // NetworkString
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
NetworkString& add(const std::string &s)
|
||||
{
|
||||
return addUInt8(uint8_t(s.size())).as(s);
|
||||
} // add
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
NetworkString& removeFront(int size)
|
||||
{
|
||||
m_string.erase(m_string.begin(), m_string.begin() + size);
|
||||
return *this;
|
||||
} // removeFront
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
NetworkString& remove(int pos, int size)
|
||||
{
|
||||
m_string.erase(m_string.begin() + pos, m_string.begin() + pos + size);
|
||||
return *this;
|
||||
} // remove
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
uint8_t operator[](const int& pos) const
|
||||
{
|
||||
return getUInt8(pos);
|
||||
} // operator[]
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Add 8 bit unsigned int. */
|
||||
NetworkString& addUInt8(const uint8_t& value)
|
||||
{
|
||||
m_string.push_back(value);
|
||||
return *this;
|
||||
} // addUInt8
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Adds 8 bit integer. */
|
||||
inline NetworkString& ai8(const uint8_t& value) { return addUInt8(value); }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Adds 16 bit unsigned int. */
|
||||
NetworkString& addUInt16(const uint16_t& value)
|
||||
{
|
||||
m_string.push_back((value >> 8) & 0xff);
|
||||
m_string.push_back(value & 0xff);
|
||||
return *this;
|
||||
} // addUInt16
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Adds 16 bit integer. */
|
||||
inline NetworkString& ai16(const uint16_t& value)
|
||||
{
|
||||
return addUInt16(value);
|
||||
} // ai16
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Adds unsigned 32 bit integer. */
|
||||
NetworkString& addUInt32(const uint32_t& value)
|
||||
{
|
||||
m_string.push_back((value >> 24) & 0xff);
|
||||
m_string.push_back((value >> 16) & 0xff);
|
||||
m_string.push_back((value >> 8) & 0xff);
|
||||
m_string.push_back(value & 0xff);
|
||||
return *this;
|
||||
} // addUInt32
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Adds 32 bit integer. */
|
||||
inline NetworkString& ai32(const uint32_t& value)
|
||||
{
|
||||
return addUInt32(value);
|
||||
} // ai32
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
NetworkString& addInt(const int& value)
|
||||
{
|
||||
m_string.push_back((value >> 24) & 0xff);
|
||||
m_string.push_back((value >> 16) & 0xff);
|
||||
m_string.push_back((value >> 8) & 0xff);
|
||||
m_string.push_back(value & 0xff);
|
||||
return *this;
|
||||
} // addInt
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
inline NetworkString& ai(const int& value) { return addInt(value); }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Adds a 4 byte floating point value. */
|
||||
NetworkString& addFloat(const float& value) //!< BEWARE OF PRECISION
|
||||
{
|
||||
assert(sizeof(float) == 4);
|
||||
f_as_i.f = value;
|
||||
m_string.push_back(f_as_i.i[0]);
|
||||
m_string.push_back(f_as_i.i[1]);
|
||||
m_string.push_back(f_as_i.i[2]);
|
||||
m_string.push_back(f_as_i.i[3]);
|
||||
return *this;
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
/** Adds a 4 byte floating point value. */
|
||||
inline NetworkString& af(const float& value) { return addFloat(value); }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Adds a 8 byte floating point value. */
|
||||
NetworkString& addDouble(const double& value) //!< BEWARE OF PRECISION
|
||||
{
|
||||
assert(sizeof(double) == 8);
|
||||
d_as_i.d = value;
|
||||
m_string.push_back(d_as_i.i[0]);
|
||||
m_string.push_back(d_as_i.i[1]);
|
||||
m_string.push_back(d_as_i.i[2]);
|
||||
m_string.push_back(d_as_i.i[3]);
|
||||
m_string.push_back(d_as_i.i[4]);
|
||||
m_string.push_back(d_as_i.i[5]);
|
||||
m_string.push_back(d_as_i.i[6]);
|
||||
m_string.push_back(d_as_i.i[7]);
|
||||
return *this;
|
||||
} // addDouble
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Adds n 8 byte floating point value. */
|
||||
inline NetworkString& ad(const double& value) { return addDouble(value); }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Adds a single character to the string. */
|
||||
NetworkString& addChar(const char& value)
|
||||
{
|
||||
m_string.push_back((uint8_t)(value));
|
||||
return *this;
|
||||
} // addChar
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Adds a single character. */
|
||||
inline NetworkString& ac(const char& value) { return addChar(value); }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Adds a string. */
|
||||
NetworkString& addString(const std::string& value)
|
||||
{
|
||||
for (unsigned int i = 0; i < value.size(); i++)
|
||||
m_string.push_back((uint8_t)(value[i]));
|
||||
return *this;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Adds a string. */
|
||||
inline NetworkString& as(const std::string& value)
|
||||
{
|
||||
return addString(value);
|
||||
} // as
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Adds the content of another network string. */
|
||||
NetworkString& operator+=(NetworkString const& value)
|
||||
{
|
||||
m_string.insert(m_string.end(), value.m_string.begin(),
|
||||
value.m_string.end() );
|
||||
return *this;
|
||||
} // operator+=
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the content of the network string as a std::string. */
|
||||
const std::string std_string() const
|
||||
{
|
||||
std::string str(m_string.begin(), m_string.end());
|
||||
return str;
|
||||
} // std_string
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the current length of the network string. */
|
||||
int size() const { return (int)m_string.size(); }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns a byte pointer to the content of the network string. */
|
||||
uint8_t* getBytes() { return &m_string[0]; };
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns a byte pointer to the content of the network string. */
|
||||
const uint8_t* getBytes() const { return &m_string[0]; };
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
template<typename T, size_t n>
|
||||
T get(int pos) const
|
||||
{
|
||||
int a = n;
|
||||
T result = 0;
|
||||
while (a--)
|
||||
{
|
||||
for (unsigned int i = 0; i < value.size(); i++)
|
||||
m_string.push_back((uint8_t)(value[i]));
|
||||
return *this;
|
||||
result <<= 8; // offset one byte
|
||||
// add the data to result
|
||||
result += ((uint8_t)(m_string[pos + n - 1 - a]) & 0xff);
|
||||
}
|
||||
inline NetworkString& as(const std::string& value) { return addString(value); }
|
||||
return result;
|
||||
} // get(int pos)
|
||||
|
||||
NetworkString& operator+=(NetworkString const& value)
|
||||
// ------------------------------------------------------------------------
|
||||
// Another function for n == 1 to surpress warnings in clang
|
||||
template<typename T>
|
||||
T get(int pos) const
|
||||
{
|
||||
return m_string[pos];
|
||||
} // get
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns a standard integer. */
|
||||
inline int getInt(int pos = 0) const { return get<int, 4>(pos); }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns a standard unsigned integer. */
|
||||
inline uint32_t getUInt(int pos = 0) const { return get<uint32_t, 4>(pos); }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns a unsigned 32 bit integer. */
|
||||
inline uint32_t getUInt32(int pos = 0) const { return get<uint32_t, 4>(pos); }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns an unsigned 16 bit integer. */
|
||||
inline uint16_t getUInt16(int pos=0) const { return get<uint16_t, 2>(pos); }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns an unsigned 8-bit integer. */
|
||||
inline uint8_t getUInt8(int pos = 0) const { return get<uint8_t>(pos); }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns a character. */
|
||||
inline char getChar(int pos = 0) const { return get<char>(pos); }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns an unsigned character. */
|
||||
inline unsigned char getUChar(int pos = 0) const
|
||||
{
|
||||
return get<unsigned char>(pos);
|
||||
} // getUChar
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns a part of the network string as a std::string.
|
||||
* \param pos First position to be in the string.
|
||||
* \param len Number of bytes to copy.
|
||||
*/
|
||||
std::string getString(int pos, int len) const
|
||||
{
|
||||
return std::string(m_string.begin() + pos,
|
||||
m_string.begin() + pos + len);
|
||||
} // getString
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns a standard integer. */
|
||||
inline int gi(int pos = 0) const { return get<int, 4>(pos); }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Retrusn an unsigned standard integer. */
|
||||
inline uint32_t gui(int pos = 0) const { return get<uint32_t, 4>(pos); }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns an unsigned 32-bit integer. */
|
||||
inline uint32_t gui32(int pos = 0) const { return get<uint32_t, 4>(pos); }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns an unsigned 16-bit integer. */
|
||||
inline uint16_t gui16(int pos = 0) const { return get<uint16_t, 2>(pos); }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns an unsigned 8-bit integer. */
|
||||
inline uint8_t gui8(int pos = 0) const { return get<uint8_t>(pos); }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Return a character. */
|
||||
inline char gc(int pos = 0) const { return get<char>(pos); }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Return an unsigned character. */
|
||||
inline unsigned char guc(int pos = 0) const
|
||||
{
|
||||
return get<unsigned char>(pos);
|
||||
} // guc
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns a 4-byte floating point value. */
|
||||
float getFloat(int pos = 0) //!< BEWARE OF PRECISION
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
f_as_i.i[i] = m_string[pos + i];
|
||||
return f_as_i.f;
|
||||
} // getFloat
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
//! Functions to get while removing
|
||||
template<typename T, size_t n>
|
||||
T getAndRemove(int pos)
|
||||
{
|
||||
int a = n;
|
||||
T result = 0;
|
||||
while (a--)
|
||||
{
|
||||
m_string.insert( m_string.end(), value.m_string.begin(), value.m_string.end() );
|
||||
return *this;
|
||||
result <<= 8; // offset one byte
|
||||
result += ((uint8_t)(m_string[pos + n - 1 - a]) & 0xff); // add the data
|
||||
}
|
||||
remove(pos, n);
|
||||
return result;
|
||||
} // getAndRemove
|
||||
|
||||
const std::string std_string() const
|
||||
{
|
||||
std::string str(m_string.begin(), m_string.end());
|
||||
return str;
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
// Another function for n == 1 to surpress warnings in clang
|
||||
template<typename T>
|
||||
T getAndRemove(int pos)
|
||||
{
|
||||
T result = m_string[pos];
|
||||
remove(pos, 1);
|
||||
return result;
|
||||
} // getAndRemove
|
||||
|
||||
int size() const
|
||||
{
|
||||
return (int)m_string.size();
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
inline int getAndRemoveInt(int pos = 0)
|
||||
{
|
||||
return getAndRemove<int, 4>(pos);
|
||||
} // getAndRemoveInt
|
||||
|
||||
uint8_t* getBytes() { return &m_string[0]; };
|
||||
const uint8_t* getBytes() const { return &m_string[0]; };
|
||||
// ------------------------------------------------------------------------
|
||||
inline uint32_t getAndRemoveUInt(int pos = 0)
|
||||
{
|
||||
return getAndRemove<uint32_t, 4>(pos);
|
||||
} // getAndRemoveUInt
|
||||
|
||||
template<typename T, size_t n>
|
||||
T get(int pos) const
|
||||
{
|
||||
int a = n;
|
||||
T result = 0;
|
||||
while(a--)
|
||||
{
|
||||
result <<= 8; // offset one byte
|
||||
result += ((uint8_t)(m_string[pos+n-1-a]) & 0xff); // add the data to result
|
||||
}
|
||||
return result;
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
inline uint32_t getAndRemoveUInt32(int pos = 0)
|
||||
{
|
||||
return getAndRemove<uint32_t, 4>(pos);
|
||||
} // getAndRemoveUInt32
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
inline uint16_t getAndRemoveUInt16(int pos = 0)
|
||||
{
|
||||
return getAndRemove<uint16_t, 2>(pos);
|
||||
} // getAndRemoveUInt16
|
||||
|
||||
// Another function for n == 1 to surpress warnings in clang
|
||||
template<typename T>
|
||||
T get(int pos) const
|
||||
{
|
||||
return m_string[pos];
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
inline uint8_t getAndRemoveUInt8(int pos = 0)
|
||||
{
|
||||
return getAndRemove<uint8_t>(pos);
|
||||
} // getAndRemoveUInt8
|
||||
// ------------------------------------------------------------------------
|
||||
inline char getAndRemoveChar(int pos = 0)
|
||||
{
|
||||
return getAndRemove<char>(pos);
|
||||
} // getAndRemoveChar
|
||||
|
||||
inline int getInt(int pos = 0) const { return get<int,4>(pos); }
|
||||
inline uint32_t getUInt(int pos = 0) const { return get<uint32_t,4>(pos); }
|
||||
inline uint32_t getUInt32(int pos = 0) const { return get<uint32_t,4>(pos); }
|
||||
inline uint16_t getUInt16(int pos = 0) const { return get<uint16_t,2>(pos); }
|
||||
inline uint8_t getUInt8(int pos = 0) const { return get<uint8_t>(pos); }
|
||||
inline char getChar(int pos = 0) const { return get<char>(pos); }
|
||||
inline unsigned char getUChar(int pos = 0) const { return get<unsigned char>(pos); }
|
||||
std::string getString(int pos, int len) const { return std::string(m_string.begin()+pos, m_string.begin()+pos+len); }
|
||||
// ------------------------------------------------------------------------
|
||||
inline unsigned char getAndRemoveUChar(int pos = 0)
|
||||
{
|
||||
return getAndRemove<unsigned char>(pos);
|
||||
} // getAndRemoveUChar
|
||||
|
||||
inline int gi(int pos = 0) const { return get<int,4>(pos); }
|
||||
inline uint32_t gui(int pos = 0) const { return get<uint32_t,4>(pos); }
|
||||
inline uint32_t gui32(int pos = 0) const { return get<uint32_t,4>(pos); }
|
||||
inline uint16_t gui16(int pos = 0) const { return get<uint16_t,2>(pos); }
|
||||
inline uint8_t gui8(int pos = 0) const { return get<uint8_t>(pos); }
|
||||
inline char gc(int pos = 0) const { return get<char>(pos); }
|
||||
inline unsigned char guc(int pos = 0) const { return get<unsigned char>(pos); }
|
||||
std::string gs(int pos, int len) const { return std::string(m_string.begin()+pos, m_string.begin()+pos+len); }
|
||||
// ------------------------------------------------------------------------
|
||||
double getAndRemoveDouble(int pos = 0) //!< BEWARE OF PRECISION
|
||||
{
|
||||
for (int i = 0; i < 8; i++)
|
||||
d_as_i.i[i] = m_string[pos + i];
|
||||
return d_as_i.d;
|
||||
remove(pos, 8);
|
||||
} // getAndRemoveDouble
|
||||
|
||||
double getDouble(int pos = 0) //!< BEWARE OF PRECISION
|
||||
{
|
||||
for (int i = 0; i < 8; i++)
|
||||
d_as_i.i[i] = m_string[pos+i];
|
||||
return d_as_i.d;
|
||||
}
|
||||
float getFloat(int pos = 0) //!< BEWARE OF PRECISION
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
f_as_i.i[i] = m_string[pos+i];
|
||||
return f_as_i.f;
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
/** Get and remove a 4 byte floating point value. */
|
||||
float getAndRemoveFloat(int pos = 0) //!< BEWARE OF PRECISION
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
f_as_i.i[i] = m_string[pos + i];
|
||||
return f_as_i.f;
|
||||
remove(pos, 4);
|
||||
} // getAndRemoveFloat
|
||||
|
||||
//! Functions to get while removing
|
||||
template<typename T, size_t n>
|
||||
T getAndRemove(int pos)
|
||||
{
|
||||
int a = n;
|
||||
T result = 0;
|
||||
while(a--)
|
||||
{
|
||||
result <<= 8; // offset one byte
|
||||
result += ((uint8_t)(m_string[pos+n-1-a]) & 0xff); // add the data
|
||||
}
|
||||
remove(pos,n);
|
||||
return result;
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
/** Removes a 8 bit unsigned int. */
|
||||
inline NetworkString& gui8(uint8_t* dst)
|
||||
{
|
||||
*dst = getAndRemoveUInt8(0);
|
||||
return *this;
|
||||
} // gui8
|
||||
|
||||
// Another function for n == 1 to surpress warnings in clang
|
||||
template<typename T>
|
||||
T getAndRemove(int pos)
|
||||
{
|
||||
T result = m_string[pos];
|
||||
remove(pos, 1);
|
||||
return result;
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns a 16 bit integer. */
|
||||
inline NetworkString& gui16(uint16_t* dst)
|
||||
{
|
||||
*dst = getAndRemoveUInt16(0);
|
||||
return *this;
|
||||
} // gui16
|
||||
|
||||
inline int getAndRemoveInt(int pos = 0) { return getAndRemove<int,4>(pos); }
|
||||
inline uint32_t getAndRemoveUInt(int pos = 0) { return getAndRemove<uint32_t,4>(pos); }
|
||||
inline uint32_t getAndRemoveUInt32(int pos = 0) { return getAndRemove<uint32_t,4>(pos); }
|
||||
inline uint16_t getAndRemoveUInt16(int pos = 0) { return getAndRemove<uint16_t,2>(pos); }
|
||||
inline uint8_t getAndRemoveUInt8(int pos = 0) { return getAndRemove<uint8_t>(pos); }
|
||||
inline char getAndRemoveChar(int pos = 0) { return getAndRemove<char>(pos); }
|
||||
inline unsigned char getAndRemoveUChar(int pos = 0) { return getAndRemove<unsigned char>(pos); }
|
||||
double getAndRemoveDouble(int pos = 0) //!< BEWARE OF PRECISION
|
||||
{
|
||||
for (int i = 0; i < 8; i++)
|
||||
d_as_i.i[i] = m_string[pos+i];
|
||||
return d_as_i.d;
|
||||
remove(pos, 8);
|
||||
}
|
||||
float getAndRemoveFloat(int pos = 0) //!< BEWARE OF PRECISION
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
f_as_i.i[i] = m_string[pos+i];
|
||||
return f_as_i.f;
|
||||
remove(pos, 4);
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns a 32 bit integer. */
|
||||
inline NetworkString& gui32(uint32_t* dst)
|
||||
{
|
||||
*dst = getAndRemoveUInt32(0);
|
||||
return *this;
|
||||
} // gui32
|
||||
|
||||
inline NetworkString& gui8(uint8_t* dst) { *dst = getAndRemoveUInt8(0); return *this; }
|
||||
inline NetworkString& gui16(uint16_t* dst) { *dst = getAndRemoveUInt16(0); return *this; }
|
||||
inline NetworkString& gui32(uint32_t* dst) { *dst = getAndRemoveUInt32(0); return *this; }
|
||||
inline NetworkString& gui(uint32_t* dst) { *dst = getAndRemoveUInt32(0); return *this; }
|
||||
inline NetworkString& gi(int* dst) { *dst = getAndRemoveInt(0); return *this; }
|
||||
inline NetworkString& gc(char* dst) { *dst = getAndRemoveChar(0); return *this; }
|
||||
inline NetworkString& guc(uchar* dst) { *dst = getAndRemoveUChar(0); return *this; }
|
||||
inline NetworkString& gd(double* dst) { *dst = getAndRemoveDouble(0); return *this; }
|
||||
inline NetworkString& gf(float* dst) { *dst = getAndRemoveFloat(0); return *this; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns a 32 bit integer. */
|
||||
inline NetworkString& gui(uint32_t* dst)
|
||||
{
|
||||
*dst = getAndRemoveUInt32(0);
|
||||
return *this;
|
||||
} // gui
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns 4 byte integer. */
|
||||
inline NetworkString& gi(int* dst)
|
||||
{
|
||||
*dst = getAndRemoveInt(0);
|
||||
return *this;
|
||||
} // gi
|
||||
|
||||
protected:
|
||||
std::vector<uint8_t> m_string;
|
||||
};
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns a single character. */
|
||||
inline NetworkString& gc(char* dst)
|
||||
{
|
||||
*dst = getAndRemoveChar(0);
|
||||
return *this;
|
||||
} // gc
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns an unsigned character. */
|
||||
inline NetworkString& guc(uchar* dst)
|
||||
{
|
||||
*dst = getAndRemoveUChar(0);
|
||||
return *this;
|
||||
} // guc
|
||||
|
||||
}; // class NetworkString
|
||||
|
||||
NetworkString operator+(NetworkString const& a, NetworkString const& b);
|
||||
|
||||
|
@ -18,8 +18,8 @@
|
||||
|
||||
#include "network/protocol_manager.hpp"
|
||||
|
||||
#include "network/protocol.hpp"
|
||||
#include "network/network_manager.hpp"
|
||||
#include "network/protocol.hpp"
|
||||
#include "utils/log.hpp"
|
||||
#include "utils/time.hpp"
|
||||
|
||||
@ -28,17 +28,25 @@
|
||||
#include <errno.h>
|
||||
#include <typeinfo>
|
||||
|
||||
void* protocolManagerUpdate(void* data)
|
||||
|
||||
ProtocolManager::ProtocolManager()
|
||||
{
|
||||
ProtocolManager* manager = static_cast<ProtocolManager*>(data);
|
||||
while(manager && !manager->exit())
|
||||
{
|
||||
manager->update();
|
||||
StkTime::sleep(2);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
void* protocolManagerAsynchronousUpdate(void* data)
|
||||
pthread_mutex_init(&m_asynchronous_protocols_mutex, NULL);
|
||||
pthread_mutex_init(&m_requests_mutex, NULL);
|
||||
pthread_mutex_init(&m_id_mutex, NULL);
|
||||
pthread_mutex_init(&m_exit_mutex, NULL);
|
||||
m_next_protocol_id = 0;
|
||||
|
||||
pthread_mutex_lock(&m_exit_mutex); // will let the update function run
|
||||
|
||||
m_asynchronous_update_thread = (pthread_t*)(malloc(sizeof(pthread_t)));
|
||||
pthread_create(m_asynchronous_update_thread, NULL,
|
||||
ProtocolManager::mainLoop, this);
|
||||
} // ProtocolManager
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void* ProtocolManager::mainLoop(void* data)
|
||||
{
|
||||
ProtocolManager* manager = static_cast<ProtocolManager*>(data);
|
||||
manager->m_asynchronous_thread_running = true;
|
||||
@ -49,78 +57,56 @@ void* protocolManagerAsynchronousUpdate(void* data)
|
||||
}
|
||||
manager->m_asynchronous_thread_running = false;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ProtocolManager::ProtocolManager()
|
||||
{
|
||||
pthread_mutex_init(&m_events_mutex, NULL);
|
||||
pthread_mutex_init(&m_protocols_mutex, NULL);
|
||||
pthread_mutex_init(&m_asynchronous_protocols_mutex, NULL);
|
||||
pthread_mutex_init(&m_requests_mutex, NULL);
|
||||
pthread_mutex_init(&m_id_mutex, NULL);
|
||||
pthread_mutex_init(&m_exit_mutex, NULL);
|
||||
m_next_protocol_id = 0;
|
||||
} // protocolManagerAsynchronousUpdate
|
||||
|
||||
|
||||
pthread_mutex_lock(&m_exit_mutex); // will let the update function run
|
||||
/// FIXME used on server because mainloop never running
|
||||
/*if (NetworkManager::getInstance()->isServer())
|
||||
{
|
||||
m_update_thread = (pthread_t*)(malloc(sizeof(pthread_t)));
|
||||
pthread_create(m_update_thread, NULL, protocolManagerUpdate, this);
|
||||
}*/
|
||||
// always run this one
|
||||
m_asynchronous_update_thread = (pthread_t*)(malloc(sizeof(pthread_t)));
|
||||
pthread_create(m_asynchronous_update_thread, NULL, protocolManagerAsynchronousUpdate, this);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
ProtocolManager::~ProtocolManager()
|
||||
{
|
||||
}
|
||||
|
||||
} // ~ProtocolManager
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void ProtocolManager::abort()
|
||||
{
|
||||
pthread_mutex_unlock(&m_exit_mutex); // will stop the update function
|
||||
pthread_join(*m_asynchronous_update_thread, NULL); // wait the thread to finish
|
||||
pthread_mutex_lock(&m_events_mutex);
|
||||
pthread_mutex_lock(&m_protocols_mutex);
|
||||
m_events_to_process.lock();
|
||||
m_protocols.lock();
|
||||
pthread_mutex_lock(&m_asynchronous_protocols_mutex);
|
||||
pthread_mutex_lock(&m_requests_mutex);
|
||||
pthread_mutex_lock(&m_id_mutex);
|
||||
for (unsigned int i = 0; i < m_protocols.size() ; i++)
|
||||
delete m_protocols[i].protocol;
|
||||
for (unsigned int i = 0; i < m_events_to_process.size() ; i++)
|
||||
delete m_events_to_process[i].event;
|
||||
m_protocols.clear();
|
||||
for (unsigned int i = 0; i < m_protocols.getData().size() ; i++)
|
||||
delete m_protocols.getData()[i].protocol;
|
||||
for (unsigned int i = 0; i < m_events_to_process.getData().size() ; i++)
|
||||
delete m_events_to_process.getData()[i].event;
|
||||
m_protocols.getData().clear();
|
||||
m_requests.clear();
|
||||
m_events_to_process.clear();
|
||||
pthread_mutex_unlock(&m_events_mutex);
|
||||
pthread_mutex_unlock(&m_protocols_mutex);
|
||||
m_events_to_process.getData().clear();
|
||||
m_events_to_process.unlock();
|
||||
m_protocols.unlock();
|
||||
pthread_mutex_unlock(&m_asynchronous_protocols_mutex);
|
||||
pthread_mutex_unlock(&m_requests_mutex);
|
||||
pthread_mutex_unlock(&m_id_mutex);
|
||||
|
||||
pthread_mutex_destroy(&m_events_mutex);
|
||||
pthread_mutex_destroy(&m_protocols_mutex);
|
||||
pthread_mutex_destroy(&m_asynchronous_protocols_mutex);
|
||||
pthread_mutex_destroy(&m_requests_mutex);
|
||||
pthread_mutex_destroy(&m_id_mutex);
|
||||
pthread_mutex_destroy(&m_exit_mutex);
|
||||
}
|
||||
} // abort
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void ProtocolManager::notifyEvent(Event* event)
|
||||
{
|
||||
pthread_mutex_lock(&m_events_mutex);
|
||||
m_events_to_process.lock();
|
||||
Event* event2 = new Event(*event);
|
||||
// register protocols that will receive this event
|
||||
std::vector<unsigned int> protocols_ids;
|
||||
PROTOCOL_TYPE searchedProtocol = PROTOCOL_NONE;
|
||||
PROTOCOL_TYPE searched_protocol = PROTOCOL_NONE;
|
||||
if (event2->type == EVENT_TYPE_MESSAGE)
|
||||
{
|
||||
if (event2->data().size() > 0)
|
||||
{
|
||||
searchedProtocol = (PROTOCOL_TYPE)(event2->data()[0]);
|
||||
searched_protocol = (PROTOCOL_TYPE)(event2->data()[0]);
|
||||
event2->removeFront(1);
|
||||
}
|
||||
else
|
||||
@ -130,21 +116,26 @@ void ProtocolManager::notifyEvent(Event* event)
|
||||
}
|
||||
if (event2->type == EVENT_TYPE_CONNECTED)
|
||||
{
|
||||
searchedProtocol = PROTOCOL_CONNECTION;
|
||||
searched_protocol = PROTOCOL_CONNECTION;
|
||||
}
|
||||
Log::verbose("ProtocolManager", "Received event for protocols of type %d", searchedProtocol);
|
||||
pthread_mutex_lock(&m_protocols_mutex);
|
||||
for (unsigned int i = 0; i < m_protocols.size() ; i++)
|
||||
Log::verbose("ProtocolManager", "Received event for protocols of type %d",
|
||||
searched_protocol);
|
||||
m_protocols.lock();
|
||||
for (unsigned int i = 0; i < m_protocols.getData().size() ; i++)
|
||||
{
|
||||
if (m_protocols[i].protocol->getProtocolType() == searchedProtocol || event2->type == EVENT_TYPE_DISCONNECTED) // pass data to protocols even when paused
|
||||
// Pass data to protocols even when paused
|
||||
if (m_protocols.getData()[i].protocol->getProtocolType() == searched_protocol ||
|
||||
event2->type == EVENT_TYPE_DISCONNECTED)
|
||||
{
|
||||
protocols_ids.push_back(m_protocols[i].id);
|
||||
protocols_ids.push_back(m_protocols.getData()[i].id);
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&m_protocols_mutex);
|
||||
if (searchedProtocol == PROTOCOL_NONE) // no protocol was aimed, show the msg to debug
|
||||
m_protocols.unlock();
|
||||
// no protocol was aimed, show the msg to debug
|
||||
if (searched_protocol == PROTOCOL_NONE)
|
||||
{
|
||||
Log::debug("ProtocolManager", "NO PROTOCOL : Message is \"%s\"", event2->data().std_string().c_str());
|
||||
Log::debug("ProtocolManager", "NO PROTOCOL : Message is \"%s\"",
|
||||
event2->data().std_string().c_str());
|
||||
}
|
||||
|
||||
if (protocols_ids.size() != 0)
|
||||
@ -153,36 +144,47 @@ void ProtocolManager::notifyEvent(Event* event)
|
||||
epi.arrival_time = (double)StkTime::getTimeSinceEpoch();
|
||||
epi.event = event2;
|
||||
epi.protocols_ids = protocols_ids;
|
||||
m_events_to_process.push_back(epi); // add the event to the queue
|
||||
m_events_to_process.getData().push_back(epi); // add the event to the queue
|
||||
}
|
||||
else
|
||||
Log::warn("ProtocolManager", "Received an event for %d that has no destination protocol.", searchedProtocol);
|
||||
pthread_mutex_unlock(&m_events_mutex);
|
||||
}
|
||||
Log::warn("ProtocolManager",
|
||||
"Received an event for %d that has no destination protocol.",
|
||||
searched_protocol);
|
||||
m_events_to_process.lock();
|
||||
} // notifyEvent
|
||||
|
||||
void ProtocolManager::sendMessage(Protocol* sender, const NetworkString& message, bool reliable)
|
||||
// ----------------------------------------------------------------------------
|
||||
void ProtocolManager::sendMessage(Protocol* sender, const NetworkString& message,
|
||||
bool reliable)
|
||||
{
|
||||
NetworkString newMessage;
|
||||
NetworkString newMessage(1+message.size());
|
||||
newMessage.ai8(sender->getProtocolType()); // add one byte to add protocol type
|
||||
newMessage += message;
|
||||
NetworkManager::getInstance()->sendPacket(newMessage, reliable);
|
||||
}
|
||||
} // sendMessage
|
||||
|
||||
void ProtocolManager::sendMessage(Protocol* sender, STKPeer* peer, const NetworkString& message, bool reliable)
|
||||
// ----------------------------------------------------------------------------
|
||||
void ProtocolManager::sendMessage(Protocol* sender, STKPeer* peer,
|
||||
const NetworkString& message, bool reliable)
|
||||
{
|
||||
NetworkString newMessage;
|
||||
NetworkString newMessage(1+message.size());
|
||||
newMessage.ai8(sender->getProtocolType()); // add one byte to add protocol type
|
||||
newMessage += message;
|
||||
NetworkManager::getInstance()->sendPacket(peer, newMessage, reliable);
|
||||
}
|
||||
void ProtocolManager::sendMessageExcept(Protocol* sender, STKPeer* peer, const NetworkString& message, bool reliable)
|
||||
} // sendMessage
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void ProtocolManager::sendMessageExcept(Protocol* sender, STKPeer* peer,
|
||||
const NetworkString& message,
|
||||
bool reliable)
|
||||
{
|
||||
NetworkString newMessage;
|
||||
NetworkString newMessage(1+message.size());
|
||||
newMessage.ai8(sender->getProtocolType()); // add one byte to add protocol type
|
||||
newMessage += message;
|
||||
NetworkManager::getInstance()->sendPacketExcept(peer, newMessage, reliable);
|
||||
}
|
||||
} // sendMessageExcept
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
uint32_t ProtocolManager::requestStart(Protocol* protocol)
|
||||
{
|
||||
// create the request
|
||||
@ -199,8 +201,9 @@ uint32_t ProtocolManager::requestStart(Protocol* protocol)
|
||||
pthread_mutex_unlock(&m_requests_mutex);
|
||||
|
||||
return info.id;
|
||||
}
|
||||
} // requestStart
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void ProtocolManager::requestStop(Protocol* protocol)
|
||||
{
|
||||
if (!protocol)
|
||||
@ -213,8 +216,9 @@ void ProtocolManager::requestStop(Protocol* protocol)
|
||||
pthread_mutex_lock(&m_requests_mutex);
|
||||
m_requests.push_back(req);
|
||||
pthread_mutex_unlock(&m_requests_mutex);
|
||||
}
|
||||
} // requestStop
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void ProtocolManager::requestPause(Protocol* protocol)
|
||||
{
|
||||
if (!protocol)
|
||||
@ -227,8 +231,9 @@ void ProtocolManager::requestPause(Protocol* protocol)
|
||||
pthread_mutex_lock(&m_requests_mutex);
|
||||
m_requests.push_back(req);
|
||||
pthread_mutex_unlock(&m_requests_mutex);
|
||||
}
|
||||
} // requestPause
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void ProtocolManager::requestUnpause(Protocol* protocol)
|
||||
{
|
||||
if (!protocol)
|
||||
@ -241,8 +246,9 @@ void ProtocolManager::requestUnpause(Protocol* protocol)
|
||||
pthread_mutex_lock(&m_requests_mutex);
|
||||
m_requests.push_back(req);
|
||||
pthread_mutex_unlock(&m_requests_mutex);
|
||||
}
|
||||
} // requestUnpause
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void ProtocolManager::requestTerminate(Protocol* protocol)
|
||||
{
|
||||
if (!protocol)
|
||||
@ -264,86 +270,111 @@ void ProtocolManager::requestTerminate(Protocol* protocol)
|
||||
}
|
||||
m_requests.push_back(req);
|
||||
pthread_mutex_unlock(&m_requests_mutex);
|
||||
}
|
||||
} // requestTerminate
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void ProtocolManager::startProtocol(ProtocolInfo protocol)
|
||||
{
|
||||
// add the protocol to the protocol vector so that it's updated
|
||||
pthread_mutex_lock(&m_protocols_mutex);
|
||||
m_protocols.lock();
|
||||
pthread_mutex_lock(&m_asynchronous_protocols_mutex);
|
||||
Log::info("ProtocolManager", "A %s protocol with id=%u has been started. There are %ld protocols running.", typeid(*protocol.protocol).name(), protocol.id, m_protocols.size()+1);
|
||||
m_protocols.push_back(protocol);
|
||||
Log::info("ProtocolManager",
|
||||
"A %s protocol with id=%u has been started. There are %ld protocols running.",
|
||||
typeid(*protocol.protocol).name(), protocol.id,
|
||||
m_protocols.getData().size()+1);
|
||||
m_protocols.getData().push_back(protocol);
|
||||
// setup the protocol and notify it that it's started
|
||||
protocol.protocol->setListener(this);
|
||||
protocol.protocol->setup();
|
||||
pthread_mutex_unlock(&m_protocols_mutex);
|
||||
m_protocols.unlock();
|
||||
pthread_mutex_unlock(&m_asynchronous_protocols_mutex);
|
||||
}
|
||||
} // startProtocol
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void ProtocolManager::stopProtocol(ProtocolInfo protocol)
|
||||
{
|
||||
} // stopProtocol
|
||||
|
||||
}
|
||||
// ----------------------------------------------------------------------------
|
||||
void ProtocolManager::pauseProtocol(ProtocolInfo protocol)
|
||||
{
|
||||
for (unsigned int i = 0; i < m_protocols.size(); i++)
|
||||
// FIXME Does this need to be locked?
|
||||
for (unsigned int i = 0; i < m_protocols.getData().size(); i++)
|
||||
{
|
||||
if (m_protocols[i].protocol == protocol.protocol && m_protocols[i].state == PROTOCOL_STATE_RUNNING)
|
||||
ProtocolInfo &p = m_protocols.getData()[i];
|
||||
if (p.protocol == protocol.protocol &&
|
||||
p.state == PROTOCOL_STATE_RUNNING)
|
||||
{
|
||||
m_protocols[i].state = PROTOCOL_STATE_PAUSED;
|
||||
m_protocols[i].protocol->pause();
|
||||
p.state = PROTOCOL_STATE_PAUSED;
|
||||
p.protocol->pause();
|
||||
}
|
||||
}
|
||||
}
|
||||
} // pauseProtocol
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void ProtocolManager::unpauseProtocol(ProtocolInfo protocol)
|
||||
{
|
||||
for (unsigned int i = 0; i < m_protocols.size(); i++)
|
||||
// FIXME Does this need to be locked??
|
||||
for (unsigned int i = 0; i < m_protocols.getData().size(); i++)
|
||||
{
|
||||
if (m_protocols[i].protocol == protocol.protocol && m_protocols[i].state == PROTOCOL_STATE_PAUSED)
|
||||
ProtocolInfo &p = m_protocols.getData()[i];
|
||||
if (p.protocol == protocol.protocol &&
|
||||
p.state == PROTOCOL_STATE_PAUSED)
|
||||
{
|
||||
m_protocols[i].state = PROTOCOL_STATE_RUNNING;
|
||||
m_protocols[i].protocol->unpause();
|
||||
p.state = PROTOCOL_STATE_RUNNING;
|
||||
p.protocol->unpause();
|
||||
}
|
||||
}
|
||||
}
|
||||
} // unpauseProtocol
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void ProtocolManager::protocolTerminated(ProtocolInfo protocol)
|
||||
{
|
||||
pthread_mutex_lock(&m_protocols_mutex); // be sure that noone accesses the protocols vector while we erase a protocol
|
||||
// Be sure that noone accesses the protocols vector while we erase a protocol
|
||||
m_protocols.lock();
|
||||
pthread_mutex_lock(&m_asynchronous_protocols_mutex);
|
||||
int offset = 0;
|
||||
std::string protocol_type = typeid(*protocol.protocol).name();
|
||||
for (unsigned int i = 0; i < m_protocols.size(); i++)
|
||||
for (unsigned int i = 0; i < m_protocols.getData().size(); i++)
|
||||
{
|
||||
if (m_protocols[i-offset].protocol == protocol.protocol)
|
||||
if (m_protocols.getData()[i-offset].protocol == protocol.protocol)
|
||||
{
|
||||
delete m_protocols[i].protocol;
|
||||
m_protocols.erase(m_protocols.begin()+(i-offset), m_protocols.begin()+(i-offset)+1);
|
||||
delete m_protocols.getData()[i].protocol;
|
||||
m_protocols.getData().erase(m_protocols.getData().begin()+(i-offset),
|
||||
m_protocols.getData().begin()+(i-offset)+1);
|
||||
offset++;
|
||||
}
|
||||
}
|
||||
Log::info("ProtocolManager", "A %s protocol has been terminated. There are %ld protocols running.", protocol_type.c_str(), m_protocols.size());
|
||||
Log::info("ProtocolManager",
|
||||
"A %s protocol has been terminated. There are %ld protocols running.",
|
||||
protocol_type.c_str(), m_protocols.getData().size());
|
||||
pthread_mutex_unlock(&m_asynchronous_protocols_mutex);
|
||||
pthread_mutex_unlock(&m_protocols_mutex);
|
||||
}
|
||||
m_protocols.unlock();
|
||||
} // protocolTerminated
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
bool ProtocolManager::propagateEvent(EventProcessingInfo* event, bool synchronous)
|
||||
{
|
||||
int index = 0;
|
||||
for (unsigned int i = 0; i < m_protocols.size(); i++)
|
||||
for (unsigned int i = 0; i < m_protocols.getData().size(); i++)
|
||||
{
|
||||
if (event->protocols_ids[index] == m_protocols[i].id)
|
||||
if (event->protocols_ids[index] == m_protocols.getData()[i].id)
|
||||
{
|
||||
bool result = false;
|
||||
if (synchronous)
|
||||
result = m_protocols[i].protocol->notifyEvent(event->event);
|
||||
result = m_protocols.getData()[i].protocol
|
||||
->notifyEvent(event->event);
|
||||
else
|
||||
result = m_protocols[i].protocol->notifyEventAsynchronous(event->event);
|
||||
result = m_protocols.getData()[i].protocol
|
||||
->notifyEventAsynchronous(event->event);
|
||||
if (result)
|
||||
event->protocols_ids.pop_back();
|
||||
else
|
||||
index++;
|
||||
}
|
||||
}
|
||||
if (event->protocols_ids.size() == 0 || (StkTime::getTimeSinceEpoch()-event->arrival_time) >= TIME_TO_KEEP_EVENTS)
|
||||
if (event->protocols_ids.size() == 0 ||
|
||||
(StkTime::getTimeSinceEpoch()-event->arrival_time) >= TIME_TO_KEEP_EVENTS)
|
||||
{
|
||||
// because we made a copy of the event
|
||||
delete event->event->peer; // no more need of that
|
||||
@ -351,57 +382,64 @@ bool ProtocolManager::propagateEvent(EventProcessingInfo* event, bool synchronou
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
} // propagateEvent
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void ProtocolManager::update()
|
||||
{
|
||||
// before updating, notice protocols that they have received events
|
||||
pthread_mutex_lock(&m_events_mutex); // secure threads
|
||||
int size = (int)m_events_to_process.size();
|
||||
m_events_to_process.lock();
|
||||
int size = (int)m_events_to_process.getData().size();
|
||||
int offset = 0;
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
bool result = propagateEvent(&m_events_to_process[i+offset], true);
|
||||
bool result = propagateEvent(&m_events_to_process.getData()[i+offset], true);
|
||||
if (result)
|
||||
{
|
||||
m_events_to_process.erase(m_events_to_process.begin()+i+offset,m_events_to_process.begin()+i+offset+1);
|
||||
m_events_to_process.getData()
|
||||
.erase(m_events_to_process.getData().begin()+i+offset,
|
||||
m_events_to_process.getData().begin()+i+offset+1);
|
||||
offset --;
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&m_events_mutex); // release the mutex
|
||||
m_events_to_process.unlock();
|
||||
// now update all protocols
|
||||
pthread_mutex_lock(&m_protocols_mutex);
|
||||
for (unsigned int i = 0; i < m_protocols.size(); i++)
|
||||
m_protocols.lock();
|
||||
for (unsigned int i = 0; i < m_protocols.getData().size(); i++)
|
||||
{
|
||||
if (m_protocols[i].state == PROTOCOL_STATE_RUNNING)
|
||||
m_protocols[i].protocol->update();
|
||||
if (m_protocols.getData()[i].state == PROTOCOL_STATE_RUNNING)
|
||||
m_protocols.getData()[i].protocol->update();
|
||||
}
|
||||
pthread_mutex_unlock(&m_protocols_mutex);
|
||||
}
|
||||
m_protocols.unlock();
|
||||
} // update
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void ProtocolManager::asynchronousUpdate()
|
||||
{
|
||||
// before updating, notice protocols that they have received information
|
||||
pthread_mutex_lock(&m_events_mutex); // secure threads
|
||||
int size = (int)m_events_to_process.size();
|
||||
m_events_to_process.lock();
|
||||
int size = (int)m_events_to_process.getData().size();
|
||||
int offset = 0;
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
bool result = propagateEvent(&m_events_to_process[i+offset], false);
|
||||
bool result = propagateEvent(&m_events_to_process.getData()[i+offset], false);
|
||||
if (result)
|
||||
{
|
||||
m_events_to_process.erase(m_events_to_process.begin()+i+offset,m_events_to_process.begin()+i+offset+1);
|
||||
m_events_to_process.getData()
|
||||
.erase(m_events_to_process.getData().begin()+i+offset,
|
||||
m_events_to_process.getData().begin()+i+offset+1);
|
||||
offset --;
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&m_events_mutex); // release the mutex
|
||||
m_events_to_process.unlock();
|
||||
|
||||
// now update all protocols that need to be updated in asynchronous mode
|
||||
pthread_mutex_lock(&m_asynchronous_protocols_mutex);
|
||||
for (unsigned int i = 0; i < m_protocols.size(); i++)
|
||||
// FIXME: does m_protocols need to be locked???
|
||||
for (unsigned int i = 0; i < m_protocols.getData().size(); i++)
|
||||
{
|
||||
if (m_protocols[i].state == PROTOCOL_STATE_RUNNING)
|
||||
m_protocols[i].protocol->asynchronousUpdate();
|
||||
if (m_protocols.getData()[i].state == PROTOCOL_STATE_RUNNING)
|
||||
m_protocols.getData()[i].protocol->asynchronousUpdate();
|
||||
}
|
||||
pthread_mutex_unlock(&m_asynchronous_protocols_mutex);
|
||||
|
||||
@ -431,79 +469,90 @@ void ProtocolManager::asynchronousUpdate()
|
||||
}
|
||||
m_requests.clear();
|
||||
pthread_mutex_unlock(&m_requests_mutex);
|
||||
}
|
||||
|
||||
int ProtocolManager::runningProtocolsCount()
|
||||
{
|
||||
return (int)m_protocols.size();
|
||||
}
|
||||
} // asynchronousUpdate
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
PROTOCOL_STATE ProtocolManager::getProtocolState(uint32_t id)
|
||||
{
|
||||
for (unsigned int i = 0; i < m_protocols.size(); i++)
|
||||
//FIXME that actually need a lock, but it also can be called from
|
||||
// a locked section anyway
|
||||
for (unsigned int i = 0; i < m_protocols.getData().size(); i++)
|
||||
{
|
||||
if (m_protocols[i].id == id) // we know a protocol with that id
|
||||
return m_protocols[i].state; // return its state
|
||||
if (m_protocols.getData()[i].id == id) // we know a protocol with that id
|
||||
return m_protocols.getData()[i].state;
|
||||
}
|
||||
// the protocol isn't running right now
|
||||
for (unsigned int i = 0; i < m_requests.size(); i++)
|
||||
{
|
||||
if (m_requests[i].protocol_info.id == id) // the protocol is going to be started
|
||||
// the protocol is going to be started
|
||||
if (m_requests[i].protocol_info.id == id)
|
||||
return PROTOCOL_STATE_RUNNING; // we can say it's running
|
||||
}
|
||||
return PROTOCOL_STATE_TERMINATED; // else, it's already finished
|
||||
}
|
||||
} // getProtocolState
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
PROTOCOL_STATE ProtocolManager::getProtocolState(Protocol* protocol)
|
||||
{
|
||||
for (unsigned int i = 0; i < m_protocols.size(); i++)
|
||||
// FIXME Does this need to be locked?
|
||||
for (unsigned int i = 0; i < m_protocols.getData().size(); i++)
|
||||
{
|
||||
if (m_protocols[i].protocol == protocol) // the protocol is known
|
||||
return m_protocols[i].state; // return its state
|
||||
if (m_protocols.getData()[i].protocol == protocol) // the protocol is known
|
||||
return m_protocols.getData()[i].state;
|
||||
}
|
||||
for (unsigned int i = 0; i < m_requests.size(); i++)
|
||||
{
|
||||
if (m_requests[i].protocol_info.protocol == protocol) // the protocol is going to be started
|
||||
// the protocol is going to be started
|
||||
if (m_requests[i].protocol_info.protocol == protocol)
|
||||
return PROTOCOL_STATE_RUNNING; // we can say it's running
|
||||
}
|
||||
return PROTOCOL_STATE_TERMINATED; // we don't know this protocol at all, it's finished
|
||||
}
|
||||
// we don't know this protocol at all, it's finished
|
||||
return PROTOCOL_STATE_TERMINATED;
|
||||
} // getProtocolState
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
uint32_t ProtocolManager::getProtocolID(Protocol* protocol)
|
||||
{
|
||||
for (unsigned int i = 0; i < m_protocols.size(); i++)
|
||||
// FIXME: Does this need to be locked?
|
||||
for (unsigned int i = 0; i < m_protocols.getData().size(); i++)
|
||||
{
|
||||
if (m_protocols[i].protocol == protocol)
|
||||
return m_protocols[i].id;
|
||||
if (m_protocols.getData()[i].protocol == protocol)
|
||||
return m_protocols.getData()[i].id;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
} // getProtocolID
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
Protocol* ProtocolManager::getProtocol(uint32_t id)
|
||||
{
|
||||
for (unsigned int i = 0; i < m_protocols.size(); i++)
|
||||
// FIXME: does m_protocols need to be locked??
|
||||
for (unsigned int i = 0; i < m_protocols.getData().size(); i++)
|
||||
{
|
||||
if (m_protocols[i].id == id)
|
||||
return m_protocols[i].protocol;
|
||||
if (m_protocols.getData()[i].id == id)
|
||||
return m_protocols.getData()[i].protocol;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
} // getProtocol
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
Protocol* ProtocolManager::getProtocol(PROTOCOL_TYPE type)
|
||||
{
|
||||
for (unsigned int i = 0; i < m_protocols.size(); i++)
|
||||
// FIXME: Does m_protocols need to be locked?
|
||||
for (unsigned int i = 0; i < m_protocols.getData().size(); i++)
|
||||
{
|
||||
if (m_protocols[i].protocol->getProtocolType() == type)
|
||||
return m_protocols[i].protocol;
|
||||
if (m_protocols.getData()[i].protocol->getProtocolType() == type)
|
||||
return m_protocols.getData()[i].protocol;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
} // getProtocol
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
bool ProtocolManager::isServer()
|
||||
{
|
||||
return NetworkManager::getInstance()->isServer();
|
||||
}
|
||||
} // isServer
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
int ProtocolManager::exit()
|
||||
{
|
||||
switch(pthread_mutex_trylock(&m_exit_mutex)) {
|
||||
@ -514,14 +563,15 @@ int ProtocolManager::exit()
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
} // exit
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void ProtocolManager::assignProtocolId(ProtocolInfo* protocol_info)
|
||||
{
|
||||
pthread_mutex_lock(&m_id_mutex);
|
||||
protocol_info->id = m_next_protocol_id;
|
||||
m_next_protocol_id++;
|
||||
pthread_mutex_unlock(&m_id_mutex);
|
||||
}
|
||||
} // assignProtocolId
|
||||
|
||||
|
||||
|
@ -26,7 +26,9 @@
|
||||
#include "network/event.hpp"
|
||||
#include "network/network_string.hpp"
|
||||
#include "network/protocol.hpp"
|
||||
#include "utils/no_copy.hpp"
|
||||
#include "utils/singleton.hpp"
|
||||
#include "utils/synchronised.hpp"
|
||||
#include "utils/types.hpp"
|
||||
|
||||
#include <vector>
|
||||
@ -102,10 +104,11 @@ typedef struct EventProcessingInfo
|
||||
* frames per second. Then, the management of protocols is thread-safe: any
|
||||
* object can start/pause/stop protocols whithout problems.
|
||||
*/
|
||||
class ProtocolManager : public AbstractSingleton<ProtocolManager>
|
||||
class ProtocolManager : public AbstractSingleton<ProtocolManager>,
|
||||
public NoCopy
|
||||
{
|
||||
friend class AbstractSingleton<ProtocolManager>;
|
||||
friend void* protocolManagerAsynchronousUpdate(void* data);
|
||||
static void* mainLoop(void *data);
|
||||
public:
|
||||
|
||||
/*! \brief Stops the protocol manager. */
|
||||
@ -189,11 +192,6 @@ class ProtocolManager : public AbstractSingleton<ProtocolManager>
|
||||
*/
|
||||
virtual void asynchronousUpdate();
|
||||
|
||||
/*!
|
||||
* \brief Get the number of protocols running.
|
||||
* \return The number of protocols that are actually running.
|
||||
*/
|
||||
virtual int runningProtocolsCount();
|
||||
/*!
|
||||
* \brief Get the state of a protocol using its id.
|
||||
* \param id : The id of the protocol you seek the state.
|
||||
@ -287,19 +285,15 @@ class ProtocolManager : public AbstractSingleton<ProtocolManager>
|
||||
bool propagateEvent(EventProcessingInfo* event, bool synchronous);
|
||||
|
||||
// protected members
|
||||
/*!
|
||||
* \brief Contains the running protocols.
|
||||
* This stores the protocols that are either running or paused, their
|
||||
* state and their unique id.
|
||||
*/
|
||||
std::vector<ProtocolInfo> m_protocols;
|
||||
/*!
|
||||
* \brief Contains the network events to pass to protocols.
|
||||
*/
|
||||
std::vector<EventProcessingInfo> m_events_to_process;
|
||||
/*!
|
||||
* \brief Contains the requests to start/stop etc... protocols.
|
||||
*/
|
||||
/** Contains the running protocols.
|
||||
* This stores the protocols that are either running or paused, their
|
||||
* state and their unique id. */
|
||||
Synchronised<std::vector<ProtocolInfo> >m_protocols;
|
||||
|
||||
/** Contains the network events to pass to protocols. */
|
||||
Synchronised<std::vector<EventProcessingInfo> > m_events_to_process;
|
||||
|
||||
/** Contains the requests to start/stop etc... protocols. */
|
||||
std::vector<ProtocolRequest> m_requests;
|
||||
/*! \brief The next id to assign to a protocol.
|
||||
* This value is incremented by 1 each time a protocol is started.
|
||||
@ -309,10 +303,6 @@ class ProtocolManager : public AbstractSingleton<ProtocolManager>
|
||||
uint32_t m_next_protocol_id;
|
||||
|
||||
// mutexes:
|
||||
/*! Used to ensure that the event queue is used thread-safely. */
|
||||
pthread_mutex_t m_events_mutex;
|
||||
/*! Used to ensure that the protocol vector is used thread-safely. */
|
||||
pthread_mutex_t m_protocols_mutex;
|
||||
/*! Used to ensure that the protocol vector is used thread-safely. */
|
||||
pthread_mutex_t m_asynchronous_protocols_mutex;
|
||||
/*! Used to ensure that the request vector is used thread-safely. */
|
||||
|
@ -29,17 +29,17 @@
|
||||
#include "utils/log.hpp"
|
||||
|
||||
ClientLobbyRoomProtocol::ClientLobbyRoomProtocol(const TransportAddress& server_address)
|
||||
: LobbyRoomProtocol(NULL)
|
||||
: LobbyRoomProtocol(NULL)
|
||||
{
|
||||
m_server_address = server_address;
|
||||
m_server_address.copy(server_address);
|
||||
m_server = NULL;
|
||||
}
|
||||
} // ClientLobbyRoomProtocol
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
ClientLobbyRoomProtocol::~ClientLobbyRoomProtocol()
|
||||
{
|
||||
}
|
||||
} // ClientLobbyRoomProtocol
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
@ -48,86 +48,85 @@ void ClientLobbyRoomProtocol::setup()
|
||||
m_setup = NetworkManager::getInstance()->setupNewGame(); // create a new setup
|
||||
m_setup->getRaceConfig()->setPlayerCount(16); //FIXME : this has to be changed when logging into the server
|
||||
m_state = NONE;
|
||||
}
|
||||
} // setup
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void ClientLobbyRoomProtocol::requestKartSelection(std::string kart_name)
|
||||
{
|
||||
NetworkString request;
|
||||
NetworkString request(6+1+kart_name.size());
|
||||
// 0x02 : kart selection request, size_token (4), token, size kart name, kart name
|
||||
request.ai8(0x02).ai8(4).ai32(m_server->getClientServerToken()).ai8(kart_name.size()).as(kart_name);
|
||||
request.ai8(0x02).ai8(4).ai32(m_server->getClientServerToken()).add(kart_name);
|
||||
m_listener->sendMessage(this, request, true);
|
||||
}
|
||||
} // requestKartSelection
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void ClientLobbyRoomProtocol::voteMajor(uint8_t major)
|
||||
{
|
||||
NetworkString request;
|
||||
NetworkString request(8);
|
||||
// 0xc0 : major vote, size_token (4), token, size major(1),major
|
||||
request.ai8(0xc0).ai8(4).ai32(m_server->getClientServerToken()).ai8(1).ai8(major);
|
||||
m_listener->sendMessage(this, request, true);
|
||||
}
|
||||
} // voteMajor
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void ClientLobbyRoomProtocol::voteRaceCount(uint8_t count)
|
||||
{
|
||||
NetworkString request;
|
||||
NetworkString request(8);
|
||||
// 0xc0 : race count vote, size_token (4), token, size race count(1), count
|
||||
request.ai8(0xc1).ai8(4).ai32(m_server->getClientServerToken()).ai8(1).ai8(count);
|
||||
m_listener->sendMessage(this, request, true);
|
||||
}
|
||||
} // voteRaceCount
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void ClientLobbyRoomProtocol::voteMinor(uint8_t minor)
|
||||
{
|
||||
NetworkString request;
|
||||
NetworkString request(8);
|
||||
// 0xc0 : minor vote, size_token (4), token, size minor(1),minor
|
||||
request.ai8(0xc2).ai8(4).ai32(m_server->getClientServerToken()).ai8(1).ai8(minor);
|
||||
m_listener->sendMessage(this, request, true);
|
||||
}
|
||||
} // voteMinor
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void ClientLobbyRoomProtocol::voteTrack(std::string track, uint8_t track_nb)
|
||||
{
|
||||
NetworkString request;
|
||||
NetworkString request(8+1+track.size());
|
||||
// 0xc0 : major vote, size_token (4), token, size track, track, size #track, #track
|
||||
request.ai8(0xc3).ai8(4).ai32(m_server->getClientServerToken()).ai8(track.size()).as(track).ai8(1).ai8(track_nb);
|
||||
request.ai8(0xc3).ai8(4).ai32(m_server->getClientServerToken()).add(track).ai8(1).ai8(track_nb);
|
||||
m_listener->sendMessage(this, request, true);
|
||||
}
|
||||
} // voteTrack
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void ClientLobbyRoomProtocol::voteReversed(bool reversed, uint8_t track_nb)
|
||||
{
|
||||
NetworkString request;
|
||||
NetworkString request(9);
|
||||
// 0xc0 : major vote, size_token (4), token, size reversed(1),reversed, size #track, #track
|
||||
request.ai8(0xc4).ai8(4).ai32(m_server->getClientServerToken()).ai8(1).ai8(reversed).ai8(1).ai8(track_nb);
|
||||
m_listener->sendMessage(this, request, true);
|
||||
}
|
||||
} // voteReversed
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void ClientLobbyRoomProtocol::voteLaps(uint8_t laps, uint8_t track_nb)
|
||||
{
|
||||
NetworkString request;
|
||||
NetworkString request(10);
|
||||
// 0xc0 : major vote, size_token (4), token, size laps(1),laps, size #track, #track
|
||||
request.ai8(0xc5).ai8(4).ai32(m_server->getClientServerToken()).ai8(1).ai8(laps).ai8(1).ai8(track_nb);
|
||||
m_listener->sendMessage(this, request, true);
|
||||
}
|
||||
} // voteLaps
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void ClientLobbyRoomProtocol::leave()
|
||||
{
|
||||
m_server->disconnect();
|
||||
m_server_address.ip = 0;
|
||||
m_server_address.port = 0;
|
||||
}
|
||||
m_server_address.clear();
|
||||
} // leave
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
@ -153,7 +152,7 @@ bool ClientLobbyRoomProtocol::notifyEvent(Event* event)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
} // notifyEvent
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
@ -215,7 +214,7 @@ bool ClientLobbyRoomProtocol::notifyEventAsynchronous(Event* event)
|
||||
return true;
|
||||
} // disconnection
|
||||
return false;
|
||||
}
|
||||
} // notifyEventAsynchronous
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
@ -231,7 +230,7 @@ void ClientLobbyRoomProtocol::update()
|
||||
break;
|
||||
case LINKED:
|
||||
{
|
||||
NetworkString ns;
|
||||
NetworkString ns(6);
|
||||
// 1 (connection request), 4 (size of id), global id
|
||||
ns.ai8(1).ai8(4).ai32(PlayerManager::getCurrentOnlineId());
|
||||
m_listener->sendMessage(this, ns);
|
||||
@ -269,7 +268,7 @@ void ClientLobbyRoomProtocol::update()
|
||||
case EXITING:
|
||||
break;
|
||||
}
|
||||
}
|
||||
} // update
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
@ -312,7 +311,7 @@ void ClientLobbyRoomProtocol::newPlayer(Event* event)
|
||||
{
|
||||
Log::error("ClientLobbyRoomProtocol", "One of the player notified in the list is myself.");
|
||||
}
|
||||
}
|
||||
} // newPlayer
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
@ -343,7 +342,7 @@ void ClientLobbyRoomProtocol::disconnectedPlayer(Event* event)
|
||||
{
|
||||
Log::error("ClientLobbyRoomProtocol", "The disconnected peer wasn't known.");
|
||||
}
|
||||
}
|
||||
} // disconnectedPlayer
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
@ -412,7 +411,7 @@ void ClientLobbyRoomProtocol::connectionAccepted(Event* event)
|
||||
}
|
||||
else
|
||||
Log::info("ClientLobbyRoomProtocol", "Failure during the connection acceptation process.");
|
||||
}
|
||||
} // connectionAccepted
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
@ -447,7 +446,7 @@ void ClientLobbyRoomProtocol::connectionRefused(Event* event)
|
||||
Log::info("ClientLobbyRoomProtocol", "Connection refused.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
} // connectionRefused
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
@ -482,7 +481,7 @@ void ClientLobbyRoomProtocol::kartSelectionRefused(Event* event)
|
||||
Log::info("ClientLobbyRoomProtocol", "Kart selection refused.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
} // kartSelectionRefused
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
@ -518,7 +517,7 @@ void ClientLobbyRoomProtocol::kartSelectionUpdate(Event* event)
|
||||
}
|
||||
m_setup->setPlayerKart(player_id, kart_name);
|
||||
NetworkKartSelectionScreen::getInstance()->playerSelected(player_id, kart_name);
|
||||
}
|
||||
} // kartSelectionUpdate
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
@ -551,7 +550,7 @@ void ClientLobbyRoomProtocol::startGame(Event* event)
|
||||
else
|
||||
Log::error("ClientLobbyRoomProtocol", "Bad token when starting game");
|
||||
|
||||
}
|
||||
} // startGame
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
@ -583,7 +582,7 @@ void ClientLobbyRoomProtocol::startSelection(Event* event)
|
||||
else
|
||||
Log::error("ClientLobbyRoomProtocol", "Bad token");
|
||||
|
||||
}
|
||||
} // startSelection
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
@ -659,7 +658,7 @@ void ClientLobbyRoomProtocol::raceFinished(Event* event)
|
||||
ranked_world->endSetKartPositions();
|
||||
m_state = RACE_FINISHED;
|
||||
ranked_world->terminateRace();
|
||||
}
|
||||
} // raceFinished
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
@ -683,9 +682,9 @@ void ClientLobbyRoomProtocol::playerMajorVote(Event* event)
|
||||
if (!isByteCorrect(event, 7, 1))
|
||||
return;
|
||||
m_setup->getRaceConfig()->setPlayerMajorVote(data[6], data[8]);
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
} // playerMajorVote
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/*! \brief Called when a player votes for the number of races in a GP.
|
||||
* \param event : Event providing the information.
|
||||
*
|
||||
@ -706,9 +705,9 @@ void ClientLobbyRoomProtocol::playerRaceCountVote(Event* event)
|
||||
if (!isByteCorrect(event, 7, 1))
|
||||
return;
|
||||
m_setup->getRaceConfig()->setPlayerRaceCountVote(data[6], data[8]);
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
} // playerRaceCountVote
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/*! \brief Called when a player votes for a minor race mode.
|
||||
* \param event : Event providing the information.
|
||||
*
|
||||
@ -729,7 +728,8 @@ void ClientLobbyRoomProtocol::playerMinorVote(Event* event)
|
||||
if (!isByteCorrect(event, 7, 1))
|
||||
return;
|
||||
m_setup->getRaceConfig()->setPlayerMinorVote(data[6], data[8]);
|
||||
}
|
||||
} // playerMinorVote
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/*! \brief Called when a player votes for a track.
|
||||
@ -750,11 +750,12 @@ void ClientLobbyRoomProtocol::playerTrackVote(Event* event)
|
||||
if (!isByteCorrect(event, 5, 1))
|
||||
return;
|
||||
int N = data[7];
|
||||
std::string track_name = data.gs(8, N);
|
||||
std::string track_name = data.getString(8, N);
|
||||
if (!isByteCorrect(event, N+8, 1))
|
||||
return;
|
||||
m_setup->getRaceConfig()->setPlayerTrackVote(data[6], track_name, data[N+9]);
|
||||
}
|
||||
} // playerTrackVote
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/*! \brief Called when a player votes for the reverse mode of a race
|
||||
@ -779,7 +780,8 @@ void ClientLobbyRoomProtocol::playerReversedVote(Event* event)
|
||||
if (!isByteCorrect(event, 9, 1))
|
||||
return;
|
||||
m_setup->getRaceConfig()->setPlayerReversedVote(data[6], data[8]!=0, data[10]);
|
||||
}
|
||||
} // playerReversedVote
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/*! \brief Called when a player votes for a major race mode.
|
||||
@ -802,5 +804,6 @@ void ClientLobbyRoomProtocol::playerLapsVote(Event* event)
|
||||
if (!isByteCorrect(event, 7, 1))
|
||||
return;
|
||||
m_setup->getRaceConfig()->setPlayerLapsVote(data[6], data[8], data[10]);
|
||||
}
|
||||
} // playerLapsVote
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -59,12 +59,10 @@ bool ConnectToPeer::notifyEventAsynchronous(Event* event)
|
||||
|
||||
void ConnectToPeer::setup()
|
||||
{
|
||||
m_state = NONE;
|
||||
m_public_address.ip = 0;
|
||||
m_public_address.port = 0;
|
||||
m_peer_address.ip = 0;
|
||||
m_peer_address.port = 0;
|
||||
m_current_protocol_id = 0;
|
||||
m_state = NONE;
|
||||
m_public_address.clear();
|
||||
m_peer_address.clear();
|
||||
m_current_protocol_id = 0;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -83,22 +81,22 @@ void ConnectToPeer::asynchronousUpdate()
|
||||
if (m_listener->getProtocolState(m_current_protocol_id)
|
||||
== PROTOCOL_STATE_TERMINATED) // we know the peer address
|
||||
{
|
||||
if (m_peer_address.ip != 0 && m_peer_address.port != 0)
|
||||
if (m_peer_address.getIP() != 0 && m_peer_address.getPort() != 0)
|
||||
{
|
||||
// we're in the same lan (same public ip address) !!
|
||||
if (m_peer_address.ip == NetworkManager::getInstance()->getPublicAddress().ip)
|
||||
if (m_peer_address.getIP() == NetworkManager::getInstance()->getPublicAddress().getIP())
|
||||
{
|
||||
// just send a broadcast packet with the string aloha_stk inside, the client will know our ip address and will connect
|
||||
STKHost* host = NetworkManager::getInstance()->getHost();
|
||||
TransportAddress broadcast_address;
|
||||
broadcast_address.ip = -1; // 255.255.255.255
|
||||
broadcast_address.port = m_peer_address.port; // 0b10101100000101101101111111111111; // for test
|
||||
broadcast_address.setIP(-1); // 255.255.255.255
|
||||
broadcast_address.setPort(m_peer_address.getPort()); // 0b10101100000101101101111111111111; // for test
|
||||
char data[] = "aloha_stk\0";
|
||||
host->sendRawPacket((uint8_t*)(data), 10, broadcast_address);
|
||||
Log::info("ConnectToPeer", "Broadcast aloha sent.");
|
||||
StkTime::sleep(1);
|
||||
broadcast_address.ip = 0x7f000001; // 127.0.0.1 (localhost)
|
||||
broadcast_address.port = m_peer_address.port;
|
||||
broadcast_address.setIP(0x7f000001); // 127.0.0.1 (localhost)
|
||||
broadcast_address.setPort(m_peer_address.getPort());
|
||||
host->sendRawPacket((uint8_t*)(data), 10, broadcast_address);
|
||||
Log::info("ConnectToPeer", "Broadcast aloha to self.");
|
||||
}
|
||||
|
@ -82,10 +82,8 @@ void ConnectToServer::setup()
|
||||
{
|
||||
Log::info("ConnectToServer", "SETUPP");
|
||||
m_state = NONE;
|
||||
m_public_address.ip = 0;
|
||||
m_public_address.port = 0;
|
||||
m_server_address.ip = 0;
|
||||
m_server_address.port = 0;
|
||||
m_public_address.clear();
|
||||
m_server_address.clear();
|
||||
m_current_protocol_id = 0;
|
||||
}
|
||||
|
||||
@ -139,7 +137,8 @@ void ConnectToServer::asynchronousUpdate()
|
||||
== PROTOCOL_STATE_TERMINATED) // we know the server address
|
||||
{
|
||||
Log::info("ConnectToServer", "Server's address known");
|
||||
if (m_server_address.ip == m_public_address.ip) // we're in the same lan (same public ip address) !!
|
||||
// we're in the same lan (same public ip address) !!
|
||||
if (m_server_address.getIP() == m_public_address.getIP())
|
||||
Log::info("ConnectToServer", "Server appears to be in the same LAN.");
|
||||
m_state = REQUESTING_CONNECTION;
|
||||
m_current_protocol_id = m_listener->requestStart(new RequestConnection(m_server_id));
|
||||
@ -150,14 +149,17 @@ void ConnectToServer::asynchronousUpdate()
|
||||
== PROTOCOL_STATE_TERMINATED) // server knows we wanna connect
|
||||
{
|
||||
Log::info("ConnectToServer", "Connection request made");
|
||||
if (m_server_address.ip == 0 || m_server_address.port == 0)
|
||||
if (m_server_address.getIP() == 0 ||
|
||||
m_server_address.getPort() == 0 )
|
||||
{ // server data not correct, hide address and stop
|
||||
m_state = HIDING_ADDRESS;
|
||||
Log::error("ConnectToServer", "Server address is " ADDRESS_FORMAT, ADDRESS_ARGS(m_server_address.ip, m_server_address.port));
|
||||
Log::error("ConnectToServer", "Server address is %s",
|
||||
m_server_address.toString().c_str());
|
||||
m_current_protocol_id = m_listener->requestStart(new HidePublicAddress());
|
||||
return;
|
||||
}
|
||||
if (m_server_address.ip == m_public_address.ip) // we're in the same lan (same public ip address) !!
|
||||
// we're in the same lan (same public ip address) !!
|
||||
if (m_server_address.getIP() == m_public_address.getIP())
|
||||
{
|
||||
// just send a broadcast packet, the client will know our ip address and will connect
|
||||
STKHost* host = NetworkManager::getInstance()->getHost();
|
||||
@ -165,8 +167,8 @@ void ConnectToServer::asynchronousUpdate()
|
||||
TransportAddress sender;
|
||||
|
||||
TransportAddress broadcast_address;
|
||||
broadcast_address.ip = -1; // 255.255.255.255
|
||||
broadcast_address.port = 7321; // 0b10101100000101101101111111111111; // for test
|
||||
broadcast_address.setIP(-1); // 255.255.255.255
|
||||
broadcast_address.setPort(7321); // 0b10101100000101101101111111111111; // for test
|
||||
char data2[] = "aloha_stk\0";
|
||||
host->sendRawPacket((uint8_t*)(data2), 10, broadcast_address);
|
||||
|
||||
@ -177,7 +179,8 @@ void ConnectToServer::asynchronousUpdate()
|
||||
const char data[] = "aloha_stk\0";
|
||||
if (strcmp(data, (char*)(received_data)) == 0)
|
||||
{
|
||||
Log::info("ConnectToServer", "LAN Server found : %u:%u", sender.ip, sender.port);
|
||||
Log::info("ConnectToServer", "LAN Server found : %s",
|
||||
sender.toString().c_str());
|
||||
#ifndef WIN32
|
||||
// just check if the ip is ours : if so, then just use localhost (127.0.0.1)
|
||||
struct ifaddrs *ifap, *ifa;
|
||||
@ -188,8 +191,10 @@ void ConnectToServer::asynchronousUpdate()
|
||||
if (ifa->ifa_addr->sa_family==AF_INET)
|
||||
{
|
||||
sa = (struct sockaddr_in *) ifa->ifa_addr;
|
||||
if (ntohl(sa->sin_addr.s_addr) == sender.ip) // this interface is ours
|
||||
sender.ip = 0x7f000001; // 127.0.0.1
|
||||
|
||||
// This interface is ours
|
||||
if (ntohl(sa->sin_addr.s_addr) == sender.getIP())
|
||||
sender.setIP(0x7f000001); // 127.0.0.1
|
||||
}
|
||||
}
|
||||
freeifaddrs(ifap);
|
||||
@ -219,16 +224,16 @@ void ConnectToServer::asynchronousUpdate()
|
||||
for(unsigned int i=0; i<table->dwNumEntries; i++)
|
||||
{
|
||||
unsigned int ip = ntohl(table->table[i].dwAddr);
|
||||
if(sender.ip == ip) // this interface is ours
|
||||
if(sender.getIP() == ip) // this interface is ours
|
||||
{
|
||||
sender.ip = 0x7f000001; // 127.0.0.1
|
||||
sender.setIP(0x7f000001); // 127.0.0.1
|
||||
break;
|
||||
}
|
||||
}
|
||||
delete[] table;
|
||||
|
||||
#endif
|
||||
m_server_address = sender;
|
||||
m_server_address.copy(sender);
|
||||
m_state = CONNECTING;
|
||||
}
|
||||
}
|
||||
@ -246,7 +251,8 @@ void ConnectToServer::asynchronousUpdate()
|
||||
{
|
||||
timer = StkTime::getRealTime();
|
||||
NetworkManager::getInstance()->connect(m_server_address);
|
||||
Log::info("ConnectToServer", "Trying to connect to %u:%u", m_server_address.ip, m_server_address.port);
|
||||
Log::info("ConnectToServer", "Trying to connect to %s",
|
||||
m_server_address.toString().c_str());
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -118,7 +118,7 @@ bool ControllerEventsProtocol::notifyEventAsynchronous(Event* event)
|
||||
{
|
||||
if (i == client_index) // don't send that message to the sender
|
||||
continue;
|
||||
NetworkString ns2;
|
||||
NetworkString ns2(4+pure_message.size());
|
||||
ns2.ai32(m_controllers[i].second->getClientServerToken());
|
||||
ns2 += pure_message;
|
||||
m_listener->sendMessage(this, m_controllers[i].second, ns2, false);
|
||||
@ -157,7 +157,7 @@ void ControllerEventsProtocol::controllerAction(Controller* controller,
|
||||
uint8_t serialized_2 = (uint8_t)(controls->m_accel*255.0);
|
||||
uint8_t serialized_3 = (uint8_t)(controls->m_steer*127.0);
|
||||
|
||||
NetworkString ns;
|
||||
NetworkString ns(17);
|
||||
ns.ai32(m_controllers[m_self_controller_index].second->getClientServerToken());
|
||||
ns.af(World::getWorld()->getTime());
|
||||
ns.ai8(m_self_controller_index);
|
||||
|
@ -79,7 +79,7 @@ void GameEventsProtocol::collectedItem(Item* item, AbstractKart* kart)
|
||||
std::vector<STKPeer*> peers = NetworkManager::getInstance()->getPeers();
|
||||
for (unsigned int i = 0; i < peers.size(); i++)
|
||||
{
|
||||
NetworkString ns;
|
||||
NetworkString ns(11);
|
||||
ns.ai32(peers[i]->getClientServerToken());
|
||||
// 0x01 : item picked : send item id, powerup type and kart race id
|
||||
uint8_t powerup = 0;
|
||||
|
@ -61,12 +61,17 @@ void GetPeerAddress::asynchronousUpdate()
|
||||
if (rec_success == "yes")
|
||||
{
|
||||
TransportAddress* addr = static_cast<TransportAddress*>(m_callback_object);
|
||||
result->get("ip", &addr->ip);
|
||||
uint32_t ip;
|
||||
result->get("ip", &ip);
|
||||
addr->setIP(ip);
|
||||
|
||||
if (addr->ip == NetworkManager::getInstance()->getPublicAddress().ip)
|
||||
result->get("private_port", &addr->port);
|
||||
uint16_t port;
|
||||
if (addr->getIP() ==
|
||||
NetworkManager::getInstance()->getPublicAddress().getIP())
|
||||
result->get("private_port", &port);
|
||||
else
|
||||
result->get("port", &addr->port);
|
||||
result->get("port", &port);
|
||||
addr->setPort(port);
|
||||
|
||||
Log::debug("GetPeerAddress", "Address gotten successfully.");
|
||||
}
|
||||
|
@ -19,15 +19,14 @@
|
||||
#include "network/protocols/get_public_address.hpp"
|
||||
|
||||
#include "config/user_config.hpp"
|
||||
#include "network/network_manager.hpp"
|
||||
#include "network/client_network_manager.hpp"
|
||||
#include "network/protocols/connect_to_server.hpp"
|
||||
#include "network/network_interface.hpp"
|
||||
|
||||
#include "network/network_manager.hpp"
|
||||
#include "network/protocols/connect_to_server.hpp"
|
||||
#include "utils/log.hpp"
|
||||
#include "utils/random_generator.hpp"
|
||||
|
||||
#include <assert.h>
|
||||
#include <string>
|
||||
|
||||
#ifdef __MINGW32__
|
||||
# undef _WIN32_WINNT
|
||||
@ -43,213 +42,171 @@
|
||||
#endif
|
||||
#include <sys/types.h>
|
||||
|
||||
// make the linker happy
|
||||
const uint32_t GetPublicAddress::m_stun_magic_cookie = 0x2112A442;
|
||||
|
||||
int stunRand()
|
||||
{
|
||||
static bool init = false;
|
||||
if (!init)
|
||||
{
|
||||
srand((unsigned int)time(NULL));
|
||||
init = true;
|
||||
}
|
||||
return rand();
|
||||
}
|
||||
|
||||
GetPublicAddress::GetPublicAddress(CallbackObject* callback_object) : Protocol(callback_object, PROTOCOL_SILENT)
|
||||
{
|
||||
}
|
||||
|
||||
GetPublicAddress::~GetPublicAddress()
|
||||
{
|
||||
}
|
||||
|
||||
void GetPublicAddress::setup()
|
||||
GetPublicAddress::GetPublicAddress(CallbackObject* callback_object)
|
||||
: Protocol(callback_object, PROTOCOL_SILENT)
|
||||
{
|
||||
m_state = NOTHING_DONE;
|
||||
}
|
||||
} // GetPublicAddress
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Creates a STUN request and sends it to a random STUN server selected from
|
||||
* the list stored in the config file. See https://tools.ietf.org/html/rfc5389#section-6
|
||||
* for details on the message structure.
|
||||
* The request is send through m_transaction_host, from which the answer
|
||||
* will be retrieved by parseStunResponse()
|
||||
*/
|
||||
void GetPublicAddress::createStunRequest()
|
||||
{
|
||||
// Pick a random stun server
|
||||
std::vector<std::string> stun_servers = UserConfigParams::m_stun_servers;
|
||||
|
||||
const char* server_name = stun_servers[rand() % stun_servers.size()].c_str();
|
||||
Log::debug("GetPublicAddress", "Using STUN server %s", server_name);
|
||||
|
||||
struct addrinfo hints, *res;
|
||||
|
||||
memset(&hints, 0, sizeof hints);
|
||||
hints.ai_family = AF_UNSPEC; // AF_INET or AF_INET6 to force version
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
|
||||
// Resolve the stun server name so we can send it a STUN request
|
||||
int status = getaddrinfo(server_name, NULL, &hints, &res);
|
||||
if (status != 0)
|
||||
{
|
||||
Log::error("GetPublicAddress", "Error in getaddrinfo: %s", gai_strerror(status));
|
||||
return;
|
||||
}
|
||||
assert(res != NULL); // documentation says it points to "one or more addrinfo structures"
|
||||
struct sockaddr_in* current_interface = (struct sockaddr_in*)(res->ai_addr);
|
||||
m_stun_server_ip = ntohl(current_interface->sin_addr.s_addr);
|
||||
m_transaction_host = new STKHost();
|
||||
m_transaction_host->setupClient(1, 1, 0, 0);
|
||||
|
||||
// Assemble the message for the stun server
|
||||
NetworkString s(21);
|
||||
|
||||
// bytes 0-1: the type of the message
|
||||
// bytes 2-3: message length added to header (attributes)
|
||||
uint16_t message_type = 0x0001; // binding request
|
||||
uint16_t message_length = 0x0000;
|
||||
s.addUInt16(message_type).addUInt16(message_length)
|
||||
.addInt(0x2112A442);
|
||||
// bytes 8-19: the transaction id
|
||||
for (int i = 0; i < 12; i++)
|
||||
{
|
||||
uint8_t random_byte = rand() % 256;
|
||||
s.addUInt8(random_byte);
|
||||
m_stun_tansaction_id[i] = random_byte;
|
||||
}
|
||||
s.addChar(0);
|
||||
|
||||
|
||||
m_transaction_host->sendRawPacket(s.getBytes(), 20, TransportAddress(m_stun_server_ip, m_stun_server_port));
|
||||
freeaddrinfo(res);
|
||||
m_state = STUN_REQUEST_SENT;
|
||||
} // createStunRequest
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/**
|
||||
* Gets the response from the STUN server, checks it for its validity and
|
||||
* then parses the answer into address and port
|
||||
* \return "" if the address could be parsed or an error message
|
||||
*/
|
||||
std::string GetPublicAddress::parseStunResponse()
|
||||
{
|
||||
uint8_t* s = m_transaction_host->receiveRawPacket(TransportAddress(m_stun_server_ip, m_stun_server_port), 2000);
|
||||
|
||||
if (!s)
|
||||
return "STUN response contains no data at all";
|
||||
|
||||
// Convert to network string.
|
||||
// FIXME: the length is not known (atm 2048 bytes are allocated in
|
||||
// receiveRawPacket, and it looks like 32 are actually used in a normal stun reply
|
||||
NetworkString datas(std::string((char*)s, 32));
|
||||
|
||||
// The received data has been copied and can now be deleted
|
||||
delete s;
|
||||
|
||||
// check that the stun response is a response, contains the magic cookie and the transaction ID
|
||||
if (datas.getUInt16(0) != 0x0101)
|
||||
return "STUN response doesn't contain the magic cookie";
|
||||
|
||||
if (datas.getUInt32(4) != m_stun_magic_cookie)
|
||||
{
|
||||
return "STUN response doesn't contain the magic cookie";
|
||||
}
|
||||
|
||||
for (int i = 0; i < 12; i++)
|
||||
{
|
||||
if (datas.getUInt8(i+8) != m_stun_tansaction_id[i])
|
||||
return "STUN response doesn't contain the transaction ID";
|
||||
}
|
||||
|
||||
Log::debug("GetPublicAddress", "The STUN server responded with a valid answer");
|
||||
int message_size = datas.getUInt16(2);
|
||||
|
||||
// The stun message is valid, so we parse it now:
|
||||
if (message_size == 0)
|
||||
return "STUN response does not contain any information.";
|
||||
if (message_size < 4) // cannot even read the size
|
||||
return "STUN response is too short.";
|
||||
|
||||
|
||||
// Those are the port and the address to be detected
|
||||
TransportAddress address;
|
||||
int pos = 20;
|
||||
while (true)
|
||||
{
|
||||
int type = datas.getUInt16(pos);
|
||||
int size = datas.getUInt16(pos+2);
|
||||
if (type == 0 || type == 1)
|
||||
{
|
||||
assert(size == 8);
|
||||
assert(datas.getUInt8(pos+5) == 0x01); // Family IPv4 only
|
||||
address.setPort(datas.getUInt16(pos + 6));
|
||||
address.setIP(datas.getUInt32(pos + 8));
|
||||
break;
|
||||
} // type = 0 or 1
|
||||
pos += 4 + size;
|
||||
message_size -= 4 + size;
|
||||
if (message_size == 0)
|
||||
return "STUN response is invalid.";
|
||||
if (message_size < 4) // cannot even read the size
|
||||
return "STUN response is invalid.";
|
||||
} // while true
|
||||
|
||||
// finished parsing, we know our public transport address
|
||||
Log::debug("GetPublicAddress", "The public address has been found: %s",
|
||||
address.toString().c_str());
|
||||
TransportAddress* addr = static_cast<TransportAddress*>(m_callback_object);
|
||||
addr->copy(address);
|
||||
|
||||
// The address and the port are known, so the connection can be closed
|
||||
m_state = EXITING;
|
||||
m_listener->requestTerminate(this);
|
||||
|
||||
return "";
|
||||
} // parseStunResponse
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Detects public IP-address and port by first sending a request to a randomly
|
||||
* selected STUN server and then parsing and validating the response */
|
||||
void GetPublicAddress::asynchronousUpdate()
|
||||
{
|
||||
if (m_state == NOTHING_DONE)
|
||||
{
|
||||
// format : 00MMMMMCMMMCMMMM (cf rfc 5389)
|
||||
uint16_t message_type = 0x0001; // binding request
|
||||
m_stun_tansaction_id[0] = stunRand();
|
||||
m_stun_tansaction_id[1] = stunRand();
|
||||
m_stun_tansaction_id[2] = stunRand();
|
||||
uint16_t message_length = 0x0000;
|
||||
|
||||
uint8_t bytes[21]; // the message to be sent
|
||||
// bytes 0-1 : the type of the message,
|
||||
bytes[0] = (uint8_t)(message_type>>8);
|
||||
bytes[1] = (uint8_t)(message_type);
|
||||
|
||||
// bytes 2-3 : message length added to header (attributes)
|
||||
bytes[2] = (uint8_t)(message_length>>8);
|
||||
bytes[3] = (uint8_t)(message_length);
|
||||
|
||||
// bytes 4-7 : magic cookie to recognize the stun protocol
|
||||
bytes[4] = (uint8_t)(m_stun_magic_cookie>>24);
|
||||
bytes[5] = (uint8_t)(m_stun_magic_cookie>>16);
|
||||
bytes[6] = (uint8_t)(m_stun_magic_cookie>>8);
|
||||
bytes[7] = (uint8_t)(m_stun_magic_cookie);
|
||||
|
||||
// bytes 8-19 : the transaction id
|
||||
bytes[8] = (uint8_t)(m_stun_tansaction_id[0]>>24);
|
||||
bytes[9] = (uint8_t)(m_stun_tansaction_id[0]>>16);
|
||||
bytes[10] = (uint8_t)(m_stun_tansaction_id[0]>>8);
|
||||
bytes[11] = (uint8_t)(m_stun_tansaction_id[0]);
|
||||
bytes[12] = (uint8_t)(m_stun_tansaction_id[1]>>24);
|
||||
bytes[13] = (uint8_t)(m_stun_tansaction_id[1]>>16);
|
||||
bytes[14] = (uint8_t)(m_stun_tansaction_id[1]>>8);
|
||||
bytes[15] = (uint8_t)(m_stun_tansaction_id[1]);
|
||||
bytes[16] = (uint8_t)(m_stun_tansaction_id[2]>>24);
|
||||
bytes[17] = (uint8_t)(m_stun_tansaction_id[2]>>16);
|
||||
bytes[18] = (uint8_t)(m_stun_tansaction_id[2]>>8);
|
||||
bytes[19] = (uint8_t)(m_stun_tansaction_id[2]);
|
||||
bytes[20] = '\0';
|
||||
|
||||
// time to pick a random stun server
|
||||
std::vector<std::string> stun_servers = UserConfigParams::m_stun_servers;
|
||||
|
||||
RandomGenerator random_gen;
|
||||
int rand_result = random_gen.get((int)stun_servers.size());
|
||||
Log::verbose("GetPublicAddress", "Using STUN server %s",
|
||||
stun_servers[rand_result].c_str());
|
||||
|
||||
// resolve the name into an IP address
|
||||
struct addrinfo hints, *res, *p;
|
||||
int status;
|
||||
|
||||
memset(&hints, 0, sizeof hints);
|
||||
hints.ai_family = AF_UNSPEC; // AF_INET or AF_INET6 to force version
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
|
||||
if ((status = getaddrinfo(stun_servers[rand_result].c_str(), NULL, &hints, &res)) != 0) {
|
||||
Log::error("getaddrinfo", gai_strerror(status));
|
||||
return;
|
||||
}
|
||||
for(p = res;p != NULL; p = p->ai_next)
|
||||
{
|
||||
struct sockaddr_in* current_interface = (struct sockaddr_in*)(p->ai_addr);
|
||||
|
||||
m_stun_server_ip = ntohl(current_interface->sin_addr.s_addr);
|
||||
m_transaction_host = new STKHost();
|
||||
m_transaction_host->setupClient(1,1,0,0);
|
||||
m_transaction_host->sendRawPacket(bytes, 20, TransportAddress(m_stun_server_ip, 3478));
|
||||
m_state = TEST_SENT;
|
||||
|
||||
freeaddrinfo(res); // free the linked list
|
||||
return;
|
||||
}
|
||||
freeaddrinfo(res); // free the linked list
|
||||
|
||||
createStunRequest();
|
||||
}
|
||||
if (m_state == TEST_SENT)
|
||||
if (m_state == STUN_REQUEST_SENT)
|
||||
{
|
||||
uint8_t* data = m_transaction_host->receiveRawPacket(TransportAddress(m_stun_server_ip, 3478), 2000);
|
||||
if (!data)
|
||||
std::string message = parseStunResponse();
|
||||
if (message != "")
|
||||
{
|
||||
m_state = NOTHING_DONE; // will send the test again to an other server
|
||||
return;
|
||||
}
|
||||
assert(data);
|
||||
|
||||
// check that the stun response is a response, contains the magic cookie and the transaction ID
|
||||
if ( data[0] == 0x01 &&
|
||||
data[1] == 0x01 &&
|
||||
data[4] == (uint8_t)(m_stun_magic_cookie>>24) &&
|
||||
data[5] == (uint8_t)(m_stun_magic_cookie>>16) &&
|
||||
data[6] == (uint8_t)(m_stun_magic_cookie>>8) &&
|
||||
data[7] == (uint8_t)(m_stun_magic_cookie) )
|
||||
{
|
||||
if(
|
||||
data[8] == (uint8_t)(m_stun_tansaction_id[0]>>24) &&
|
||||
data[9] == (uint8_t)(m_stun_tansaction_id[0]>>16) &&
|
||||
data[10] == (uint8_t)(m_stun_tansaction_id[0]>>8 ) &&
|
||||
data[11] == (uint8_t)(m_stun_tansaction_id[0] ) &&
|
||||
data[12] == (uint8_t)(m_stun_tansaction_id[1]>>24) &&
|
||||
data[13] == (uint8_t)(m_stun_tansaction_id[1]>>16) &&
|
||||
data[14] == (uint8_t)(m_stun_tansaction_id[1]>>8 ) &&
|
||||
data[15] == (uint8_t)(m_stun_tansaction_id[1] ) &&
|
||||
data[16] == (uint8_t)(m_stun_tansaction_id[2]>>24) &&
|
||||
data[17] == (uint8_t)(m_stun_tansaction_id[2]>>16) &&
|
||||
data[18] == (uint8_t)(m_stun_tansaction_id[2]>>8 ) &&
|
||||
data[19] == (uint8_t)(m_stun_tansaction_id[2] ))
|
||||
{
|
||||
Log::verbose("GetPublicAddress", "The STUN server responded with a valid answer");
|
||||
int message_size = data[2]*256+data[3];
|
||||
|
||||
// parse the stun message now:
|
||||
bool finish = false;
|
||||
uint8_t* attributes = data+20;
|
||||
if (message_size == 0)
|
||||
{
|
||||
Log::error("GetPublicAddress", "STUN answer does not contain any information.");
|
||||
finish = true;
|
||||
}
|
||||
if (message_size < 4) // cannot even read the size
|
||||
{
|
||||
Log::error("GetPublicAddress", "STUN message is not valid.");
|
||||
finish = true;
|
||||
}
|
||||
uint16_t port;
|
||||
uint32_t address;
|
||||
bool valid = false;
|
||||
while(!finish)
|
||||
{
|
||||
int type = attributes[0]*256+attributes[1];
|
||||
int size = attributes[2]*256+attributes[3];
|
||||
switch(type)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
assert(size == 8);
|
||||
assert(attributes[5] == 0x01); // IPv4 only
|
||||
port = attributes[6]*256+attributes[7];
|
||||
address = (attributes[8]<<24 & 0xFF000000)+(attributes[9]<<16 & 0x00FF0000)+(attributes[10]<<8 & 0x0000FF00)+(attributes[11] & 0x000000FF);
|
||||
finish = true;
|
||||
valid = true;
|
||||
continue;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
attributes = attributes + 4 + size;
|
||||
message_size -= 4 + size;
|
||||
if (message_size == 0)
|
||||
finish = true;
|
||||
if (message_size < 4) // cannot even read the size
|
||||
{
|
||||
Log::error("GetPublicAddress", "STUN message is not valid.");
|
||||
finish = true;
|
||||
}
|
||||
}
|
||||
// finished parsing, we know our public transport address
|
||||
if (valid)
|
||||
{
|
||||
Log::debug("GetPublicAddress", "The public address has been found : %i.%i.%i.%i:%i", address>>24&0xff, address>>16&0xff, address>>8&0xff, address&0xff, port);
|
||||
m_state = ADDRESS_KNOWN;
|
||||
TransportAddress* addr = static_cast<TransportAddress*>(m_callback_object);
|
||||
addr->ip = address;
|
||||
addr->port = port;
|
||||
}
|
||||
else
|
||||
m_state = NOTHING_DONE; // need to re-send the stun request
|
||||
}
|
||||
else
|
||||
{
|
||||
m_state = NOTHING_DONE; // need to re-send the stun request
|
||||
}
|
||||
Log::warn("GetPublicAddress", "%s", message.c_str());
|
||||
m_state = NOTHING_DONE;
|
||||
}
|
||||
}
|
||||
if (m_state == ADDRESS_KNOWN)
|
||||
{
|
||||
m_state = EXITING;
|
||||
// terminate the protocol
|
||||
m_listener->requestTerminate(this);
|
||||
}
|
||||
if (m_state == EXITING)
|
||||
{
|
||||
}
|
||||
}
|
||||
} // asynchronousUpdate
|
@ -21,29 +21,36 @@
|
||||
|
||||
#include "network/protocol.hpp"
|
||||
|
||||
#include <string>
|
||||
|
||||
class GetPublicAddress : public Protocol
|
||||
{
|
||||
public:
|
||||
GetPublicAddress(CallbackObject* callback_object);
|
||||
virtual ~GetPublicAddress();
|
||||
virtual ~GetPublicAddress() {}
|
||||
|
||||
virtual bool notifyEvent(Event* event) { return true; }
|
||||
virtual bool notifyEventAsynchronous(Event* event) { return true; }
|
||||
virtual void setup();
|
||||
virtual void setup() { m_state = NOTHING_DONE; }
|
||||
virtual void update() {}
|
||||
virtual void asynchronousUpdate();
|
||||
|
||||
protected:
|
||||
private:
|
||||
void createStunRequest();
|
||||
std::string parseStunResponse();
|
||||
|
||||
// Constants
|
||||
static const uint32_t m_stun_magic_cookie;
|
||||
static const int m_stun_server_port = 3478;
|
||||
|
||||
enum STATE
|
||||
{
|
||||
NOTHING_DONE,
|
||||
TEST_SENT,
|
||||
ADDRESS_KNOWN,
|
||||
STUN_REQUEST_SENT,
|
||||
EXITING
|
||||
};
|
||||
STATE m_state;
|
||||
uint32_t m_stun_tansaction_id[3];
|
||||
static const uint32_t m_stun_magic_cookie = 0x2112A442;
|
||||
uint8_t m_stun_tansaction_id[12];
|
||||
uint32_t m_stun_server_ip;
|
||||
STKHost* m_transaction_host;
|
||||
};
|
||||
|
@ -78,7 +78,7 @@ void KartUpdateProtocol::update()
|
||||
time = current_time;
|
||||
if (m_listener->isServer())
|
||||
{
|
||||
NetworkString ns;
|
||||
NetworkString ns(4+m_karts.size()*32);
|
||||
ns.af( World::getWorld()->getTime());
|
||||
for (unsigned int i = 0; i < m_karts.size(); i++)
|
||||
{
|
||||
@ -97,7 +97,7 @@ void KartUpdateProtocol::update()
|
||||
AbstractKart* kart = m_karts[m_self_kart_index];
|
||||
Vec3 v = kart->getXYZ();
|
||||
btQuaternion quat = kart->getRotation();
|
||||
NetworkString ns;
|
||||
NetworkString ns(36);
|
||||
ns.af( World::getWorld()->getTime());
|
||||
ns.ai32( kart->getWorldKartId());
|
||||
ns.af(v[0]).af(v[1]).af(v[2]); // add position
|
||||
|
@ -21,9 +21,10 @@
|
||||
#include "network/network_manager.hpp"
|
||||
#include "utils/time.hpp"
|
||||
|
||||
PingProtocol::PingProtocol(const TransportAddress& ping_dst, double delay_between_pings) : Protocol(NULL, PROTOCOL_SILENT)
|
||||
PingProtocol::PingProtocol(const TransportAddress& ping_dst, double delay_between_pings)
|
||||
: Protocol(NULL, PROTOCOL_SILENT)
|
||||
{
|
||||
m_ping_dst = ping_dst;
|
||||
m_ping_dst.copy(ping_dst);
|
||||
m_delay_between_pings = delay_between_pings;
|
||||
}
|
||||
|
||||
|
@ -42,7 +42,7 @@ void QuickJoinProtocol::asynchronousUpdate()
|
||||
{
|
||||
if (m_state == NONE)
|
||||
{
|
||||
TransportAddress addr = NetworkManager::getInstance()->getPublicAddress();
|
||||
const TransportAddress& addr = NetworkManager::getInstance()->getPublicAddress();
|
||||
m_request = new Online::XMLRequest();
|
||||
PlayerManager::setUserDetails(m_request, "quick-join", Online::API::SERVER_PATH);
|
||||
|
||||
@ -59,10 +59,15 @@ void QuickJoinProtocol::asynchronousUpdate()
|
||||
{
|
||||
if(rec_success == "yes")
|
||||
{
|
||||
result->get("ip", &res->ip);
|
||||
result->get("port", &res->port);
|
||||
uint32_t ip;
|
||||
result->get("ip", &ip);
|
||||
res->setIP(ip);
|
||||
uint16_t port;
|
||||
result->get("port", &port);
|
||||
res->setPort(port);
|
||||
result->get("hostid", m_server_id);
|
||||
Log::info("QuickJoinProtocol", "Quick joining %d:%d (server#%d).", res->ip, res->port, *m_server_id);
|
||||
Log::info("QuickJoinProtocol", "Quick joining %s (server#%d).",
|
||||
res->toString().c_str(), *m_server_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -53,8 +53,7 @@ void ServerLobbyRoomProtocol::setup()
|
||||
m_setup->getRaceConfig()->setPlayerCount(16); //FIXME : this has to be moved to when logging into the server
|
||||
m_next_id = 0;
|
||||
m_state = NONE;
|
||||
m_public_address.ip = 0;
|
||||
m_public_address.port = 0;
|
||||
m_public_address.clear();
|
||||
m_selection_enabled = false;
|
||||
m_in_race = false;
|
||||
Log::info("ServerLobbyRoomProtocol", "Starting the protocol.");
|
||||
@ -150,7 +149,7 @@ void ServerLobbyRoomProtocol::startGame()
|
||||
std::vector<STKPeer*> peers = NetworkManager::getInstance()->getPeers();
|
||||
for (unsigned int i = 0; i < peers.size(); i++)
|
||||
{
|
||||
NetworkString ns;
|
||||
NetworkString ns(6);
|
||||
ns.ai8(0x04).ai8(4).ai32(peers[i]->getClientServerToken()); // start game
|
||||
m_listener->sendMessage(this, peers[i], ns, true); // reliably
|
||||
}
|
||||
@ -165,7 +164,7 @@ void ServerLobbyRoomProtocol::startSelection()
|
||||
std::vector<STKPeer*> peers = NetworkManager::getInstance()->getPeers();
|
||||
for (unsigned int i = 0; i < peers.size(); i++)
|
||||
{
|
||||
NetworkString ns;
|
||||
NetworkString ns(6);
|
||||
ns.ai8(0x05).ai8(4).ai32(peers[i]->getClientServerToken()); // start selection
|
||||
m_listener->sendMessage(this, peers[i], ns, true); // reliably
|
||||
}
|
||||
@ -181,12 +180,12 @@ void ServerLobbyRoomProtocol::checkIncomingConnectionRequests()
|
||||
if (StkTime::getRealTime() > last_poll_time+10.0)
|
||||
{
|
||||
last_poll_time = StkTime::getRealTime();
|
||||
TransportAddress addr = NetworkManager::getInstance()->getPublicAddress();
|
||||
const TransportAddress &addr = NetworkManager::getInstance()->getPublicAddress();
|
||||
Online::XMLRequest* request = new Online::XMLRequest();
|
||||
PlayerManager::setUserDetails(request, "poll-connection-requests", Online::API::SERVER_PATH);
|
||||
|
||||
request->addParameter("address", addr.ip);
|
||||
request->addParameter("port", addr.port);
|
||||
request->addParameter("address", addr.getIP());
|
||||
request->addParameter("port", addr.getPort());
|
||||
|
||||
request->executeNow();
|
||||
assert(request->isDone());
|
||||
@ -256,7 +255,7 @@ void ServerLobbyRoomProtocol::checkRaceFinished()
|
||||
|
||||
std::vector<STKPeer*> peers = NetworkManager::getInstance()->getPeers();
|
||||
|
||||
NetworkString queue;
|
||||
NetworkString queue(karts_results.size()*2);
|
||||
for (unsigned int i = 0; i < karts_results.size(); i++)
|
||||
{
|
||||
queue.ai8(1).ai8(karts_results[i]); // kart pos = i+1
|
||||
@ -264,7 +263,7 @@ void ServerLobbyRoomProtocol::checkRaceFinished()
|
||||
}
|
||||
for (unsigned int i = 0; i < peers.size(); i++)
|
||||
{
|
||||
NetworkString ns;
|
||||
NetworkString ns(6);
|
||||
ns.ai8(0x06).ai8(4).ai32(peers[i]->getClientServerToken());
|
||||
NetworkString total = ns + queue;
|
||||
m_listener->sendMessage(this, peers[i], total, true);
|
||||
@ -311,7 +310,7 @@ void ServerLobbyRoomProtocol::kartDisconnected(Event* event)
|
||||
STKPeer* peer = *(event->peer);
|
||||
if (peer->getPlayerProfile() != NULL) // others knew him
|
||||
{
|
||||
NetworkString msg;
|
||||
NetworkString msg(3);
|
||||
msg.ai8(0x02).ai8(1).ai8(peer->getPlayerProfile()->race_id);
|
||||
m_listener->sendMessage(this, msg);
|
||||
Log::info("ServerLobbyRoomProtocol", "Player disconnected : id %d",
|
||||
@ -353,7 +352,7 @@ void ServerLobbyRoomProtocol::connectionRequested(Event* event)
|
||||
// add the player to the game setup
|
||||
m_next_id = m_setup->getPlayerCount();
|
||||
// notify everybody that there is a new player
|
||||
NetworkString message;
|
||||
NetworkString message(8);
|
||||
// new player (1) -- size of id -- id -- size of local id -- local id;
|
||||
message.ai8(1).ai8(4).ai32(player_id).ai8(1).ai8(m_next_id);
|
||||
m_listener->sendMessageExcept(this, peer, message);
|
||||
@ -366,12 +365,13 @@ void ServerLobbyRoomProtocol::connectionRequested(Event* event)
|
||||
((token_generator.get(RAND_MAX)<<8) & 0xff) +
|
||||
((token_generator.get(RAND_MAX) & 0xff)));
|
||||
|
||||
std::vector<NetworkPlayerProfile*> players = m_setup->getPlayers();
|
||||
// send a message to the one that asked to connect
|
||||
NetworkString message_ack;
|
||||
// Size is overestimated, probably one player's data will not be sent
|
||||
NetworkString message_ack(13+players.size()*7);
|
||||
// connection success (129) -- size of token -- token
|
||||
message_ack.ai8(0x81).ai8(1).ai8(m_next_id).ai8(4).ai32(token).ai8(4).ai32(player_id);
|
||||
// add all players so that this user knows
|
||||
std::vector<NetworkPlayerProfile*> players = m_setup->getPlayers();
|
||||
for (unsigned int i = 0; i < players.size(); i++)
|
||||
{
|
||||
// do not duplicate the player into the message
|
||||
@ -392,7 +392,7 @@ void ServerLobbyRoomProtocol::connectionRequested(Event* event)
|
||||
} // accept player
|
||||
else // refuse the connection with code 0 (too much players)
|
||||
{
|
||||
NetworkString message;
|
||||
NetworkString message(3);
|
||||
message.ai8(0x80); // 128 means connection refused
|
||||
message.ai8(1); // 1 bytes for the error code
|
||||
message.ai8(0); // 0 = too much players
|
||||
@ -422,7 +422,7 @@ void ServerLobbyRoomProtocol::kartSelectionRequested(Event* event)
|
||||
return;
|
||||
|
||||
uint8_t kart_name_size = data.gui8(5);
|
||||
std::string kart_name = data.gs(6, kart_name_size);
|
||||
std::string kart_name = data.getString(6, kart_name_size);
|
||||
if (kart_name.size() != kart_name_size)
|
||||
{
|
||||
Log::error("ServerLobbyRoomProtocol", "Kart names sizes differ: told:"
|
||||
@ -432,7 +432,7 @@ void ServerLobbyRoomProtocol::kartSelectionRequested(Event* event)
|
||||
// check if selection is possible
|
||||
if (!m_selection_enabled)
|
||||
{
|
||||
NetworkString answer;
|
||||
NetworkString answer(3);
|
||||
answer.ai8(0x82).ai8(1).ai8(2); // selection still not started
|
||||
m_listener->sendMessage(this, peer, answer);
|
||||
return;
|
||||
@ -440,7 +440,7 @@ void ServerLobbyRoomProtocol::kartSelectionRequested(Event* event)
|
||||
// check if somebody picked that kart
|
||||
if (!m_setup->isKartAvailable(kart_name))
|
||||
{
|
||||
NetworkString answer;
|
||||
NetworkString answer(3);
|
||||
answer.ai8(0x82).ai8(1).ai8(0); // kart is already taken
|
||||
m_listener->sendMessage(this, peer, answer);
|
||||
return;
|
||||
@ -448,17 +448,17 @@ void ServerLobbyRoomProtocol::kartSelectionRequested(Event* event)
|
||||
// check if this kart is authorized
|
||||
if (!m_setup->isKartAllowed(kart_name))
|
||||
{
|
||||
NetworkString answer;
|
||||
NetworkString answer(3);
|
||||
answer.ai8(0x82).ai8(1).ai8(1); // kart is not authorized
|
||||
m_listener->sendMessage(this, peer, answer);
|
||||
return;
|
||||
}
|
||||
// send a kart update to everyone
|
||||
NetworkString answer;
|
||||
NetworkString answer(3+1+kart_name.size());
|
||||
// kart update (3), 1, race id
|
||||
answer.ai8(0x03).ai8(1).ai8(peer->getPlayerProfile()->race_id);
|
||||
// kart name size, kart name
|
||||
answer.ai8(kart_name.size()).as(kart_name);
|
||||
answer.add(kart_name);
|
||||
m_listener->sendMessage(this, answer);
|
||||
m_setup->setPlayerKart(peer->getPlayerProfile()->race_id, kart_name);
|
||||
}
|
||||
@ -486,11 +486,11 @@ void ServerLobbyRoomProtocol::playerMajorVote(Event* event)
|
||||
uint8_t player_id = peer->getPlayerProfile()->race_id;
|
||||
m_setup->getRaceConfig()->setPlayerMajorVote(player_id, data[6]);
|
||||
// Send the vote to everybody (including the sender)
|
||||
NetworkString other;
|
||||
other.ai8(1).ai8(player_id); // add the player id
|
||||
data.removeFront(5); // remove the token
|
||||
NetworkString other(2+data.size());
|
||||
other.ai8(1).ai8(player_id); // add the player id
|
||||
other += data; // add the data
|
||||
NetworkString prefix;
|
||||
NetworkString prefix(1);
|
||||
prefix.ai8(0xc0); // prefix the token with the ype
|
||||
sendMessageToPeersChangingToken(prefix, other);
|
||||
}
|
||||
@ -517,11 +517,11 @@ void ServerLobbyRoomProtocol::playerRaceCountVote(Event* event)
|
||||
uint8_t player_id = peer->getPlayerProfile()->race_id;
|
||||
m_setup->getRaceConfig()->setPlayerRaceCountVote(player_id, data[6]);
|
||||
// Send the vote to everybody (including the sender)
|
||||
NetworkString other;
|
||||
other.ai8(1).ai8(player_id); // add the player id
|
||||
data.removeFront(5); // remove the token
|
||||
NetworkString other(2+data.size());
|
||||
other.ai8(1).ai8(player_id); // add the player id
|
||||
other += data; // add the data
|
||||
NetworkString prefix;
|
||||
NetworkString prefix(1);
|
||||
prefix.ai8(0xc1); // prefix the token with the type
|
||||
sendMessageToPeersChangingToken(prefix, other);
|
||||
}
|
||||
@ -548,11 +548,11 @@ void ServerLobbyRoomProtocol::playerMinorVote(Event* event)
|
||||
uint8_t player_id = peer->getPlayerProfile()->race_id;
|
||||
m_setup->getRaceConfig()->setPlayerMinorVote(player_id, data[6]);
|
||||
// Send the vote to everybody (including the sender)
|
||||
NetworkString other;
|
||||
other.ai8(1).ai8(player_id); // add the player id
|
||||
data.removeFront(5); // remove the token
|
||||
NetworkString other(2+data.size());
|
||||
other.ai8(1).ai8(player_id); // add the player id
|
||||
other += data; // add the data
|
||||
NetworkString prefix;
|
||||
NetworkString prefix(1);
|
||||
prefix.ai8(0xc2); // prefix the token with the ype
|
||||
sendMessageToPeersChangingToken(prefix, other);
|
||||
}
|
||||
@ -575,17 +575,17 @@ void ServerLobbyRoomProtocol::playerTrackVote(Event* event)
|
||||
if (!checkDataSizeAndToken(event, 8))
|
||||
return;
|
||||
int N = data[5];
|
||||
std::string track_name = data.gs(5, N);
|
||||
std::string track_name = data.getString(5, N);
|
||||
if (!isByteCorrect(event, N+6, 1))
|
||||
return;
|
||||
uint8_t player_id = peer->getPlayerProfile()->race_id;
|
||||
m_setup->getRaceConfig()->setPlayerTrackVote(player_id, track_name, data[N+7]);
|
||||
// Send the vote to everybody (including the sender)
|
||||
NetworkString other;
|
||||
other.ai8(1).ai8(player_id); // add the player id
|
||||
data.removeFront(5); // remove the token
|
||||
NetworkString other(2+data.size());
|
||||
other.ai8(1).ai8(player_id); // add the player id
|
||||
other += data; // add the data
|
||||
NetworkString prefix;
|
||||
NetworkString prefix(1);
|
||||
prefix.ai8(0xc3); // prefix the token with the ype
|
||||
sendMessageToPeersChangingToken(prefix, other);
|
||||
}
|
||||
@ -614,11 +614,11 @@ void ServerLobbyRoomProtocol::playerReversedVote(Event* event)
|
||||
uint8_t player_id = peer->getPlayerProfile()->race_id;
|
||||
m_setup->getRaceConfig()->setPlayerReversedVote(player_id, data[6]!=0, data[8]);
|
||||
// Send the vote to everybody (including the sender)
|
||||
NetworkString other;
|
||||
other.ai8(1).ai8(player_id); // add the player id
|
||||
data.removeFront(5); // remove the token
|
||||
NetworkString other(2+data.size());
|
||||
other.ai8(1).ai8(player_id); // add the player id
|
||||
other += data; // add the data
|
||||
NetworkString prefix;
|
||||
NetworkString prefix(1);
|
||||
prefix.ai8(0xc4); // prefix the token with the ype
|
||||
sendMessageToPeersChangingToken(prefix, other);
|
||||
}
|
||||
@ -647,11 +647,11 @@ void ServerLobbyRoomProtocol::playerLapsVote(Event* event)
|
||||
uint8_t player_id = peer->getPlayerProfile()->race_id;
|
||||
m_setup->getRaceConfig()->setPlayerLapsVote(player_id, data[6], data[8]);
|
||||
// Send the vote to everybody (including the sender)
|
||||
NetworkString other;
|
||||
other.ai8(1).ai8(player_id); // add the player id
|
||||
data.removeFront(5); // remove the token
|
||||
NetworkString other(2+data.size());
|
||||
other.ai8(1).ai8(player_id); // add the player id
|
||||
other += data; // add the data
|
||||
NetworkString prefix;
|
||||
NetworkString prefix(1);
|
||||
prefix.ai8(0xc5); // prefix the token with the ype
|
||||
sendMessageToPeersChangingToken(prefix, other);
|
||||
}
|
||||
|
@ -41,15 +41,15 @@ void ShowPublicAddress::asynchronousUpdate()
|
||||
{
|
||||
if (m_state == NONE)
|
||||
{
|
||||
TransportAddress addr = NetworkManager::getInstance()->getPublicAddress();
|
||||
const TransportAddress& addr = NetworkManager::getInstance()->getPublicAddress();
|
||||
m_request = new Online::XMLRequest();
|
||||
PlayerManager::setUserDetails(m_request, "set", Online::API::SERVER_PATH);
|
||||
|
||||
m_request->addParameter("address", addr.ip);
|
||||
m_request->addParameter("port", addr.port);
|
||||
m_request->addParameter("address", addr.getIP());
|
||||
m_request->addParameter("port", addr.getPort());
|
||||
m_request->addParameter("private_port", NetworkManager::getInstance()->getHost()->getPort());
|
||||
|
||||
Log::info("ShowPublicAddress", "Showing addr %u and port %d", addr.ip, addr.port);
|
||||
Log::info("ShowPublicAddress", "Showing addr %s", addr.toString().c_str());
|
||||
|
||||
Online::RequestManager::get()->addRequest(m_request);
|
||||
m_state = REQUEST_PENDING;
|
||||
|
@ -198,7 +198,7 @@ void StartGameProtocol::ready() // on clients, means the loading is finished
|
||||
if (!m_listener->isServer()) // if we're a client
|
||||
{
|
||||
assert(NetworkManager::getInstance()->getPeerCount() == 1);
|
||||
NetworkString ns;
|
||||
NetworkString ns(5);
|
||||
ns.ai32(NetworkManager::getInstance()->getPeers()[0]->getClientServerToken()).ai8(1);
|
||||
Log::info("StartGameProtocol", "Player ready, notifying server.");
|
||||
m_listener->sendMessage(this, ns, true);
|
||||
|
@ -40,16 +40,16 @@ void StartServer::asynchronousUpdate()
|
||||
{
|
||||
if (m_state == NONE)
|
||||
{
|
||||
TransportAddress addr = NetworkManager::getInstance()->getPublicAddress();
|
||||
const TransportAddress& addr = NetworkManager::getInstance()->getPublicAddress();
|
||||
m_request = new Online::XMLRequest();
|
||||
PlayerManager::setUserDetails(m_request, "start", Online::API::SERVER_PATH);
|
||||
|
||||
m_request->addParameter("address", addr.ip);
|
||||
m_request->addParameter("port", addr.port);
|
||||
m_request->addParameter("address", addr.getIP());
|
||||
m_request->addParameter("port", addr.getPort());
|
||||
m_request->addParameter("private_port", NetworkManager::getInstance()->getHost()->getPort());
|
||||
m_request->addParameter("max_players", UserConfigParams::m_server_max_players);
|
||||
|
||||
Log::info("ShowPublicAddress", "Showing addr %u and port %d", addr.ip, addr.port);
|
||||
Log::info("ShowPublicAddress", "Showing addr %s", addr.toString().c_str());
|
||||
|
||||
Online::RequestManager::get()->addRequest(m_request);
|
||||
m_state = REQUEST_PENDING;
|
||||
|
@ -45,14 +45,14 @@ void StopServer::asynchronousUpdate()
|
||||
{
|
||||
if (m_state == NONE)
|
||||
{
|
||||
TransportAddress addr = NetworkManager::getInstance()->getPublicAddress();
|
||||
const TransportAddress& addr = NetworkManager::getInstance()->getPublicAddress();
|
||||
m_request = new Online::XMLRequest();
|
||||
PlayerManager::setUserDetails(m_request, "stop", Online::API::SERVER_PATH);
|
||||
|
||||
m_request->addParameter("address", addr.ip);
|
||||
m_request->addParameter("port", addr.port);
|
||||
m_request->addParameter("address", addr.getIP());
|
||||
m_request->addParameter("port", addr.getPort());
|
||||
|
||||
Log::info("StopServer", "address %u, port %d", addr.ip, addr.port);
|
||||
Log::info("StopServer", "address %s", addr.toString().c_str());
|
||||
|
||||
Online::RequestManager::get()->addRequest(m_request);
|
||||
m_state = REQUEST_PENDING;
|
||||
|
@ -74,7 +74,7 @@ bool SynchronizationProtocol::notifyEventAsynchronous(Event* event)
|
||||
|
||||
if (request)
|
||||
{
|
||||
NetworkString response;
|
||||
NetworkString response(10);
|
||||
response.ai8(data.gui8(talk_id)).ai32(token).ai8(0).ai32(sequence);
|
||||
m_listener->sendMessage(this, peers[peer_id], response, false);
|
||||
Log::verbose("SynchronizationProtocol", "Answering sequence %u", sequence);
|
||||
@ -155,7 +155,7 @@ void SynchronizationProtocol::asynchronousUpdate()
|
||||
std::vector<STKPeer*> peers = NetworkManager::getInstance()->getPeers();
|
||||
for (unsigned int i = 0; i < peers.size(); i++)
|
||||
{
|
||||
NetworkString ns;
|
||||
NetworkString ns(10);
|
||||
ns.ai8(i).addUInt32(peers[i]->getClientServerToken()).addUInt8(1).addUInt32(m_pings[i].size());
|
||||
// now add the countdown if necessary
|
||||
if (m_countdown_activated && m_listener->isServer())
|
||||
|
@ -201,20 +201,20 @@ void STKHost::stopListening()
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void STKHost::sendRawPacket(uint8_t* data, int length, TransportAddress dst)
|
||||
void STKHost::sendRawPacket(uint8_t* data, int length, const TransportAddress& dst)
|
||||
{
|
||||
struct sockaddr_in to;
|
||||
int to_len = sizeof(to);
|
||||
memset(&to,0,to_len);
|
||||
|
||||
to.sin_family = AF_INET;
|
||||
to.sin_port = htons(dst.port);
|
||||
to.sin_addr.s_addr = htonl(dst.ip);
|
||||
to.sin_port = htons(dst.getPort());
|
||||
to.sin_addr.s_addr = htonl(dst.getIP());
|
||||
|
||||
sendto(m_host->socket, (char*)data, length, 0,(sockaddr*)&to, to_len);
|
||||
Log::verbose("STKHost", "Raw packet sent to %i.%i.%i.%i:%u", ((dst.ip>>24)&0xff)
|
||||
, ((dst.ip>>16)&0xff), ((dst.ip>>8)&0xff), ((dst.ip>>0)&0xff), dst.port);
|
||||
STKHost::logPacket(NetworkString(std::string((char*)(data), length)), false);
|
||||
Log::verbose("STKHost", "Raw packet sent to %s", dst.toString().c_str());
|
||||
STKHost::logPacket(NetworkString(std::string((char*)(data), length)),
|
||||
false);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -265,14 +265,12 @@ uint8_t* STKHost::receiveRawPacket(TransportAddress* sender)
|
||||
Log::error("STKHost", "Problem with the socket. Please contact the dev team.");
|
||||
}
|
||||
// we received the data
|
||||
sender->ip = ntohl((uint32_t)(addr.sin_addr.s_addr));
|
||||
sender->port = ntohs(addr.sin_port);
|
||||
sender->setIP( ntohl((uint32_t)(addr.sin_addr.s_addr)) );
|
||||
sender->setPort( ntohs(addr.sin_port) );
|
||||
|
||||
if (addr.sin_family == AF_INET)
|
||||
{
|
||||
char s[20];
|
||||
inet_ntop(AF_INET, &(addr.sin_addr), s, 20);
|
||||
Log::info("STKHost", "IPv4 Address of the sender was %s", s);
|
||||
Log::info("STKHost", "IPv4 Address of the sender was %s", sender->toString().c_str());
|
||||
}
|
||||
STKHost::logPacket(NetworkString(std::string((char*)(buffer), len)), true);
|
||||
return buffer;
|
||||
@ -280,7 +278,7 @@ uint8_t* STKHost::receiveRawPacket(TransportAddress* sender)
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
uint8_t* STKHost::receiveRawPacket(TransportAddress sender, int max_tries)
|
||||
uint8_t* STKHost::receiveRawPacket(const TransportAddress& sender, int max_tries)
|
||||
{
|
||||
uint8_t* buffer; // max size needed normally (only used for stun)
|
||||
buffer = (uint8_t*)(malloc(sizeof(uint8_t)*2048));
|
||||
@ -294,7 +292,7 @@ uint8_t* STKHost::receiveRawPacket(TransportAddress sender, int max_tries)
|
||||
|
||||
int i = 0;
|
||||
// wait to receive the message because enet sockets are non-blocking
|
||||
while(len < 0 || addr.sin_addr.s_addr == sender.ip)
|
||||
while(len < 0 || addr.sin_addr.s_addr == sender.getIP())
|
||||
{
|
||||
i++;
|
||||
if (len>=0)
|
||||
@ -335,12 +333,12 @@ void STKHost::broadcastPacket(const NetworkString& data, bool reliable)
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
bool STKHost::peerExists(TransportAddress peer)
|
||||
bool STKHost::peerExists(const TransportAddress& peer)
|
||||
{
|
||||
for (unsigned int i = 0; i < m_host->peerCount; i++)
|
||||
{
|
||||
if (m_host->peers[i].address.host == ntohl(peer.ip) &&
|
||||
m_host->peers[i].address.port == peer.port)
|
||||
if (m_host->peers[i].address.host == ntohl(peer.getIP()) &&
|
||||
m_host->peers[i].address.port == peer.getPort() )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@ -350,12 +348,11 @@ bool STKHost::peerExists(TransportAddress peer)
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
bool STKHost::isConnectedTo(TransportAddress peer)
|
||||
bool STKHost::isConnectedTo(const TransportAddress& peer)
|
||||
{
|
||||
for (unsigned int i = 0; i < m_host->peerCount; i++)
|
||||
{
|
||||
if (m_host->peers[i].address.host == ntohl(peer.ip) &&
|
||||
m_host->peers[i].address.port == peer.port &&
|
||||
if (peer == m_host->peers[i].address &&
|
||||
m_host->peers[i].state == ENET_PEER_STATE_CONNECTED)
|
||||
{
|
||||
return true;
|
||||
|
@ -118,7 +118,7 @@ class STKHost
|
||||
* \param dst : Destination of the packet.
|
||||
*/
|
||||
void sendRawPacket(uint8_t* data, int length,
|
||||
TransportAddress dst);
|
||||
const TransportAddress& dst);
|
||||
/*! \brief Receives a packet directly from the network interface.
|
||||
* Receive a packet whithout ENet processing it.
|
||||
* \return A string containing the data of the received packet.
|
||||
@ -138,7 +138,7 @@ class STKHost
|
||||
* \return A string containing the data of the received packet
|
||||
* matching the sender's ip address.
|
||||
*/
|
||||
uint8_t* receiveRawPacket(TransportAddress sender, int max_tries = -1);
|
||||
uint8_t* receiveRawPacket(const TransportAddress& sender, int max_tries = -1);
|
||||
/*! \brief Broadcasts a packet to all peers.
|
||||
* \param data : Data to send.
|
||||
*/
|
||||
@ -147,11 +147,11 @@ class STKHost
|
||||
/*! \brief Tells if a peer is known.
|
||||
* \return True if the peer is known, false elseway.
|
||||
*/
|
||||
bool peerExists(TransportAddress peer_address);
|
||||
bool peerExists(const TransportAddress& peer_address);
|
||||
/*! \brief Tells if a peer is known and connected.
|
||||
* \return True if the peer is known and connected, false elseway.
|
||||
*/
|
||||
bool isConnectedTo(TransportAddress peer_address);
|
||||
bool isConnectedTo(const TransportAddress& peer_address);
|
||||
|
||||
/*! \brief Returns true when the thread should stop listening. */
|
||||
int mustStopListening();
|
||||
|
@ -62,16 +62,10 @@ STKPeer::~STKPeer()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool STKPeer::connectToHost(STKHost* localhost, TransportAddress host,
|
||||
bool STKPeer::connectToHost(STKHost* localhost, const TransportAddress &host,
|
||||
uint32_t channel_count, uint32_t data)
|
||||
{
|
||||
ENetAddress address;
|
||||
address.host =
|
||||
((host.ip & 0xff000000) >> 24)
|
||||
+ ((host.ip & 0x00ff0000) >> 8)
|
||||
+ ((host.ip & 0x0000ff00) << 8)
|
||||
+ ((host.ip & 0x000000ff) << 24); // because ENet wants little endian
|
||||
address.port = host.port;
|
||||
const ENetAddress address = host.toEnetAddress();
|
||||
|
||||
ENetPeer* peer = enet_host_connect(localhost->m_host, &address, 2, 0);
|
||||
if (peer == NULL)
|
||||
@ -79,10 +73,8 @@ bool STKPeer::connectToHost(STKHost* localhost, TransportAddress host,
|
||||
Log::error("STKPeer", "Could not try to connect to server.\n");
|
||||
return false;
|
||||
}
|
||||
Log::verbose("STKPeer", "Connecting to %i.%i.%i.%i:%i.\nENetPeer address "
|
||||
"is %ld", (peer->address.host>>0)&0xff,
|
||||
(peer->address.host>>8)&0xff,(peer->address.host>>16)&0xff,
|
||||
(peer->address.host>>24)&0xff,peer->address.port, (long int)(peer));
|
||||
TransportAddress a(peer->address);
|
||||
Log::verbose("STKPeer", "Connecting to %s", a.toString().c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -97,10 +89,10 @@ void STKPeer::disconnect()
|
||||
|
||||
void STKPeer::sendPacket(NetworkString const& data, bool reliable)
|
||||
{
|
||||
Log::verbose("STKPeer", "sending packet of size %d to %i.%i.%i.%i:%i",
|
||||
data.size(), (m_peer->address.host>>0)&0xff,
|
||||
(m_peer->address.host>>8)&0xff,(m_peer->address.host>>16)&0xff,
|
||||
(m_peer->address.host>>24)&0xff,m_peer->address.port);
|
||||
TransportAddress a(m_peer->address);
|
||||
Log::verbose("STKPeer", "sending packet of size %d to %s",
|
||||
a.toString().c_str());
|
||||
|
||||
ENetPacket* packet = enet_packet_create(data.getBytes(), data.size() + 1,
|
||||
(reliable ? ENET_PACKET_FLAG_RELIABLE : ENET_PACKET_FLAG_UNSEQUENCED));
|
||||
/* to debug the packet output
|
||||
|
@ -41,7 +41,8 @@ class STKPeer
|
||||
virtual ~STKPeer();
|
||||
|
||||
virtual void sendPacket(const NetworkString& data, bool reliable = true);
|
||||
static bool connectToHost(STKHost* localhost, TransportAddress host, uint32_t channel_count, uint32_t data);
|
||||
static bool connectToHost(STKHost* localhost, const TransportAddress& host,
|
||||
uint32_t channel_count, uint32_t data);
|
||||
void disconnect();
|
||||
|
||||
void setClientServerToken(const uint32_t& token) { *m_client_server_token = token; *m_token_set = true; }
|
||||
|
@ -22,14 +22,15 @@
|
||||
#ifndef TYPES_HPP
|
||||
#define TYPES_HPP
|
||||
|
||||
#include "utils/no_copy.hpp"
|
||||
#include "utils/string_utils.hpp"
|
||||
#include "utils/types.hpp"
|
||||
|
||||
#include "enet/enet.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
/*! functions to write easily addresses in logs. */
|
||||
#define ADDRESS_FORMAT "%d.%d.%d.%d:%d"
|
||||
#define ADDRESS_ARGS(ip,port) ((ip>>24)&0xff),((ip>>16)&0xff),((ip>>8)&0xff),((ip>>0)&0xff),port
|
||||
|
||||
// ============================================================================
|
||||
/*! \class CallbackObject
|
||||
* \brief Class that must be inherited to pass objects to protocols.
|
||||
*/
|
||||
@ -39,29 +40,116 @@ class CallbackObject
|
||||
CallbackObject() {}
|
||||
~CallbackObject() {}
|
||||
|
||||
};
|
||||
}; // CallbackObject
|
||||
|
||||
// ============================================================================
|
||||
/*! \class TransportAddress
|
||||
* \brief Describes a transport-layer address.
|
||||
* For IP networks, a transport address is the couple ip:port.
|
||||
*/
|
||||
class TransportAddress : public CallbackObject
|
||||
class TransportAddress : public CallbackObject, public NoCopy
|
||||
{
|
||||
public:
|
||||
TransportAddress(uint32_t p_ip = 0, uint16_t p_port = 0)
|
||||
{ ip = p_ip; port = p_port; }
|
||||
private:
|
||||
uint32_t m_ip; //!< The IPv4 address
|
||||
uint16_t m_port; //!< The port number
|
||||
|
||||
public:
|
||||
/** Constructor. */
|
||||
TransportAddress(uint32_t ip = 0, uint16_t port = 0)
|
||||
{
|
||||
m_ip = ip;
|
||||
m_port = port;
|
||||
} // TransportAddress
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Construct an transport address from an ENetAddress. */
|
||||
TransportAddress(const ENetAddress &a)
|
||||
{
|
||||
m_ip = a.host;
|
||||
m_port = a.port;
|
||||
} // TransportAddress(EnetAddress)
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
~TransportAddress() {}
|
||||
// ------------------------------------------------------------------------
|
||||
/** A copy function (to replace the copy constructor which is disabled
|
||||
* using NoCopy). */
|
||||
void copy(const TransportAddress &other)
|
||||
{
|
||||
m_ip = other.m_ip;
|
||||
m_port = other.m_port;
|
||||
} // copy
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Resets ip and port to 0. */
|
||||
void clear()
|
||||
{
|
||||
m_ip = 0;
|
||||
m_port = 0;
|
||||
} // clear
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the ip address. */
|
||||
uint32_t getIP() const { return m_ip; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the port number. */
|
||||
uint16_t getPort() const { return m_port; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Sets the ip address. */
|
||||
void setIP(uint32_t ip) { m_ip = ip; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Set the port. */
|
||||
void setPort(uint16_t port) { m_port = port; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Converts the address to an enet address. */
|
||||
ENetAddress toEnetAddress() const
|
||||
{
|
||||
ENetAddress a;
|
||||
// because ENet wants little endian
|
||||
a.host = ((m_ip & 0xff000000) >> 24)
|
||||
+ ((m_ip & 0x00ff0000) >> 8)
|
||||
+ ((m_ip & 0x0000ff00) << 8)
|
||||
+ ((m_ip & 0x000000ff) << 24);
|
||||
a.port = m_port;
|
||||
return a;
|
||||
} // toEnetAddress
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Compares if ip address and port are identical. */
|
||||
bool operator==(const TransportAddress& other) const
|
||||
{ return other.ip == ip && other.port == port; }
|
||||
{
|
||||
return other.m_ip == m_ip && other.m_port == m_port;
|
||||
} // operator==
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
bool operator==(const ENetAddress& other)
|
||||
{
|
||||
return other.host == ntohl(m_ip) && other.port == m_port;
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
/** Compares if ip address or port are different. */
|
||||
bool operator!=(const TransportAddress& other) const
|
||||
{ return other.ip != ip || other.port != port; }
|
||||
|
||||
uint32_t ip; //!< The IPv4 address
|
||||
uint16_t port; //!< The port number
|
||||
};
|
||||
{
|
||||
return other.m_ip != m_ip || other.m_port != m_port;
|
||||
} // operator!=
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns a std::string representing the ip address and port in human
|
||||
* readable format. */
|
||||
std::string toString() const
|
||||
{
|
||||
return
|
||||
StringUtils::insertValues("%d.%d.%d.%d:%d",
|
||||
((m_ip >> 24) & 0xff), ((m_ip >> 16) & 0xff),
|
||||
((m_ip >> 8) & 0xff), ((m_ip >> 0) & 0xff),
|
||||
m_port );
|
||||
} // toString
|
||||
}; // TransportAddress
|
||||
|
||||
// ============================================================================
|
||||
/*! \class PlayerLogin
|
||||
* \brief Contains the information needed to authenticate a user.
|
||||
*/
|
||||
@ -73,7 +161,7 @@ class PlayerLogin : public CallbackObject
|
||||
|
||||
std::string username; //!< Username of the player
|
||||
std::string password; //!< Password of the player
|
||||
};
|
||||
}; // class PlayerLogin
|
||||
|
||||
|
||||
#endif // TYPES_HPP
|
||||
|
@ -28,7 +28,7 @@ namespace Online
|
||||
{
|
||||
Server::SortOrder Server::m_sort_order = Server::SO_NAME;
|
||||
|
||||
Server::Server(const XMLNode & xml)
|
||||
Server::Server(const XMLNode & xml, bool is_lan)
|
||||
{
|
||||
assert(xml.getName() == "server");
|
||||
|
||||
@ -37,9 +37,10 @@ namespace Online
|
||||
m_server_id = 0;
|
||||
m_current_players = 0;
|
||||
m_max_players = 0;
|
||||
m_is_lan = is_lan;
|
||||
|
||||
xml.get("name", &m_lower_case_name);
|
||||
m_name = StringUtils::xmlDecode(m_lower_case_name);
|
||||
m_name = StringUtils::xmlDecode(m_lower_case_name);
|
||||
m_lower_case_name = StringUtils::toLowerCase(m_lower_case_name);
|
||||
|
||||
xml.get("id", &m_server_id);
|
||||
@ -49,6 +50,18 @@ namespace Online
|
||||
|
||||
} // Server(const XML&)
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
Server::Server(const core::stringw &name, bool is_lan, int max_players,
|
||||
int current_players)
|
||||
{
|
||||
m_name = name;
|
||||
m_satisfaction_score = 0;
|
||||
m_server_id = 0;
|
||||
m_current_players = current_players;
|
||||
m_max_players = max_players;
|
||||
m_is_lan = is_lan;
|
||||
} // server(name, ...)
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/**
|
||||
* \brief Filter the add-on with a list of words.
|
||||
|
@ -65,6 +65,9 @@ namespace Online
|
||||
/** The score/rating given */
|
||||
float m_satisfaction_score;
|
||||
|
||||
/** True if this server is on the LAN, false otherwise. */
|
||||
bool m_is_lan;
|
||||
|
||||
/** The sort order to be used in the comparison. */
|
||||
static SortOrder m_sort_order;
|
||||
|
||||
@ -73,8 +76,9 @@ namespace Online
|
||||
public:
|
||||
|
||||
/** Initialises the object from an XML node. */
|
||||
Server(const XMLNode & xml);
|
||||
|
||||
Server(const XMLNode &xml, bool is_lan);
|
||||
Server(const core::stringw &name, bool is_lan, int max_players,
|
||||
int current_players);
|
||||
// ------------------------------------------------------------------------
|
||||
/** Sets the sort order used in the comparison function. It is static, so
|
||||
* that each instance can access the sort order. */
|
||||
|
@ -18,13 +18,14 @@
|
||||
|
||||
#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"
|
||||
|
||||
#include <assert.h>
|
||||
#include <irrString.h>
|
||||
#include <string>
|
||||
|
||||
#define SERVER_REFRESH_INTERVAL 5.0f
|
||||
|
||||
namespace Online
|
||||
@ -37,29 +38,31 @@ namespace Online
|
||||
manager_singleton = new ServersManager();
|
||||
|
||||
return manager_singleton;
|
||||
}
|
||||
} // get
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
void ServersManager::deallocate()
|
||||
{
|
||||
delete manager_singleton;
|
||||
manager_singleton = NULL;
|
||||
} // deallocate
|
||||
|
||||
// ============================================================================
|
||||
// ========================================================================
|
||||
ServersManager::ServersManager()
|
||||
{
|
||||
m_last_load_time.setAtomic(0.0f);
|
||||
m_joined_server.setAtomic(NULL);
|
||||
}
|
||||
} // ServersManager
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
ServersManager::~ServersManager()
|
||||
{
|
||||
cleanUpServers();
|
||||
MutexLocker(m_joined_server);
|
||||
delete m_joined_server.getData();
|
||||
}
|
||||
} // ~ServersManager
|
||||
|
||||
// ============================================================================
|
||||
// ------------------------------------------------------------------------
|
||||
void ServersManager::cleanUpServers()
|
||||
{
|
||||
m_sorted_servers.lock();
|
||||
@ -68,12 +71,12 @@ namespace Online
|
||||
m_mapped_servers.lock();
|
||||
m_mapped_servers.getData().clear();
|
||||
m_mapped_servers.unlock();
|
||||
}
|
||||
} // cleanUpServers
|
||||
|
||||
// ============================================================================
|
||||
ServersManager::RefreshRequest * ServersManager::refreshRequest(bool request_now) const
|
||||
// ------------------------------------------------------------------------
|
||||
ServersManager::RefreshRequest* ServersManager::refreshRequest(bool request_now) const
|
||||
{
|
||||
RefreshRequest * request = NULL;
|
||||
RefreshRequest* request = NULL;
|
||||
if(StkTime::getRealTime() - m_last_load_time.getAtomic() > SERVER_REFRESH_INTERVAL)
|
||||
{
|
||||
request = new RefreshRequest();
|
||||
@ -84,9 +87,14 @@ namespace Online
|
||||
}
|
||||
|
||||
return request;
|
||||
}
|
||||
} // refreshRequest
|
||||
|
||||
void ServersManager::refresh(bool success, const XMLNode * input)
|
||||
// ------------------------------------------------------------------------
|
||||
/** Callback from the refresh request.
|
||||
* \param success If the refresh was successful.
|
||||
* \param input The XML data describing the server.
|
||||
*/
|
||||
void ServersManager::refresh(bool success, const XMLNode *input)
|
||||
{
|
||||
if (!success)
|
||||
{
|
||||
@ -94,30 +102,31 @@ namespace Online
|
||||
return;
|
||||
}
|
||||
|
||||
const XMLNode * servers_xml = input->getNode("servers");
|
||||
const XMLNode *servers_xml = input->getNode("servers");
|
||||
cleanUpServers();
|
||||
for (unsigned int i = 0; i < servers_xml->getNumNodes(); i++)
|
||||
{
|
||||
addServer(new Server(*servers_xml->getNode(i)));
|
||||
addServer(new Server(*servers_xml->getNode(i), /*is_lan*/false));
|
||||
}
|
||||
m_last_load_time.setAtomic((float)StkTime::getRealTime());
|
||||
}
|
||||
} // refresh
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
void ServersManager::RefreshRequest::callback()
|
||||
{
|
||||
ServersManager::get()->refresh(isSuccess(), getXMLData());
|
||||
}
|
||||
} // callback
|
||||
|
||||
// ============================================================================
|
||||
const Server * ServersManager::getQuickPlay() const
|
||||
// ------------------------------------------------------------------------
|
||||
const Server* ServersManager::getQuickPlay() const
|
||||
{
|
||||
if(m_sorted_servers.getData().size() > 0)
|
||||
return getServerBySort(0);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
} // getQuickPlay
|
||||
|
||||
// ============================================================================
|
||||
// ------------------------------------------------------------------------
|
||||
void ServersManager::setJoinedServer(uint32_t id)
|
||||
{
|
||||
MutexLocker(m_joined_server);
|
||||
@ -125,18 +134,18 @@ namespace Online
|
||||
|
||||
// It's a copy!
|
||||
m_joined_server.getData() = new Server(*getServerByID(id));
|
||||
}
|
||||
} // setJoinedServer
|
||||
|
||||
// ============================================================================
|
||||
// ------------------------------------------------------------------------
|
||||
void ServersManager::unsetJoinedServer()
|
||||
{
|
||||
MutexLocker(m_joined_server);
|
||||
delete m_joined_server.getData();
|
||||
m_joined_server.getData() = NULL;
|
||||
}
|
||||
} // unsetJoinedServer
|
||||
|
||||
// ============================================================================
|
||||
void ServersManager::addServer(Server * server)
|
||||
// ------------------------------------------------------------------------
|
||||
void ServersManager::addServer(Server *server)
|
||||
{
|
||||
m_sorted_servers.lock();
|
||||
m_sorted_servers.getData().push_back(server);
|
||||
@ -145,40 +154,40 @@ namespace Online
|
||||
m_mapped_servers.lock();
|
||||
m_mapped_servers.getData()[server->getServerId()] = server;
|
||||
m_mapped_servers.unlock();
|
||||
}
|
||||
} // addServer
|
||||
|
||||
// ============================================================================
|
||||
// ------------------------------------------------------------------------
|
||||
int ServersManager::getNumServers () const
|
||||
{
|
||||
MutexLocker(m_sorted_servers);
|
||||
return m_sorted_servers.getData().size();
|
||||
}
|
||||
} // getNumServers
|
||||
|
||||
// ============================================================================
|
||||
const Server * ServersManager::getServerBySort (int index) const
|
||||
// ------------------------------------------------------------------------
|
||||
const Server* ServersManager::getServerBySort (int index) const
|
||||
{
|
||||
MutexLocker(m_sorted_servers);
|
||||
return m_sorted_servers.getData().get(index);
|
||||
}
|
||||
} // getServerBySort
|
||||
|
||||
// ============================================================================
|
||||
const Server * ServersManager::getServerByID (uint32_t id) const
|
||||
// ------------------------------------------------------------------------
|
||||
const Server* ServersManager::getServerByID (uint32_t id) const
|
||||
{
|
||||
MutexLocker(m_mapped_servers);
|
||||
return m_mapped_servers.getData().at(id);
|
||||
}
|
||||
} // getServerByID
|
||||
|
||||
// ============================================================================
|
||||
Server * ServersManager::getJoinedServer() const
|
||||
// ------------------------------------------------------------------------
|
||||
Server* ServersManager::getJoinedServer() const
|
||||
{
|
||||
return m_joined_server.getAtomic();
|
||||
}
|
||||
} // getJoinedServer
|
||||
|
||||
// ============================================================================
|
||||
// ------------------------------------------------------------------------
|
||||
void ServersManager::sort(bool sort_desc)
|
||||
{
|
||||
MutexLocker(m_sorted_servers);
|
||||
m_sorted_servers.getData().insertionSort(0, sort_desc);
|
||||
}
|
||||
} // sort
|
||||
|
||||
} // namespace Online
|
||||
|
@ -19,12 +19,12 @@
|
||||
#ifndef HEADER_SERVERS_MANAGER_HPP
|
||||
#define HEADER_SERVERS_MANAGER_HPP
|
||||
|
||||
#include "utils/ptr_vector.hpp"
|
||||
#include "utils/types.hpp"
|
||||
#include "online/server.hpp"
|
||||
#include "online/request_manager.hpp"
|
||||
#include "online/server.hpp"
|
||||
#include "online/xml_request.hpp"
|
||||
#include "utils/ptr_vector.hpp"
|
||||
#include "utils/synchronised.hpp"
|
||||
#include "utils/types.hpp"
|
||||
|
||||
namespace Online
|
||||
{
|
||||
@ -35,17 +35,19 @@ namespace Online
|
||||
class ServersManager
|
||||
{
|
||||
public:
|
||||
|
||||
// ====================================================================
|
||||
class RefreshRequest : public XMLRequest
|
||||
{
|
||||
virtual void callback ();
|
||||
public:
|
||||
RefreshRequest() : XMLRequest() {}
|
||||
};
|
||||
}; // RefreshRequest
|
||||
// ====================================================================
|
||||
|
||||
private:
|
||||
ServersManager();
|
||||
~ServersManager();
|
||||
|
||||
/** Sorted vector of servers */
|
||||
Synchronised<PtrVector<Server> > m_sorted_servers;
|
||||
|
||||
@ -53,29 +55,29 @@ namespace Online
|
||||
Synchronised<std::map<uint32_t, Server*> > m_mapped_servers;
|
||||
|
||||
/** This is a pointer to a copy of the server, the moment it got joined */
|
||||
Synchronised<Server *> m_joined_server;
|
||||
Synchronised<Server *> m_joined_server;
|
||||
|
||||
Synchronised<float> m_last_load_time;
|
||||
void refresh(bool success, const XMLNode * input);
|
||||
void cleanUpServers();
|
||||
Synchronised<float> m_last_load_time;
|
||||
void refresh(bool success, const XMLNode * input);
|
||||
void cleanUpServers();
|
||||
|
||||
public:
|
||||
// Singleton
|
||||
static ServersManager* get();
|
||||
static void deallocate();
|
||||
static ServersManager* get();
|
||||
static void deallocate();
|
||||
|
||||
RefreshRequest * refreshRequest(bool request_now = true) const;
|
||||
void setJoinedServer(uint32_t server_id);
|
||||
void unsetJoinedServer();
|
||||
void addServer(Server * server);
|
||||
int getNumServers () const;
|
||||
const Server * getServerByID (uint32_t server_id) const;
|
||||
const Server * getServerBySort (int index) const;
|
||||
void sort(bool sort_desc);
|
||||
Server * getJoinedServer() const;
|
||||
RefreshRequest * refreshRequest(bool request_now = true) const;
|
||||
void setJoinedServer(uint32_t server_id);
|
||||
void unsetJoinedServer();
|
||||
void addServer(Server * server);
|
||||
int getNumServers () const;
|
||||
const Server * getServerByID (uint32_t server_id) const;
|
||||
const Server * getServerBySort (int index) const;
|
||||
void sort(bool sort_desc);
|
||||
Server * getJoinedServer() const;
|
||||
|
||||
// Returns the best server to join
|
||||
const Server * getQuickPlay() const;
|
||||
const Server * getQuickPlay() const;
|
||||
|
||||
}; // class ServersManager
|
||||
} // namespace Online
|
||||
|
@ -117,6 +117,14 @@ namespace Scripting
|
||||
return SimpleVec3(velocity.getX(), velocity.getY(), velocity.getZ());
|
||||
}
|
||||
|
||||
/** Gets the maximum speed (velocity) a kart can reach */
|
||||
float getMaxSpeed(int idKart)
|
||||
{
|
||||
AbstractKart* kart = World::getWorld()->getKart(idKart);
|
||||
return kart->getKartProperties()->getMaxSpeed() *
|
||||
kart->getPlayerDifficulty()->getMaxSpeed();
|
||||
}
|
||||
|
||||
/** @}*/
|
||||
/** @}*/
|
||||
|
||||
@ -130,6 +138,7 @@ namespace Scripting
|
||||
//r = engine->RegisterGlobalFunction("void jumpTo(int id, float x, float y)", asFUNCTION(jumpTo), asCALL_GENERIC); assert(r >= 0);
|
||||
r = engine->RegisterGlobalFunction("Vec3 getLocation(int id)", asFUNCTION(getLocation), asCALL_CDECL); assert(r >= 0);
|
||||
r = engine->RegisterGlobalFunction("Vec3 getVelocity(int id)", asFUNCTION(getVelocity), asCALL_CDECL); assert(r >= 0);
|
||||
r = engine->RegisterGlobalFunction("float getMaxSpeed(int id)", asFUNCTION(getMaxSpeed), asCALL_CDECL); assert(r >= 0);
|
||||
}
|
||||
|
||||
void registerScriptEnums(asIScriptEngine *engine)
|
||||
|
@ -11,13 +11,15 @@
|
||||
#ifndef SCRIPTSTDSTRING_H
|
||||
#define SCRIPTSTDSTRING_H
|
||||
|
||||
// String must be included before angelscript.h to avoid some errors during
|
||||
// compilation with GetObject function
|
||||
#include <string>
|
||||
|
||||
#ifndef ANGELSCRIPT_H
|
||||
// Avoid having to inform include path if header is already include before
|
||||
#include <angelscript.h>
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
|
||||
//---------------------------
|
||||
// Compilation settings
|
||||
//
|
||||
|
@ -47,6 +47,7 @@ DEFINE_SCREEN_SINGLETON( CreateServerScreen );
|
||||
CreateServerScreen::CreateServerScreen() : Screen("online/create_server.stkgui")
|
||||
{
|
||||
m_server_creation_request = NULL;
|
||||
m_is_lan = false;
|
||||
} // CreateServerScreen
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -80,8 +81,6 @@ void CreateServerScreen::beforeAddingWidget()
|
||||
|
||||
} // beforeAddingWidget
|
||||
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void CreateServerScreen::init()
|
||||
{
|
||||
@ -89,7 +88,12 @@ void CreateServerScreen::init()
|
||||
setInitialFocus();
|
||||
DemoWorld::resetIdleTime();
|
||||
m_info_widget->setText("", false);
|
||||
}
|
||||
LabelWidget *title = getWidget<LabelWidget>("title");
|
||||
|
||||
title->setText(m_is_lan ? _("Create LAN Server")
|
||||
: _("Create Server") , false);
|
||||
} // init
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void CreateServerScreen::onUpdate(float delta)
|
||||
{
|
||||
@ -99,7 +103,8 @@ void CreateServerScreen::onUpdate(float delta)
|
||||
{
|
||||
if(m_server_creation_request->isSuccess())
|
||||
{
|
||||
new ServerInfoDialog(m_server_creation_request->getCreatedServerID(), true);
|
||||
new ServerInfoDialog(m_server_creation_request->getCreatedServerID(),
|
||||
true);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -124,22 +129,36 @@ void CreateServerScreen::onUpdate(float delta)
|
||||
// ----------------------------------------------------------------------------
|
||||
void CreateServerScreen::serverCreationRequest()
|
||||
{
|
||||
if (m_is_lan)
|
||||
{
|
||||
const irr::core::stringw name = m_name_widget->getText().trim();
|
||||
const int max_players = m_max_players_widget->getValue();
|
||||
Server *server = new Server(name, /*lan*/true, max_players,
|
||||
/*current_player*/1);
|
||||
ServersManager::get()->addServer(server);
|
||||
return;
|
||||
}
|
||||
|
||||
// Now must be WAN: forward request to the stk server
|
||||
const irr::core::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);
|
||||
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);
|
||||
m_info_widget->setText(
|
||||
_("The maxinum number of players has to be between 2 and 12."), false);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
m_server_creation_request = new ServerCreationRequest();
|
||||
PlayerManager::setUserDetails(m_server_creation_request, "create", Online::API::SERVER_PATH);
|
||||
PlayerManager::setUserDetails(m_server_creation_request, "create",
|
||||
Online::API::SERVER_PATH);
|
||||
m_server_creation_request->addParameter("name", name);
|
||||
m_server_creation_request->addParameter("max_players", max_players);
|
||||
m_server_creation_request->queue();
|
||||
@ -147,13 +166,18 @@ void CreateServerScreen::serverCreationRequest()
|
||||
return;
|
||||
}
|
||||
SFXManager::get()->quickSound("anvil");
|
||||
}
|
||||
// --------------------------------------------------------------------
|
||||
} // serverCreationRequest
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Callbacks from the online create server request.
|
||||
*/
|
||||
void CreateServerScreen::ServerCreationRequest::callback()
|
||||
{
|
||||
if (isSuccess())
|
||||
{
|
||||
Server *server = new Server(*getXMLData()->getNode("server"));
|
||||
// Must be a WAN server
|
||||
Server *server = new Server(*getXMLData()->getNode("server"),
|
||||
/*is lan*/false);
|
||||
ServersManager::get()->addServer(server);
|
||||
m_created_server_id = server->getServerId();
|
||||
} // isSuccess
|
||||
@ -165,7 +189,8 @@ void CreateServerScreen::eventCallback(Widget* widget, const std::string& name,
|
||||
{
|
||||
if (name == m_options_widget->m_properties[PROP_ID])
|
||||
{
|
||||
const std::string& selection = m_options_widget->getSelectionIDString(PLAYER_ID_GAME_MASTER);
|
||||
const std::string& selection =
|
||||
m_options_widget->getSelectionIDString(PLAYER_ID_GAME_MASTER);
|
||||
if (selection == m_cancel_widget->m_properties[PROP_ID])
|
||||
{
|
||||
StateManager::get()->escapePressed();
|
||||
@ -173,7 +198,7 @@ void CreateServerScreen::eventCallback(Widget* widget, const std::string& name,
|
||||
else if (selection == m_create_widget->m_properties[PROP_ID])
|
||||
{
|
||||
serverCreationRequest();
|
||||
}
|
||||
} // is create_widget
|
||||
}
|
||||
} // eventCallback
|
||||
|
||||
|
@ -35,6 +35,9 @@ class CreateServerScreen : public GUIEngine::Screen,
|
||||
private:
|
||||
friend class GUIEngine::ScreenSingleton<CreateServerScreen>;
|
||||
|
||||
/** */
|
||||
bool m_is_lan;
|
||||
|
||||
CreateServerScreen();
|
||||
|
||||
GUIEngine::TextBoxWidget * m_name_widget;
|
||||
@ -93,6 +96,10 @@ public:
|
||||
|
||||
/** \brief Implements the callback when a dialog gets closed. */
|
||||
virtual void onDialogClose() OVERRIDE;
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Sets if a lan or wan server is to be created. */
|
||||
void setIsLan(bool is_lan) { m_is_lan = is_lan; }
|
||||
}; // class CreateServerScreen
|
||||
|
||||
#endif
|
||||
|
@ -20,7 +20,7 @@
|
||||
#include "input/input.hpp"
|
||||
#include "input/input_manager.hpp"
|
||||
#include "states_screens/dialogs/press_a_key_dialog.hpp"
|
||||
#include "states_screens/options_screen_input2.hpp"
|
||||
#include "states_screens/options_screen_device.hpp"
|
||||
#include "utils/translation.hpp"
|
||||
|
||||
using namespace GUIEngine;
|
||||
@ -47,13 +47,13 @@ GUIEngine::EventPropagation PressAKeyDialog::processEvent(const std::string& eve
|
||||
else if (eventSource == "assignNone")
|
||||
{
|
||||
Input simulatedInput;
|
||||
OptionsScreenInput2::getInstance()->gotSensedInput(simulatedInput);
|
||||
OptionsScreenDevice::getInstance()->gotSensedInput(simulatedInput);
|
||||
return GUIEngine::EVENT_BLOCK;
|
||||
}
|
||||
else if (eventSource == "assignEsc")
|
||||
{
|
||||
Input simulatedInput(Input::IT_KEYBOARD, 0 /* deviceID */, KEY_ESCAPE);
|
||||
OptionsScreenInput2::getInstance()->gotSensedInput(simulatedInput);
|
||||
OptionsScreenDevice::getInstance()->gotSensedInput(simulatedInput);
|
||||
return GUIEngine::EVENT_BLOCK;
|
||||
}
|
||||
|
||||
|
@ -37,10 +37,13 @@ using namespace Online;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
ServerInfoDialog::ServerInfoDialog(uint32_t server_id, uint32_t host_id, bool from_server_creation)
|
||||
: ModalDialog(0.8f,0.8f), m_server_id(server_id), m_host_id(host_id)
|
||||
ServerInfoDialog::ServerInfoDialog(uint32_t server_id, uint32_t host_id,
|
||||
bool from_server_creation)
|
||||
: ModalDialog(0.8f,0.8f), m_server_id(server_id),
|
||||
m_host_id(host_id)
|
||||
{
|
||||
Log::info("ServerInfoDialog", "Server id is %d, Host id is %d", server_id, host_id);
|
||||
Log::info("ServerInfoDialog", "Server id is %d, Host id is %d",
|
||||
server_id, host_id);
|
||||
m_self_destroy = false;
|
||||
m_enter_lobby = false;
|
||||
m_from_server_creation = from_server_creation;
|
||||
@ -67,6 +70,7 @@ ServerInfoDialog::ServerInfoDialog(uint32_t server_id, uint32_t host_id, bool fr
|
||||
} // ServerInfoDialog
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
ServerInfoDialog::~ServerInfoDialog()
|
||||
{
|
||||
if (m_server_join_request)
|
||||
|
@ -35,25 +35,25 @@ using namespace GUIEngine;
|
||||
DEFINE_SCREEN_SINGLETON( EditGPScreen );
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
EditGPScreen::EditGPScreen()
|
||||
: Screen("gpedit.stkgui"), m_gp(NULL), m_list(NULL), m_icon_bank(NULL),
|
||||
m_selected(-1), m_modified(false)
|
||||
EditGPScreen::EditGPScreen() : Screen("edit_gp.stkgui"), m_gp(NULL),
|
||||
m_list(NULL), m_icon_bank(NULL),
|
||||
m_selected(-1), m_modified(false)
|
||||
{
|
||||
|
||||
}
|
||||
} // EditGPScreen
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
EditGPScreen::~EditGPScreen()
|
||||
{
|
||||
delete m_icon_bank;
|
||||
}
|
||||
} // ~EditGPScreen
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
void EditGPScreen::setSelectedGP(GrandPrixData* gp)
|
||||
{
|
||||
assert(gp != NULL);
|
||||
m_gp = gp;
|
||||
}
|
||||
} // setSelectedGP
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
void EditGPScreen::loadedFromFile()
|
||||
@ -66,11 +66,12 @@ void EditGPScreen::loadedFromFile()
|
||||
m_list->addColumn(_("Track"), 3);
|
||||
m_list->addColumn(_("Laps"), 1);
|
||||
m_list->addColumn(_("Reversed"), 1);
|
||||
}
|
||||
} // loadedFromFile
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
void EditGPScreen::eventCallback(GUIEngine::Widget* widget, const std::string& name,
|
||||
const int playerID)
|
||||
void EditGPScreen::eventCallback(GUIEngine::Widget* widget,
|
||||
const std::string& name,
|
||||
const int playerID)
|
||||
{
|
||||
setSelected(m_list->getSelectionID());
|
||||
|
||||
@ -146,7 +147,7 @@ void EditGPScreen::eventCallback(GUIEngine::Widget* widget, const std::string& n
|
||||
back();
|
||||
}
|
||||
}
|
||||
}
|
||||
} // eventCallback
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
void EditGPScreen::init()
|
||||
@ -191,7 +192,7 @@ void EditGPScreen::init()
|
||||
m_action.clear();
|
||||
}
|
||||
enableButtons();
|
||||
}
|
||||
} // init
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
void EditGPScreen::onConfirm()
|
||||
@ -210,7 +211,7 @@ void EditGPScreen::onConfirm()
|
||||
save();
|
||||
back();
|
||||
}
|
||||
}
|
||||
} // onConfirm
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
void EditGPScreen::onCancel()
|
||||
@ -221,7 +222,7 @@ void EditGPScreen::onCancel()
|
||||
m_gp->reload(); // Discard changes
|
||||
back();
|
||||
}
|
||||
}
|
||||
} // onCancel
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
void EditGPScreen::loadList(const int selected)
|
||||
@ -268,7 +269,7 @@ void EditGPScreen::loadList(const int selected)
|
||||
{
|
||||
enableButtons();
|
||||
}
|
||||
}
|
||||
} // loadList
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
void EditGPScreen::setModified(const bool modified)
|
||||
@ -285,14 +286,14 @@ void EditGPScreen::setModified(const bool modified)
|
||||
header->setText(modified ? _(L"%s (+)", m_gp->getName()) : L"", true);
|
||||
|
||||
enableButtons();
|
||||
}
|
||||
} // setModified
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
void EditGPScreen::setSelected(const int selected)
|
||||
{
|
||||
m_selected = selected;
|
||||
enableButtons();
|
||||
}
|
||||
} // setSelected
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
void EditGPScreen::edit()
|
||||
@ -308,7 +309,7 @@ void EditGPScreen::edit()
|
||||
m_gp->getReverse((unsigned int)m_selected));
|
||||
edit_screen->push();
|
||||
}
|
||||
}
|
||||
} // edit
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
bool EditGPScreen::save()
|
||||
@ -325,7 +326,7 @@ bool EditGPScreen::save()
|
||||
MessageDialog::MESSAGE_DIALOG_OK, NULL, false);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} // save
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
void EditGPScreen::back()
|
||||
@ -333,19 +334,19 @@ void EditGPScreen::back()
|
||||
m_action.clear();
|
||||
m_modified = false;
|
||||
StateManager::get()->popMenu();
|
||||
}
|
||||
} // back
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
bool EditGPScreen::canMoveUp() const
|
||||
{
|
||||
return (0 < m_selected && m_selected < m_list->getItemCount());
|
||||
}
|
||||
} // canMoveUp
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
bool EditGPScreen::canMoveDown() const
|
||||
{
|
||||
return (0 <= m_selected && m_selected < m_list->getItemCount() - 1);
|
||||
}
|
||||
} // canMoveDown
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
void EditGPScreen::enableButtons()
|
||||
@ -365,4 +366,4 @@ void EditGPScreen::enableButtons()
|
||||
|
||||
edit_button->setActive(m_selected >= 0);
|
||||
remove_button->setActive(m_selected >= 0);
|
||||
}
|
||||
} // enableButtons
|
||||
|
@ -40,8 +40,9 @@ DEFINE_SCREEN_SINGLETON( GrandPrixEditorScreen );
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
GrandPrixEditorScreen::GrandPrixEditorScreen()
|
||||
: Screen("gpeditor.stkgui"), m_selection(NULL), m_gpgroup(GrandPrixData::GP_NONE)
|
||||
GrandPrixEditorScreen::GrandPrixEditorScreen()
|
||||
: Screen("grand_prix_editor.stkgui"), m_selection(NULL),
|
||||
m_gpgroup(GrandPrixData::GP_NONE)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -72,7 +72,7 @@ bool MainMenuScreen::m_enable_online = false;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
MainMenuScreen::MainMenuScreen() : Screen("main.stkgui")
|
||||
MainMenuScreen::MainMenuScreen() : Screen("main_menu.stkgui")
|
||||
{
|
||||
} // MainMenuScreen
|
||||
|
||||
|
@ -45,7 +45,7 @@ DEFINE_SCREEN_SINGLETON( NetworkingLobby );
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
NetworkingLobby::NetworkingLobby() : Screen("online/lobby.stkgui")
|
||||
NetworkingLobby::NetworkingLobby() : Screen("online/networking_lobby.stkgui")
|
||||
{
|
||||
m_server = NULL;
|
||||
} // NetworkingLobby
|
||||
@ -107,7 +107,7 @@ void NetworkingLobby::eventCallback(Widget* widget, const std::string& name, con
|
||||
|
||||
RibbonWidget* ribbon = dynamic_cast<RibbonWidget*>(widget);
|
||||
if (ribbon == NULL) return;
|
||||
std::string selection = ribbon->getSelectionIDString(PLAYER_ID_GAME_MASTER);
|
||||
const std::string &selection = ribbon->getSelectionIDString(PLAYER_ID_GAME_MASTER);
|
||||
|
||||
if (selection == m_exit_widget->m_properties[PROP_ID])
|
||||
{
|
||||
|
@ -26,21 +26,20 @@
|
||||
#include "input/device_manager.hpp"
|
||||
#include "input/input_manager.hpp"
|
||||
#include "io/file_manager.hpp"
|
||||
#include "main_loop.hpp"
|
||||
#include "modes/demo_world.hpp"
|
||||
#include "network/protocol_manager.hpp"
|
||||
#include "network/protocol_manager.hpp"
|
||||
#include "network/protocols/connect_to_server.hpp"
|
||||
#include "network/protocols/request_connection.hpp"
|
||||
#include "online/profile_manager.hpp"
|
||||
#include "online/request.hpp"
|
||||
#include "online/servers_manager.hpp"
|
||||
#include "states_screens/state_manager.hpp"
|
||||
#include "states_screens/create_server_screen.hpp"
|
||||
#include "states_screens/dialogs/message_dialog.hpp"
|
||||
#include "states_screens/networking_lobby.hpp"
|
||||
#include "states_screens/server_selection.hpp"
|
||||
#include "states_screens/create_server_screen.hpp"
|
||||
#include "states_screens/online_profile_achievements.hpp"
|
||||
#include "states_screens/server_selection.hpp"
|
||||
#include "states_screens/state_manager.hpp"
|
||||
#include "states_screens/user_screen.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
@ -53,7 +52,7 @@ DEFINE_SCREEN_SINGLETON( OnlineScreen );
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
OnlineScreen::OnlineScreen() : Screen("online/main.stkgui")
|
||||
OnlineScreen::OnlineScreen() : Screen("online/online_screen.stkgui")
|
||||
{
|
||||
m_recorded_state = PlayerProfile::OS_SIGNED_OUT;
|
||||
} // OnlineScreen
|
||||
@ -68,26 +67,34 @@ OnlineScreen::~OnlineScreen()
|
||||
|
||||
void OnlineScreen::loadedFromFile()
|
||||
{
|
||||
m_user_id = getWidget<ButtonWidget>("user-id");
|
||||
assert(m_user_id);
|
||||
|
||||
m_back_widget = getWidget<IconButtonWidget>("back");
|
||||
assert(m_back_widget != NULL);
|
||||
|
||||
m_top_menu_widget = getWidget<RibbonWidget>("menu_toprow");
|
||||
m_top_menu_widget = getWidget<RibbonWidget>("menu_top_row");
|
||||
assert(m_top_menu_widget != NULL);
|
||||
m_quick_play_widget = (IconButtonWidget *) m_top_menu_widget->findWidgetNamed("quick_play");
|
||||
assert(m_quick_play_widget != NULL);
|
||||
m_find_server_widget = (IconButtonWidget *) m_top_menu_widget->findWidgetNamed("find_server");
|
||||
assert(m_find_server_widget != NULL);
|
||||
m_create_server_widget = (IconButtonWidget *) m_top_menu_widget->findWidgetNamed("create_server");
|
||||
assert(m_create_server_widget != NULL);
|
||||
|
||||
m_online_status_widget = getWidget<LabelWidget>("online_status");
|
||||
assert(m_online_status_widget != NULL);
|
||||
m_find_lan_server_widget = getWidget<IconButtonWidget>("find_lan_server");
|
||||
assert(m_find_lan_server_widget != NULL);
|
||||
m_create_lan_server_widget = getWidget<IconButtonWidget>("create_lan_server");
|
||||
assert(m_create_lan_server_widget != NULL);
|
||||
m_manage_user = getWidget<IconButtonWidget>("manage_user");
|
||||
assert(m_manage_user);
|
||||
|
||||
m_find_wan_server_widget = getWidget<IconButtonWidget>("find_wan_server");
|
||||
assert(m_find_wan_server_widget != NULL);
|
||||
m_create_wan_server_widget = getWidget<IconButtonWidget>("create_wan_server");
|
||||
assert(m_create_wan_server_widget != NULL);
|
||||
m_quick_wan_play_widget = getWidget<IconButtonWidget>("quick_wan_play");
|
||||
assert(m_quick_wan_play_widget != NULL);
|
||||
|
||||
m_bottom_menu_widget = getWidget<RibbonWidget>("menu_bottomrow");
|
||||
assert(m_bottom_menu_widget != NULL);
|
||||
m_profile_widget = (IconButtonWidget *) m_bottom_menu_widget->findWidgetNamed("profile");
|
||||
m_profile_widget = getWidget<IconButtonWidget>("profile");
|
||||
assert(m_profile_widget != NULL);
|
||||
m_sign_out_widget = (IconButtonWidget *) m_bottom_menu_widget->findWidgetNamed("sign_out");
|
||||
m_sign_out_widget = getWidget<IconButtonWidget>("sign_out");
|
||||
assert(m_sign_out_widget != NULL);
|
||||
|
||||
} // loadedFromFile
|
||||
@ -107,7 +114,8 @@ bool OnlineScreen::hasStateChanged()
|
||||
// ----------------------------------------------------------------------------
|
||||
void OnlineScreen::beforeAddingWidget()
|
||||
{
|
||||
//Set everything that could be set invisible or deactivated, to active and visible
|
||||
// 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();
|
||||
@ -115,18 +123,26 @@ void OnlineScreen::beforeAddingWidget()
|
||||
m_recorded_state == PlayerProfile::OS_SIGNING_IN ||
|
||||
m_recorded_state == PlayerProfile::OS_SIGNING_OUT)
|
||||
{
|
||||
m_quick_play_widget->setActive(false);
|
||||
m_find_server_widget->setActive(false);
|
||||
m_create_server_widget->setActive(false);
|
||||
m_quick_wan_play_widget->setActive(false);
|
||||
m_find_wan_server_widget->setActive(false);
|
||||
m_create_wan_server_widget->setActive(false);
|
||||
m_sign_out_widget->setVisible(false);
|
||||
m_profile_widget->setVisible(false);
|
||||
}
|
||||
else if (m_recorded_state == PlayerProfile::OS_GUEST)
|
||||
{
|
||||
m_find_server_widget->setActive(false);
|
||||
m_create_server_widget->setActive(false);
|
||||
m_find_wan_server_widget->setActive(false);
|
||||
m_create_wan_server_widget->setActive(false);
|
||||
m_profile_widget->setVisible(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_quick_wan_play_widget->setActive(true);
|
||||
m_find_wan_server_widget->setActive(true);
|
||||
m_create_wan_server_widget->setActive(true);
|
||||
m_sign_out_widget->setVisible(true);
|
||||
m_profile_widget->setVisible(true);
|
||||
}
|
||||
|
||||
} // beforeAddingWidget
|
||||
|
||||
@ -136,30 +152,28 @@ void OnlineScreen::init()
|
||||
Screen::init();
|
||||
setInitialFocus();
|
||||
DemoWorld::resetIdleTime();
|
||||
core::stringw m = _("Logged in as: %s.",
|
||||
PlayerManager::getCurrentOnlineUserName());
|
||||
m_online_status_widget->setText(m, false);
|
||||
|
||||
} // init
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void OnlineScreen::onUpdate(float delta)
|
||||
{
|
||||
PlayerProfile *player = PlayerManager::getCurrentPlayer();
|
||||
if (PlayerManager::getCurrentOnlineState() == PlayerProfile::OS_SIGNED_IN)
|
||||
{
|
||||
m_user_id->setText(player->getLastOnlineName() + "@stk");
|
||||
}
|
||||
else
|
||||
{
|
||||
m_user_id->setText(player->getName());
|
||||
}
|
||||
|
||||
if (hasStateChanged())
|
||||
{
|
||||
GUIEngine::reshowCurrentScreen();
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_recorded_state == PlayerProfile::OS_SIGNING_IN)
|
||||
{
|
||||
m_online_status_widget->setText(StringUtils::loadingDots(_("Logging in")),
|
||||
false );
|
||||
}
|
||||
else if (m_recorded_state == PlayerProfile::OS_SIGNING_OUT)
|
||||
{
|
||||
m_online_status_widget->setText(StringUtils::loadingDots(_("Logging out")),
|
||||
false );
|
||||
}
|
||||
} // onUpdate
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -191,7 +205,8 @@ void OnlineScreen::doQuickPlay()
|
||||
return;
|
||||
}
|
||||
|
||||
PlayerManager::setUserDetails(join_request, "request-connection", Online::API::SERVER_PATH);
|
||||
PlayerManager::setUserDetails(join_request, "request-connection",
|
||||
Online::API::SERVER_PATH);
|
||||
join_request->addParameter("server_id", server->getServerId());
|
||||
|
||||
join_request->executeNow();
|
||||
@ -230,20 +245,36 @@ void OnlineScreen::eventCallback(Widget* widget, const std::string& name,
|
||||
PlayerManager::requestSignOut();
|
||||
StateManager::get()->popMenu();
|
||||
}
|
||||
else if (selection == m_create_lan_server_widget->m_properties[PROP_ID])
|
||||
{
|
||||
CreateServerScreen::getInstance()->setIsLan(true);
|
||||
CreateServerScreen::getInstance()->push();
|
||||
// TODO: create lan server
|
||||
}
|
||||
else if (selection == m_find_lan_server_widget->m_properties[PROP_ID])
|
||||
{
|
||||
ServerSelection::getInstance()->push();
|
||||
// TODO: find lan server;
|
||||
}
|
||||
else if (selection == m_manage_user->m_properties[PROP_ID])
|
||||
{
|
||||
UserScreen::getInstance()->push();
|
||||
}
|
||||
else if (selection == m_profile_widget->m_properties[PROP_ID])
|
||||
{
|
||||
ProfileManager::get()->setVisiting(PlayerManager::getCurrentOnlineId());
|
||||
OnlineProfileAchievements::getInstance()->push();
|
||||
}
|
||||
else if (selection == m_find_server_widget->m_properties[PROP_ID])
|
||||
else if (selection == m_find_wan_server_widget->m_properties[PROP_ID])
|
||||
{
|
||||
ServerSelection::getInstance()->push();
|
||||
}
|
||||
else if (selection == m_create_server_widget->m_properties[PROP_ID])
|
||||
else if (selection == m_create_wan_server_widget->m_properties[PROP_ID])
|
||||
{
|
||||
CreateServerScreen::getInstance()->setIsLan(false);
|
||||
CreateServerScreen::getInstance()->push();
|
||||
}
|
||||
else if (selection == m_quick_play_widget->m_properties[PROP_ID])
|
||||
else if (selection == m_quick_wan_play_widget->m_properties[PROP_ID])
|
||||
{
|
||||
doQuickPlay();
|
||||
}
|
||||
|
@ -25,7 +25,7 @@
|
||||
#include "guiengine/widgets/icon_button_widget.hpp"
|
||||
#include "utils/ptr_vector.hpp"
|
||||
|
||||
namespace GUIEngine { class Widget; class ListWidget; }
|
||||
namespace GUIEngine { class Widget; class ListWidget; class ButtonWidget; }
|
||||
|
||||
/**
|
||||
* \brief Handles the main menu
|
||||
@ -40,19 +40,24 @@ private:
|
||||
OnlineScreen();
|
||||
~OnlineScreen();
|
||||
|
||||
GUIEngine::IconButtonWidget * m_back_widget;
|
||||
GUIEngine::IconButtonWidget *m_back_widget;
|
||||
|
||||
GUIEngine::RibbonWidget * m_top_menu_widget;
|
||||
GUIEngine::IconButtonWidget * m_quick_play_widget;
|
||||
GUIEngine::IconButtonWidget * m_find_server_widget;
|
||||
GUIEngine::IconButtonWidget * m_create_server_widget;
|
||||
GUIEngine::RibbonWidget *m_top_menu_widget;
|
||||
GUIEngine::IconButtonWidget *m_find_lan_server_widget;
|
||||
GUIEngine::IconButtonWidget *m_create_lan_server_widget;
|
||||
GUIEngine::IconButtonWidget *m_manage_user;
|
||||
|
||||
GUIEngine::LabelWidget * m_online_status_widget;
|
||||
GUIEngine::IconButtonWidget *m_find_wan_server_widget;
|
||||
GUIEngine::IconButtonWidget *m_create_wan_server_widget;
|
||||
GUIEngine::IconButtonWidget *m_quick_wan_play_widget;
|
||||
|
||||
GUIEngine::RibbonWidget * m_bottom_menu_widget;
|
||||
GUIEngine::IconButtonWidget * m_register_widget;
|
||||
GUIEngine::IconButtonWidget * m_profile_widget;
|
||||
GUIEngine::IconButtonWidget * m_sign_out_widget;
|
||||
GUIEngine::RibbonWidget *m_bottom_menu_widget;
|
||||
GUIEngine::IconButtonWidget *m_register_widget;
|
||||
GUIEngine::IconButtonWidget *m_profile_widget;
|
||||
GUIEngine::IconButtonWidget *m_sign_out_widget;
|
||||
|
||||
/** Keep the widget to to the user name. */
|
||||
GUIEngine::ButtonWidget *m_user_id;
|
||||
|
||||
PlayerProfile::OnlineState m_recorded_state;
|
||||
|
||||
|
@ -38,7 +38,6 @@ DEFINE_SCREEN_SINGLETON( OnlineUserSearch );
|
||||
|
||||
OnlineUserSearch::OnlineUserSearch() : Screen("online/user_search.stkgui")
|
||||
{
|
||||
m_selected_index = -1;
|
||||
m_search_request = NULL;
|
||||
m_search_string = "";
|
||||
m_last_search_string = "";
|
||||
@ -226,9 +225,9 @@ void OnlineUserSearch::eventCallback(GUIEngine::Widget* widget,
|
||||
}
|
||||
else if (name == m_user_list_widget->m_properties[GUIEngine::PROP_ID])
|
||||
{
|
||||
m_selected_index = m_user_list_widget->getSelectionID();
|
||||
if (m_selected_index != -1)
|
||||
new UserInfoDialog(m_users[m_selected_index]);
|
||||
int selected_index = m_user_list_widget->getSelectionID();
|
||||
if (selected_index != -1)
|
||||
new UserInfoDialog(m_users[selected_index]);
|
||||
}
|
||||
else if (name == m_search_button_widget->m_properties[GUIEngine::PROP_ID])
|
||||
{
|
||||
@ -239,22 +238,6 @@ void OnlineUserSearch::eventCallback(GUIEngine::Widget* widget,
|
||||
|
||||
} // 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 OnlineUserSearch::setLastSelected() //FIXME actually use this here and in server selection
|
||||
{
|
||||
if(m_selected_index>-1)
|
||||
{
|
||||
m_user_list_widget->setFocusForPlayer(PLAYER_ID_GAME_MASTER);
|
||||
m_user_list_widget->setSelectionID(m_selected_index);
|
||||
}
|
||||
} // setLastSelected
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Called every frame. It queries the search request for results and
|
||||
* displays them if necessary.
|
||||
|
@ -48,9 +48,6 @@ private:
|
||||
/** Pointer to the result list. */
|
||||
GUIEngine::ListWidget * m_user_list_widget;
|
||||
|
||||
/** The currently selected index, used to re-select this item after
|
||||
* addons_loading is being displayed. */
|
||||
int m_selected_index;
|
||||
/** Seach string entered in the search widget. */
|
||||
irr::core::stringw m_search_string;
|
||||
/** Last search string, used to avoid doing the same search again. */
|
||||
@ -86,7 +83,6 @@ public:
|
||||
/** \brief implement callback from parent class GUIEngine::Screen */
|
||||
virtual void onUpdate(float dt) OVERRIDE;
|
||||
|
||||
void setLastSelected();
|
||||
/** Sets the search string to an initial value. */
|
||||
void setSearchString(const irr::core::stringw & search_string)
|
||||
{
|
||||
|
@ -15,7 +15,7 @@
|
||||
// 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/options_screen_input2.hpp"
|
||||
#include "states_screens/options_screen_device.hpp"
|
||||
|
||||
#include "config/user_config.hpp"
|
||||
#include "guiengine/CGUISpriteBank.hpp"
|
||||
@ -45,24 +45,24 @@
|
||||
|
||||
using namespace GUIEngine;
|
||||
|
||||
DEFINE_SCREEN_SINGLETON( OptionsScreenInput2 );
|
||||
DEFINE_SCREEN_SINGLETON( OptionsScreenDevice );
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
OptionsScreenInput2::OptionsScreenInput2() : Screen("options_device.stkgui")
|
||||
OptionsScreenDevice::OptionsScreenDevice() : Screen("options_device.stkgui")
|
||||
{
|
||||
m_config = NULL;
|
||||
} // OptionsScreenInput2
|
||||
} // OptionsScreenDevice
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void OptionsScreenInput2::loadedFromFile()
|
||||
void OptionsScreenDevice::loadedFromFile()
|
||||
{
|
||||
} // loadedFromFile
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void OptionsScreenInput2::beforeAddingWidget()
|
||||
void OptionsScreenDevice::beforeAddingWidget()
|
||||
{
|
||||
GUIEngine::ListWidget* w_list =
|
||||
getWidget<GUIEngine::ListWidget>("actions");
|
||||
@ -75,7 +75,7 @@ void OptionsScreenInput2::beforeAddingWidget()
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void OptionsScreenInput2::init()
|
||||
void OptionsScreenDevice::init()
|
||||
{
|
||||
Screen::init();
|
||||
RibbonWidget* tabBar = getWidget<RibbonWidget>("options_choice");
|
||||
@ -165,9 +165,9 @@ void OptionsScreenInput2::init()
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void OptionsScreenInput2::addListItemSubheader(GUIEngine::ListWidget* actions,
|
||||
const char* id,
|
||||
const core::stringw& text)
|
||||
void OptionsScreenDevice::addListItemSubheader(GUIEngine::ListWidget* actions,
|
||||
const char* id,
|
||||
const core::stringw& text)
|
||||
{
|
||||
std::vector<GUIEngine::ListWidget::ListCell> row;
|
||||
row.push_back(GUIEngine::ListWidget::ListCell(text, -1, 1, false));
|
||||
@ -177,8 +177,8 @@ void OptionsScreenInput2::addListItemSubheader(GUIEngine::ListWidget* actions,
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void OptionsScreenInput2::addListItem(GUIEngine::ListWidget* actions,
|
||||
PlayerAction pa)
|
||||
void OptionsScreenDevice::addListItem(GUIEngine::ListWidget* actions,
|
||||
PlayerAction pa)
|
||||
{
|
||||
std::vector<GUIEngine::ListWidget::ListCell> row;
|
||||
core::stringw s(KartActionStrings[pa].c_str());
|
||||
@ -189,10 +189,10 @@ void OptionsScreenInput2::addListItem(GUIEngine::ListWidget* actions,
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void OptionsScreenInput2::renameRow(GUIEngine::ListWidget* actions,
|
||||
int idRow,
|
||||
const irr::core::stringw &translatedName,
|
||||
PlayerAction action) const
|
||||
void OptionsScreenDevice::renameRow(GUIEngine::ListWidget* actions,
|
||||
int idRow,
|
||||
const irr::core::stringw &translatedName,
|
||||
PlayerAction action) const
|
||||
{
|
||||
actions->renameCell(idRow, 0, core::stringw(" ") + translatedName);
|
||||
actions->renameCell(idRow, 1, m_config->getBindingAsString(action));
|
||||
@ -201,7 +201,7 @@ void OptionsScreenInput2::renameRow(GUIEngine::ListWidget* actions,
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void OptionsScreenInput2::updateInputButtons()
|
||||
void OptionsScreenDevice::updateInputButtons()
|
||||
{
|
||||
assert(m_config != NULL);
|
||||
|
||||
@ -372,7 +372,7 @@ void OptionsScreenInput2::updateInputButtons()
|
||||
static PlayerAction binding_to_set;
|
||||
static std::string binding_to_set_button;
|
||||
|
||||
void OptionsScreenInput2::gotSensedInput(const Input& sensed_input)
|
||||
void OptionsScreenDevice::gotSensedInput(const Input& sensed_input)
|
||||
{
|
||||
const bool keyboard = (m_config->isKeyboard() &&
|
||||
sensed_input.m_type == Input::IT_KEYBOARD);
|
||||
@ -384,7 +384,7 @@ void OptionsScreenInput2::gotSensedInput(const Input& sensed_input)
|
||||
{
|
||||
if (UserConfigParams::logMisc())
|
||||
{
|
||||
Log::info("OptionsScreenInput2", "Binding %s: setting to keyboard key %d",
|
||||
Log::info("OptionsScreenDevice", "Binding %s: setting to keyboard key %d",
|
||||
KartActionStrings[binding_to_set].c_str(), sensed_input.m_button_id);
|
||||
}
|
||||
|
||||
@ -401,21 +401,21 @@ void OptionsScreenInput2::gotSensedInput(const Input& sensed_input)
|
||||
{
|
||||
if (UserConfigParams::logMisc())
|
||||
{
|
||||
Log::info("OptionsScreenInput2", "Binding %s: setting to gamepad #%d",
|
||||
Log::info("OptionsScreenDevice", "Binding %s: setting to gamepad #%d",
|
||||
KartActionStrings[binding_to_set].c_str(), sensed_input.m_device_id);
|
||||
|
||||
if (sensed_input.m_type == Input::IT_STICKMOTION)
|
||||
{
|
||||
Log::info("OptionsScreenInput2", "Axis %d; direction %s", sensed_input.m_button_id,
|
||||
Log::info("OptionsScreenDevice", "Axis %d; direction %s", sensed_input.m_button_id,
|
||||
sensed_input.m_axis_direction == Input::AD_NEGATIVE ? "-" : "+");
|
||||
}
|
||||
else if (sensed_input.m_type == Input::IT_STICKBUTTON)
|
||||
{
|
||||
Log::info("OptionsScreenInput2", "Button %d", sensed_input.m_button_id);
|
||||
Log::info("OptionsScreenDevice", "Button %d", sensed_input.m_button_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
Log::info("OptionsScreenInput2", "Sensed unknown gamepad event type??");
|
||||
Log::info("OptionsScreenDevice", "Sensed unknown gamepad event type??");
|
||||
}
|
||||
}
|
||||
|
||||
@ -439,7 +439,7 @@ void OptionsScreenInput2::gotSensedInput(const Input& sensed_input)
|
||||
{
|
||||
if (UserConfigParams::logMisc())
|
||||
{
|
||||
Log::info("OptionsScreenInput2", "Binding %s: setting to keyboard key NONE",
|
||||
Log::info("OptionsScreenDevice", "Binding %s: setting to keyboard key NONE",
|
||||
KartActionStrings[binding_to_set].c_str());
|
||||
}
|
||||
|
||||
@ -481,9 +481,9 @@ void OptionsScreenInput2::gotSensedInput(const Input& sensed_input)
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void OptionsScreenInput2::eventCallback(Widget* widget,
|
||||
const std::string& name,
|
||||
const int playerID)
|
||||
void OptionsScreenDevice::eventCallback(Widget* widget,
|
||||
const std::string& name,
|
||||
const int playerID)
|
||||
{
|
||||
//const std::string& screen_name = getName();
|
||||
|
||||
@ -529,7 +529,7 @@ void OptionsScreenInput2::eventCallback(Widget* widget,
|
||||
// we found which one. show the "press a key" dialog.
|
||||
if (UserConfigParams::logMisc())
|
||||
{
|
||||
Log::info("OptionsScreenInput2", "Entering sensing mode for %s",
|
||||
Log::info("OptionsScreenDevice", "Entering sensing mode for %s",
|
||||
m_config->getName().c_str());
|
||||
}
|
||||
|
||||
@ -547,7 +547,7 @@ void OptionsScreenInput2::eventCallback(Widget* widget,
|
||||
}
|
||||
else
|
||||
{
|
||||
Log::error("OptionsScreenInput2", "Unknown selection device in options: %s",
|
||||
Log::error("OptionsScreenDevice", "Unknown selection device in options: %s",
|
||||
m_config->getName().c_str());
|
||||
}
|
||||
break;
|
||||
@ -583,13 +583,13 @@ void OptionsScreenInput2::eventCallback(Widget* widget,
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void OptionsScreenInput2::unloaded()
|
||||
void OptionsScreenDevice::unloaded()
|
||||
{
|
||||
} // unloaded
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
bool OptionsScreenInput2::onEscapePressed()
|
||||
bool OptionsScreenDevice::onEscapePressed()
|
||||
{
|
||||
StateManager::get()
|
||||
->replaceTopMostScreen(OptionsScreenInput::getInstance());
|
||||
@ -599,13 +599,13 @@ bool OptionsScreenInput2::onEscapePressed()
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void OptionsScreenInput2::onConfirm()
|
||||
void OptionsScreenDevice::onConfirm()
|
||||
{
|
||||
const bool success =
|
||||
input_manager->getDeviceManager()->deleteConfig(m_config);
|
||||
assert(success);
|
||||
if (!success)
|
||||
Log::error("OptionsScreenInput2", "Failed to delete config!");
|
||||
Log::error("OptionsScreenDevice", "Failed to delete config!");
|
||||
|
||||
m_config = NULL;
|
||||
input_manager->getDeviceManager()->save();
|
||||
@ -617,8 +617,9 @@ void OptionsScreenInput2::onConfirm()
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
|
||||
bool OptionsScreenInput2::conflictsBetweenKbdConfig(PlayerAction action,
|
||||
PlayerAction from, PlayerAction to)
|
||||
bool OptionsScreenDevice::conflictsBetweenKbdConfig(PlayerAction action,
|
||||
PlayerAction from,
|
||||
PlayerAction to)
|
||||
{
|
||||
KeyboardConfig* other_kbd_config;
|
||||
int id = m_config->getBinding(action).getId();
|
@ -16,8 +16,8 @@
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
|
||||
#ifndef __HEADER_OPTIONS_SCREEN_INPUT2_HPP__
|
||||
#define __HEADER_OPTIONS_SCREEN_INPUT2_HPP__
|
||||
#ifndef HEADER_OPTIONS_SCREEN_DEVICE_HPP
|
||||
#define HEADER_OPTIONS_SCREEN_DEVICE_HPP
|
||||
|
||||
#include <string>
|
||||
#include <irrString.h>
|
||||
@ -37,11 +37,11 @@ struct Input;
|
||||
* \brief Input options screen
|
||||
* \ingroup states_screens
|
||||
*/
|
||||
class OptionsScreenInput2 : public GUIEngine::Screen,
|
||||
public GUIEngine::ScreenSingleton<OptionsScreenInput2>,
|
||||
class OptionsScreenDevice : public GUIEngine::Screen,
|
||||
public GUIEngine::ScreenSingleton<OptionsScreenDevice>,
|
||||
public MessageDialog::IConfirmDialogListener
|
||||
{
|
||||
OptionsScreenInput2();
|
||||
OptionsScreenDevice();
|
||||
|
||||
void updateInputButtons();
|
||||
|
||||
@ -62,7 +62,7 @@ class OptionsScreenInput2 : public GUIEngine::Screen,
|
||||
const core::stringw& text);
|
||||
|
||||
public:
|
||||
friend class GUIEngine::ScreenSingleton<OptionsScreenInput2>;
|
||||
friend class GUIEngine::ScreenSingleton<OptionsScreenDevice>;
|
||||
|
||||
/** Sets the configuration to be used. */
|
||||
void setDevice(DeviceConfig* config) { m_config = config; }
|
@ -28,7 +28,7 @@
|
||||
#include "input/gamepad_device.hpp"
|
||||
#include "input/input_manager.hpp"
|
||||
#include "io/file_manager.hpp"
|
||||
#include "states_screens/options_screen_input2.hpp"
|
||||
#include "states_screens/options_screen_device.hpp"
|
||||
#include "states_screens/options_screen_audio.hpp"
|
||||
#include "states_screens/options_screen_video.hpp"
|
||||
#include "states_screens/options_screen_ui.hpp"
|
||||
@ -225,8 +225,8 @@ void OptionsScreenInput::eventCallback(Widget* widget, const std::string& name,
|
||||
read = sscanf( selection.c_str(), "gamepad%i", &i );
|
||||
if (read == 1 && i != -1)
|
||||
{
|
||||
OptionsScreenInput2::getInstance()->setDevice( input_manager->getDeviceManager()->getGamepadConfig(i) );
|
||||
StateManager::get()->replaceTopMostScreen(OptionsScreenInput2::getInstance());
|
||||
OptionsScreenDevice::getInstance()->setDevice( input_manager->getDeviceManager()->getGamepadConfig(i) );
|
||||
StateManager::get()->replaceTopMostScreen(OptionsScreenDevice::getInstance());
|
||||
//updateInputButtons( input_manager->getDeviceList()->getGamepadConfig(i) );
|
||||
}
|
||||
else
|
||||
@ -242,8 +242,9 @@ void OptionsScreenInput::eventCallback(Widget* widget, const std::string& name,
|
||||
if (read == 1 && i != -1)
|
||||
{
|
||||
// updateInputButtons( input_manager->getDeviceList()->getKeyboardConfig(i) );
|
||||
OptionsScreenInput2::getInstance()->setDevice( input_manager->getDeviceManager()->getKeyboardConfig(i) );
|
||||
StateManager::get()->replaceTopMostScreen(OptionsScreenInput2::getInstance());
|
||||
OptionsScreenDevice::getInstance()
|
||||
->setDevice( input_manager->getDeviceManager()->getKeyboardConfig(i) );
|
||||
StateManager::get()->replaceTopMostScreen(OptionsScreenDevice::getInstance());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -831,8 +831,8 @@ void RaceGUI::drawLap(const AbstractKart* kart,
|
||||
// If the time display in the top right is in this viewport,
|
||||
// move the lap/rank display down a little bit so that it is
|
||||
// displayed under the time.
|
||||
if(viewport.UpperLeftCorner.Y==0 &&
|
||||
viewport.LowerRightCorner.X==irr_driver->getActualScreenSize().Width &&
|
||||
if (viewport.UpperLeftCorner.Y==0 &&
|
||||
viewport.LowerRightCorner.X==(int)(irr_driver->getActualScreenSize().Width) &&
|
||||
race_manager->getNumPlayers()!=3)
|
||||
pos.UpperLeftCorner.Y += m_font_height;
|
||||
pos.LowerRightCorner.Y = viewport.LowerRightCorner.Y+20;
|
||||
|
@ -47,7 +47,7 @@ DEFINE_SCREEN_SINGLETON( RaceSetupScreen );
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
RaceSetupScreen::RaceSetupScreen() : Screen("racesetup.stkgui")
|
||||
RaceSetupScreen::RaceSetupScreen() : Screen("race_setup.stkgui")
|
||||
{
|
||||
} // RaceSetupScreen
|
||||
|
||||
|
@ -36,9 +36,7 @@ DEFINE_SCREEN_SINGLETON( ServerSelection );
|
||||
|
||||
ServerSelection::ServerSelection() : Screen("online/server_selection.stkgui")
|
||||
{
|
||||
m_selected_index = -1;
|
||||
m_refresh_request = NULL;
|
||||
|
||||
} // ServerSelection
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -66,7 +64,7 @@ void ServerSelection::refresh()
|
||||
m_server_list_widget->addItem("loading",
|
||||
StringUtils::loadingDots(_("Fetching servers")));
|
||||
m_reload_widget->setActive(false);
|
||||
}
|
||||
} // refresh
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -90,7 +88,8 @@ void ServerSelection::beforeAddingWidget()
|
||||
m_server_list_widget->clearColumns();
|
||||
m_server_list_widget->addColumn( _("Name"), 3 );
|
||||
m_server_list_widget->addColumn( _("Players"), 1);
|
||||
}
|
||||
} // beforeAddingWidget
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void ServerSelection::init()
|
||||
@ -112,11 +111,11 @@ void ServerSelection::init()
|
||||
void ServerSelection::loadList()
|
||||
{
|
||||
m_server_list_widget->clear();
|
||||
ServersManager * manager = ServersManager::get();
|
||||
ServersManager *manager = ServersManager::get();
|
||||
manager->sort(m_sort_desc);
|
||||
for(int i=0; i < manager->getNumServers(); i++)
|
||||
{
|
||||
const Server * server = manager->getServerBySort(i);
|
||||
const Server *server = manager->getServerBySort(i);
|
||||
core::stringw num_players;
|
||||
num_players.append(StringUtils::toWString(server->getCurrentPlayers()));
|
||||
num_players.append("/");
|
||||
@ -159,30 +158,14 @@ void ServerSelection::eventCallback( GUIEngine::Widget* widget,
|
||||
|
||||
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::get()->getServerBySort(m_selected_index)->getServerId();
|
||||
uint32_t host_id = ServersManager::get()->getServerBySort(m_selected_index)->getHostId();
|
||||
int selected_index = m_server_list_widget->getSelectionID();
|
||||
uint32_t server_id = ServersManager::get()->getServerBySort(selected_index)->getServerId();
|
||||
uint32_t host_id = ServersManager::get()->getServerBySort(selected_index)->getHostId();
|
||||
new ServerInfoDialog(server_id, host_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)
|
||||
|
@ -43,16 +43,15 @@ private:
|
||||
GUIEngine::LabelWidget * m_update_status;
|
||||
GUIEngine::ListWidget * m_server_list_widget;
|
||||
|
||||
|
||||
/** 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;
|
||||
|
||||
const Online::ServersManager::RefreshRequest * m_refresh_request;
|
||||
const Online::ServersManager::RefreshRequest *m_refresh_request;
|
||||
bool m_fake_refresh;
|
||||
|
||||
/** True if only lan servers should be shown. */
|
||||
bool m_is_lan;
|
||||
|
||||
void refresh();
|
||||
|
||||
public:
|
||||
@ -79,8 +78,6 @@ public:
|
||||
/** \brief implement callback from parent class GUIEngine::Screen */
|
||||
virtual void onUpdate(float dt) OVERRIDE;
|
||||
|
||||
void setLastSelected();
|
||||
|
||||
};
|
||||
}; // ServerSelection
|
||||
|
||||
#endif
|
||||
|
@ -218,7 +218,8 @@ void TrackObject::init(const XMLNode &xml_node, scene::ISceneNode* parent,
|
||||
core::matrix4 absTransform = node->getAbsoluteTransformation();
|
||||
node->setParent(irr_driver->getSceneManager()->getRootSceneNode());
|
||||
node->setPosition(absTransform.getTranslation());
|
||||
node->setRotation(absTransform.getRotationDegrees());
|
||||
// Doesn't seem necessary to set rotation here, TODO: not sure why
|
||||
//node->setRotation(absTransform.getRotationDegrees());
|
||||
node->setScale(absTransform.getScale());
|
||||
is_movable = true;
|
||||
}
|
||||
|
@ -188,6 +188,388 @@ LightNode* findNearestLight()
|
||||
return nearest;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
bool handleContextMenuAction(s32 cmdID)
|
||||
{
|
||||
|
||||
World *world = World::getWorld();
|
||||
Physics *physics = world ? world->getPhysics() : NULL;
|
||||
if (cmdID == DEBUG_GRAPHICS_RELOAD_SHADERS)
|
||||
{
|
||||
Log::info("Debug", "Reloading shaders...");
|
||||
ShaderBase::updateShaders();
|
||||
}
|
||||
else if (cmdID == DEBUG_GRAPHICS_RESET)
|
||||
{
|
||||
if (physics)
|
||||
physics->setDebugMode(IrrDebugDrawer::DM_NONE);
|
||||
|
||||
irr_driver->resetDebugModes();
|
||||
}
|
||||
else if (cmdID == DEBUG_GRAPHICS_WIREFRAME)
|
||||
{
|
||||
if (physics)
|
||||
physics->setDebugMode(IrrDebugDrawer::DM_NONE);
|
||||
|
||||
irr_driver->resetDebugModes();
|
||||
irr_driver->toggleWireframe();
|
||||
}
|
||||
else if (cmdID == DEBUG_GRAPHICS_MIPMAP_VIZ)
|
||||
{
|
||||
if (physics)
|
||||
physics->setDebugMode(IrrDebugDrawer::DM_NONE);
|
||||
|
||||
irr_driver->resetDebugModes();
|
||||
irr_driver->toggleMipVisualization();
|
||||
}
|
||||
else if (cmdID == DEBUG_GRAPHICS_NORMALS_VIZ)
|
||||
{
|
||||
if (physics)
|
||||
physics->setDebugMode(IrrDebugDrawer::DM_NONE);
|
||||
|
||||
irr_driver->resetDebugModes();
|
||||
irr_driver->toggleNormals();
|
||||
}
|
||||
else if (cmdID == DEBUG_GRAPHICS_SSAO_VIZ)
|
||||
{
|
||||
if (physics)
|
||||
physics->setDebugMode(IrrDebugDrawer::DM_NONE);
|
||||
|
||||
irr_driver->resetDebugModes();
|
||||
irr_driver->toggleSSAOViz();
|
||||
}
|
||||
else if (cmdID == DEBUG_GRAPHICS_RSM_VIZ)
|
||||
{
|
||||
if (physics)
|
||||
physics->setDebugMode(IrrDebugDrawer::DM_NONE);
|
||||
|
||||
irr_driver->resetDebugModes();
|
||||
irr_driver->toggleRSM();
|
||||
}
|
||||
else if (cmdID == DEBUG_GRAPHICS_RH_VIZ)
|
||||
{
|
||||
if (physics)
|
||||
physics->setDebugMode(IrrDebugDrawer::DM_NONE);
|
||||
|
||||
irr_driver->resetDebugModes();
|
||||
irr_driver->toggleRH();
|
||||
}
|
||||
else if (cmdID == DEBUG_GRAPHICS_GI_VIZ)
|
||||
{
|
||||
if (physics)
|
||||
physics->setDebugMode(IrrDebugDrawer::DM_NONE);
|
||||
|
||||
irr_driver->resetDebugModes();
|
||||
irr_driver->toggleGI();
|
||||
}
|
||||
else if (cmdID == DEBUG_GRAPHICS_SHADOW_VIZ)
|
||||
{
|
||||
if (physics)
|
||||
physics->setDebugMode(IrrDebugDrawer::DM_NONE);
|
||||
|
||||
irr_driver->resetDebugModes();
|
||||
irr_driver->toggleShadowViz();
|
||||
}
|
||||
else if (cmdID == DEBUG_GRAPHICS_LIGHT_VIZ)
|
||||
{
|
||||
if (physics)
|
||||
physics->setDebugMode(IrrDebugDrawer::DM_NONE);
|
||||
|
||||
irr_driver->resetDebugModes();
|
||||
irr_driver->toggleLightViz();
|
||||
}
|
||||
else if (cmdID == DEBUG_GRAPHICS_DISTORT_VIZ)
|
||||
{
|
||||
if (physics)
|
||||
physics->setDebugMode(IrrDebugDrawer::DM_NONE);
|
||||
|
||||
irr_driver->resetDebugModes();
|
||||
irr_driver->toggleDistortViz();
|
||||
}
|
||||
else if (cmdID == DEBUG_GRAPHICS_BULLET_1)
|
||||
{
|
||||
irr_driver->resetDebugModes();
|
||||
|
||||
if (!world) return false;
|
||||
physics->setDebugMode(IrrDebugDrawer::DM_KARTS_PHYSICS);
|
||||
}
|
||||
else if (cmdID == DEBUG_GRAPHICS_BULLET_2)
|
||||
{
|
||||
irr_driver->resetDebugModes();
|
||||
|
||||
if (!world) return false;
|
||||
Physics *physics = world->getPhysics();
|
||||
physics->setDebugMode(IrrDebugDrawer::DM_NO_KARTS_GRAPHICS);
|
||||
}
|
||||
else if (cmdID == DEBUG_GRAPHICS_BOUNDING_BOXES_VIZ)
|
||||
{
|
||||
irr_driver->resetDebugModes();
|
||||
irr_driver->toggleBoundingBoxesViz();
|
||||
}
|
||||
else if (cmdID == DEBUG_PROFILER)
|
||||
{
|
||||
UserConfigParams::m_profiler_enabled =
|
||||
!UserConfigParams::m_profiler_enabled;
|
||||
}
|
||||
else if (cmdID == DEBUG_PROFILER_GENERATE_REPORT)
|
||||
{
|
||||
profiler.setCaptureReport(!profiler.getCaptureReport());
|
||||
}
|
||||
else if (cmdID == DEBUG_THROTTLE_FPS)
|
||||
{
|
||||
main_loop->setThrottleFPS(false);
|
||||
}
|
||||
else if (cmdID == DEBUG_FPS)
|
||||
{
|
||||
UserConfigParams::m_display_fps =
|
||||
!UserConfigParams::m_display_fps;
|
||||
}
|
||||
else if (cmdID == DEBUG_SAVE_REPLAY)
|
||||
{
|
||||
ReplayRecorder::get()->Save();
|
||||
}
|
||||
else if (cmdID == DEBUG_SAVE_HISTORY)
|
||||
{
|
||||
history->Save();
|
||||
}
|
||||
else if (cmdID == DEBUG_POWERUP_BOWLING)
|
||||
{
|
||||
addPowerup(PowerupManager::POWERUP_BOWLING);
|
||||
}
|
||||
else if (cmdID == DEBUG_POWERUP_BUBBLEGUM)
|
||||
{
|
||||
addPowerup(PowerupManager::POWERUP_BUBBLEGUM);
|
||||
}
|
||||
else if (cmdID == DEBUG_POWERUP_CAKE)
|
||||
{
|
||||
addPowerup(PowerupManager::POWERUP_CAKE);
|
||||
}
|
||||
else if (cmdID == DEBUG_POWERUP_PARACHUTE)
|
||||
{
|
||||
addPowerup(PowerupManager::POWERUP_PARACHUTE);
|
||||
}
|
||||
else if (cmdID == DEBUG_POWERUP_PLUNGER)
|
||||
{
|
||||
addPowerup(PowerupManager::POWERUP_PLUNGER);
|
||||
}
|
||||
else if (cmdID == DEBUG_POWERUP_RUBBERBALL)
|
||||
{
|
||||
addPowerup(PowerupManager::POWERUP_RUBBERBALL);
|
||||
}
|
||||
else if (cmdID == DEBUG_POWERUP_SWATTER)
|
||||
{
|
||||
addPowerup(PowerupManager::POWERUP_SWATTER);
|
||||
}
|
||||
else if (cmdID == DEBUG_POWERUP_SWITCH)
|
||||
{
|
||||
addPowerup(PowerupManager::POWERUP_SWITCH);
|
||||
}
|
||||
else if (cmdID == DEBUG_POWERUP_ZIPPER)
|
||||
{
|
||||
addPowerup(PowerupManager::POWERUP_ZIPPER);
|
||||
}
|
||||
else if (cmdID == DEBUG_POWERUP_NITRO)
|
||||
{
|
||||
if (!world) return false;
|
||||
const unsigned int num_local_players =
|
||||
race_manager->getNumLocalPlayers();
|
||||
for (unsigned int i = 0; i < num_local_players; i++)
|
||||
{
|
||||
AbstractKart* kart = world->getLocalPlayerKart(i);
|
||||
kart->setEnergy(100.0f);
|
||||
}
|
||||
}
|
||||
else if (cmdID == DEBUG_ATTACHMENT_ANVIL)
|
||||
{
|
||||
addAttachment(Attachment::ATTACH_ANVIL);
|
||||
}
|
||||
else if (cmdID == DEBUG_ATTACHMENT_BOMB)
|
||||
{
|
||||
addAttachment(Attachment::ATTACH_BOMB);
|
||||
}
|
||||
else if (cmdID == DEBUG_ATTACHMENT_PARACHUTE)
|
||||
{
|
||||
addAttachment(Attachment::ATTACH_PARACHUTE);
|
||||
}
|
||||
else if (cmdID == DEBUG_GUI_TOGGLE)
|
||||
{
|
||||
if (!world) return false;
|
||||
RaceGUIBase* gui = world->getRaceGUI();
|
||||
if (gui != NULL) gui->m_enabled = !gui->m_enabled;
|
||||
}
|
||||
else if (cmdID == DEBUG_GUI_HIDE_KARTS)
|
||||
{
|
||||
if (!world) return false;
|
||||
for (unsigned int n = 0; n<world->getNumKarts(); n++)
|
||||
{
|
||||
AbstractKart* kart = world->getKart(n);
|
||||
if (kart->getController()->isPlayerController())
|
||||
kart->getNode()->setVisible(false);
|
||||
}
|
||||
}
|
||||
else if (cmdID == DEBUG_GUI_CAM_TOP)
|
||||
{
|
||||
UserConfigParams::m_camera_debug = 1;
|
||||
irr_driver->getDevice()->getCursorControl()->setVisible(true);
|
||||
}
|
||||
else if (cmdID == DEBUG_GUI_CAM_WHEEL)
|
||||
{
|
||||
UserConfigParams::m_camera_debug = 2;
|
||||
irr_driver->getDevice()->getCursorControl()->setVisible(true);
|
||||
}
|
||||
else if (cmdID == DEBUG_GUI_CAM_BEHIND_KART)
|
||||
{
|
||||
UserConfigParams::m_camera_debug = 4;
|
||||
irr_driver->getDevice()->getCursorControl()->setVisible(true);
|
||||
}
|
||||
else if (cmdID == DEBUG_GUI_CAM_SIDE_OF_KART)
|
||||
{
|
||||
UserConfigParams::m_camera_debug = 5;
|
||||
irr_driver->getDevice()->getCursorControl()->setVisible(true);
|
||||
}
|
||||
else if (cmdID == DEBUG_GUI_CAM_FREE)
|
||||
{
|
||||
UserConfigParams::m_camera_debug = 3;
|
||||
irr_driver->getDevice()->getCursorControl()->setVisible(false);
|
||||
// Reset camera rotation
|
||||
Camera *cam = Camera::getActiveCamera();
|
||||
cam->setDirection(vector3df(0, 0, 1));
|
||||
cam->setUpVector(vector3df(0, 1, 0));
|
||||
}
|
||||
else if (cmdID == DEBUG_GUI_CAM_NORMAL)
|
||||
{
|
||||
UserConfigParams::m_camera_debug = 0;
|
||||
irr_driver->getDevice()->getCursorControl()->setVisible(true);
|
||||
}
|
||||
else if (cmdID == DEBUG_GUI_CAM_SMOOTH)
|
||||
{
|
||||
Camera *cam = Camera::getActiveCamera();
|
||||
cam->setSmoothMovement(!cam->getSmoothMovement());
|
||||
}
|
||||
else if (cmdID == DEBUG_GUI_CAM_ATTACH)
|
||||
{
|
||||
Camera *cam = Camera::getActiveCamera();
|
||||
cam->setAttachedFpsCam(!cam->getAttachedFpsCam());
|
||||
}
|
||||
else if (cmdID == DEBUG_PRINT_START_POS)
|
||||
{
|
||||
if (!world) return false;
|
||||
for (unsigned int i = 0; i<world->getNumKarts(); i++)
|
||||
{
|
||||
AbstractKart *kart = world->getKart(i);
|
||||
Log::warn(kart->getIdent().c_str(),
|
||||
"<start position=\"%d\" x=\"%f\" y=\"%f\" z=\"%f\" h=\"%f\"/>",
|
||||
i, kart->getXYZ().getX(), kart->getXYZ().getY(),
|
||||
kart->getXYZ().getZ(), kart->getHeading()*RAD_TO_DEGREE
|
||||
);
|
||||
}
|
||||
}
|
||||
else if (cmdID == DEBUG_VISUAL_VALUES)
|
||||
{
|
||||
#if !defined(__APPLE__)
|
||||
DebugSliderDialog *dsd = new DebugSliderDialog();
|
||||
dsd->setSliderHook("red_slider", 0, 255,
|
||||
[](){ return int(irr_driver->getAmbientLight().r * 255.f); },
|
||||
[](int v){
|
||||
video::SColorf ambient = irr_driver->getAmbientLight();
|
||||
ambient.setColorComponentValue(0, v / 255.f);
|
||||
irr_driver->setAmbientLight(ambient); }
|
||||
);
|
||||
dsd->setSliderHook("green_slider", 0, 255,
|
||||
[](){ return int(irr_driver->getAmbientLight().g * 255.f); },
|
||||
[](int v){
|
||||
video::SColorf ambient = irr_driver->getAmbientLight();
|
||||
ambient.setColorComponentValue(1, v / 255.f);
|
||||
irr_driver->setAmbientLight(ambient); }
|
||||
);
|
||||
dsd->setSliderHook("blue_slider", 0, 255,
|
||||
[](){ return int(irr_driver->getAmbientLight().b * 255.f); },
|
||||
[](int v){
|
||||
video::SColorf ambient = irr_driver->getAmbientLight();
|
||||
ambient.setColorComponentValue(2, v / 255.f);
|
||||
irr_driver->setAmbientLight(ambient); }
|
||||
);
|
||||
dsd->setSliderHook("ssao_radius", 0, 100,
|
||||
[](){ return int(irr_driver->getSSAORadius() * 10.f); },
|
||||
[](int v){irr_driver->setSSAORadius(v / 10.f); }
|
||||
);
|
||||
dsd->setSliderHook("ssao_k", 0, 100,
|
||||
[](){ return int(irr_driver->getSSAOK() * 10.f); },
|
||||
[](int v){irr_driver->setSSAOK(v / 10.f); }
|
||||
);
|
||||
dsd->setSliderHook("ssao_sigma", 0, 100,
|
||||
[](){ return int(irr_driver->getSSAOSigma() * 10.f); },
|
||||
[](int v){irr_driver->setSSAOSigma(v / 10.f); }
|
||||
);
|
||||
#endif
|
||||
}
|
||||
else if (cmdID == DEBUG_ADJUST_LIGHTS)
|
||||
{
|
||||
#if !defined(__APPLE__)
|
||||
// Some sliders use multipliers because the spinner widget
|
||||
// only supports integers
|
||||
DebugSliderDialog *dsd = new DebugSliderDialog();
|
||||
dsd->changeLabel("Red", "Red (x10)");
|
||||
dsd->setSliderHook("red_slider", 0, 100,
|
||||
[]()
|
||||
{
|
||||
return int(findNearestLight()->getColor().X * 100);
|
||||
},
|
||||
[](int intensity)
|
||||
{
|
||||
LightNode* nearest = findNearestLight();
|
||||
core::vector3df color = nearest->getColor();
|
||||
nearest->setColor(intensity / 100.0f, color.Y, color.Z);
|
||||
}
|
||||
);
|
||||
dsd->changeLabel("Green", "Green (x10)");
|
||||
dsd->setSliderHook("green_slider", 0, 100,
|
||||
[]()
|
||||
{
|
||||
return int(findNearestLight()->getColor().Y * 100);
|
||||
},
|
||||
[](int intensity)
|
||||
{
|
||||
LightNode* nearest = findNearestLight();
|
||||
core::vector3df color = nearest->getColor();
|
||||
nearest->setColor(color.X, intensity / 100.0f, color.Z);
|
||||
}
|
||||
);
|
||||
dsd->changeLabel("Blue", "Blue (x10)");
|
||||
dsd->setSliderHook("blue_slider", 0, 100,
|
||||
[]()
|
||||
{
|
||||
return int(findNearestLight()->getColor().Z * 100);
|
||||
},
|
||||
[](int intensity)
|
||||
{
|
||||
LightNode* nearest = findNearestLight();
|
||||
core::vector3df color = nearest->getColor();
|
||||
nearest->setColor(color.X, color.Y, intensity / 100.0f);
|
||||
}
|
||||
);
|
||||
dsd->changeLabel("SSAO radius", "energy (x10)");
|
||||
dsd->setSliderHook("ssao_radius", 0, 100,
|
||||
[]() { return int(findNearestLight()->getEnergy() * 10); },
|
||||
[](int v){ findNearestLight()->setEnergy(v / 10.0f); }
|
||||
);
|
||||
dsd->changeLabel("SSAO k", "radius");
|
||||
dsd->setSliderHook("ssao_k", 0, 100,
|
||||
[]() { return int(findNearestLight()->getRadius()); },
|
||||
[](int v){ findNearestLight()->setRadius(float(v)); }
|
||||
);
|
||||
dsd->changeLabel("SSAO Sigma", "[None]");
|
||||
#endif
|
||||
}
|
||||
else if (cmdID == DEBUG_SCRIPT_CONSOLE)
|
||||
{
|
||||
ScriptingConsole* console = new ScriptingConsole();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
/** Debug menu handling */
|
||||
bool onEvent(const SEvent &event)
|
||||
@ -202,10 +584,11 @@ bool onEvent(const SEvent &event)
|
||||
if(event.MouseInput.Event == EMIE_RMOUSE_PRESSED_DOWN &&
|
||||
!g_debug_menu_visible)
|
||||
{
|
||||
irr_driver->getDevice()->getCursorControl()->setVisible(true);
|
||||
|
||||
// root menu
|
||||
gui::IGUIEnvironment* guienv = irr_driver->getGUI();
|
||||
core::rect<s32> r(event.MouseInput.X, event.MouseInput.Y,
|
||||
event.MouseInput.Y+100, event.MouseInput.Y+100);
|
||||
core::rect<s32> r(100, 50, 150, 500);
|
||||
IGUIContextMenu* mnu = guienv->addContextMenu(r, NULL);
|
||||
int graphicsMenuIndex = mnu->addItem(L"Graphics >",-1,true,true);
|
||||
|
||||
@ -255,8 +638,8 @@ bool onEvent(const SEvent &event)
|
||||
sub->addItem(L"Behind wheel view", DEBUG_GUI_CAM_WHEEL);
|
||||
sub->addItem(L"Behind kart view", DEBUG_GUI_CAM_BEHIND_KART);
|
||||
sub->addItem(L"Side of kart view", DEBUG_GUI_CAM_SIDE_OF_KART);
|
||||
sub->addItem(L"First person view", DEBUG_GUI_CAM_FREE);
|
||||
sub->addItem(L"Normal view", DEBUG_GUI_CAM_NORMAL);
|
||||
sub->addItem(L"First person view (Ctrl + F1)", DEBUG_GUI_CAM_FREE);
|
||||
sub->addItem(L"Normal view (Ctrl + F2)", DEBUG_GUI_CAM_NORMAL);
|
||||
sub->addItem(L"Toggle smooth camera", DEBUG_GUI_CAM_SMOOTH);
|
||||
sub->addItem(L"Attach fps camera to kart", DEBUG_GUI_CAM_ATTACH);
|
||||
|
||||
@ -292,394 +675,37 @@ bool onEvent(const SEvent &event)
|
||||
IGUIContextMenu *menu = (IGUIContextMenu*)event.GUIEvent.Caller;
|
||||
s32 cmdID = menu->getItemCommandId(menu->getSelectedItem());
|
||||
|
||||
if(event.GUIEvent.EventType == EGET_ELEMENT_CLOSED)
|
||||
if (event.GUIEvent.EventType == EGET_ELEMENT_CLOSED)
|
||||
{
|
||||
g_debug_menu_visible = false;
|
||||
}
|
||||
|
||||
if (event.GUIEvent.EventType == gui::EGET_MENU_ITEM_SELECTED)
|
||||
else if (event.GUIEvent.EventType == gui::EGET_MENU_ITEM_SELECTED)
|
||||
{
|
||||
World *world = World::getWorld();
|
||||
Physics *physics = world ? world->getPhysics() : NULL;
|
||||
if(cmdID == DEBUG_GRAPHICS_RELOAD_SHADERS)
|
||||
{
|
||||
Log::info("Debug", "Reloading shaders...");
|
||||
ShaderBase::updateShaders();
|
||||
}
|
||||
else if (cmdID == DEBUG_GRAPHICS_RESET)
|
||||
{
|
||||
if (physics)
|
||||
physics->setDebugMode(IrrDebugDrawer::DM_NONE);
|
||||
|
||||
irr_driver->resetDebugModes();
|
||||
}
|
||||
else if (cmdID == DEBUG_GRAPHICS_WIREFRAME)
|
||||
{
|
||||
if (physics)
|
||||
physics->setDebugMode(IrrDebugDrawer::DM_NONE);
|
||||
|
||||
irr_driver->resetDebugModes();
|
||||
irr_driver->toggleWireframe();
|
||||
}
|
||||
else if (cmdID == DEBUG_GRAPHICS_MIPMAP_VIZ)
|
||||
{
|
||||
if (physics)
|
||||
physics->setDebugMode(IrrDebugDrawer::DM_NONE);
|
||||
|
||||
irr_driver->resetDebugModes();
|
||||
irr_driver->toggleMipVisualization();
|
||||
}
|
||||
else if (cmdID == DEBUG_GRAPHICS_NORMALS_VIZ)
|
||||
{
|
||||
if (physics)
|
||||
physics->setDebugMode(IrrDebugDrawer::DM_NONE);
|
||||
|
||||
irr_driver->resetDebugModes();
|
||||
irr_driver->toggleNormals();
|
||||
}
|
||||
else if (cmdID == DEBUG_GRAPHICS_SSAO_VIZ)
|
||||
{
|
||||
if (physics)
|
||||
physics->setDebugMode(IrrDebugDrawer::DM_NONE);
|
||||
|
||||
irr_driver->resetDebugModes();
|
||||
irr_driver->toggleSSAOViz();
|
||||
}
|
||||
else if (cmdID == DEBUG_GRAPHICS_RSM_VIZ)
|
||||
{
|
||||
if (physics)
|
||||
physics->setDebugMode(IrrDebugDrawer::DM_NONE);
|
||||
|
||||
irr_driver->resetDebugModes();
|
||||
irr_driver->toggleRSM();
|
||||
}
|
||||
else if (cmdID == DEBUG_GRAPHICS_RH_VIZ)
|
||||
{
|
||||
if (physics)
|
||||
physics->setDebugMode(IrrDebugDrawer::DM_NONE);
|
||||
|
||||
irr_driver->resetDebugModes();
|
||||
irr_driver->toggleRH();
|
||||
}
|
||||
else if (cmdID == DEBUG_GRAPHICS_GI_VIZ)
|
||||
{
|
||||
if (physics)
|
||||
physics->setDebugMode(IrrDebugDrawer::DM_NONE);
|
||||
|
||||
irr_driver->resetDebugModes();
|
||||
irr_driver->toggleGI();
|
||||
}
|
||||
else if (cmdID == DEBUG_GRAPHICS_SHADOW_VIZ)
|
||||
{
|
||||
if (physics)
|
||||
physics->setDebugMode(IrrDebugDrawer::DM_NONE);
|
||||
|
||||
irr_driver->resetDebugModes();
|
||||
irr_driver->toggleShadowViz();
|
||||
}
|
||||
else if (cmdID == DEBUG_GRAPHICS_LIGHT_VIZ)
|
||||
{
|
||||
if (physics)
|
||||
physics->setDebugMode(IrrDebugDrawer::DM_NONE);
|
||||
|
||||
irr_driver->resetDebugModes();
|
||||
irr_driver->toggleLightViz();
|
||||
}
|
||||
else if (cmdID == DEBUG_GRAPHICS_DISTORT_VIZ)
|
||||
{
|
||||
if (physics)
|
||||
physics->setDebugMode(IrrDebugDrawer::DM_NONE);
|
||||
|
||||
irr_driver->resetDebugModes();
|
||||
irr_driver->toggleDistortViz();
|
||||
}
|
||||
else if (cmdID == DEBUG_GRAPHICS_BULLET_1)
|
||||
{
|
||||
irr_driver->resetDebugModes();
|
||||
|
||||
if (!world) return false;
|
||||
physics->setDebugMode(IrrDebugDrawer::DM_KARTS_PHYSICS);
|
||||
}
|
||||
else if (cmdID == DEBUG_GRAPHICS_BULLET_2)
|
||||
{
|
||||
irr_driver->resetDebugModes();
|
||||
|
||||
if (!world) return false;
|
||||
Physics *physics = world->getPhysics();
|
||||
physics->setDebugMode(IrrDebugDrawer::DM_NO_KARTS_GRAPHICS);
|
||||
}
|
||||
else if (cmdID == DEBUG_GRAPHICS_BOUNDING_BOXES_VIZ)
|
||||
{
|
||||
irr_driver->resetDebugModes();
|
||||
irr_driver->toggleBoundingBoxesViz();
|
||||
}
|
||||
else if (cmdID == DEBUG_PROFILER)
|
||||
{
|
||||
UserConfigParams::m_profiler_enabled =
|
||||
!UserConfigParams::m_profiler_enabled;
|
||||
}
|
||||
else if (cmdID == DEBUG_PROFILER_GENERATE_REPORT)
|
||||
{
|
||||
profiler.setCaptureReport(!profiler.getCaptureReport());
|
||||
}
|
||||
else if (cmdID == DEBUG_THROTTLE_FPS)
|
||||
{
|
||||
main_loop->setThrottleFPS(false);
|
||||
}
|
||||
else if (cmdID == DEBUG_FPS)
|
||||
{
|
||||
UserConfigParams::m_display_fps =
|
||||
!UserConfigParams::m_display_fps;
|
||||
}
|
||||
else if (cmdID == DEBUG_SAVE_REPLAY)
|
||||
{
|
||||
ReplayRecorder::get()->Save();
|
||||
}
|
||||
else if (cmdID == DEBUG_SAVE_HISTORY)
|
||||
{
|
||||
history->Save();
|
||||
}
|
||||
else if (cmdID == DEBUG_POWERUP_BOWLING)
|
||||
{
|
||||
addPowerup(PowerupManager::POWERUP_BOWLING);
|
||||
}
|
||||
else if (cmdID == DEBUG_POWERUP_BUBBLEGUM)
|
||||
{
|
||||
addPowerup(PowerupManager::POWERUP_BUBBLEGUM);
|
||||
}
|
||||
else if (cmdID == DEBUG_POWERUP_CAKE)
|
||||
{
|
||||
addPowerup(PowerupManager::POWERUP_CAKE);
|
||||
}
|
||||
else if (cmdID == DEBUG_POWERUP_PARACHUTE)
|
||||
{
|
||||
addPowerup(PowerupManager::POWERUP_PARACHUTE);
|
||||
}
|
||||
else if (cmdID == DEBUG_POWERUP_PLUNGER)
|
||||
{
|
||||
addPowerup(PowerupManager::POWERUP_PLUNGER);
|
||||
}
|
||||
else if (cmdID == DEBUG_POWERUP_RUBBERBALL)
|
||||
{
|
||||
addPowerup(PowerupManager::POWERUP_RUBBERBALL);
|
||||
}
|
||||
else if (cmdID == DEBUG_POWERUP_SWATTER)
|
||||
{
|
||||
addPowerup(PowerupManager::POWERUP_SWATTER);
|
||||
}
|
||||
else if (cmdID == DEBUG_POWERUP_SWITCH)
|
||||
{
|
||||
addPowerup(PowerupManager::POWERUP_SWITCH);
|
||||
}
|
||||
else if (cmdID == DEBUG_POWERUP_ZIPPER)
|
||||
{
|
||||
addPowerup(PowerupManager::POWERUP_ZIPPER);
|
||||
}
|
||||
else if (cmdID == DEBUG_POWERUP_NITRO)
|
||||
{
|
||||
if (!world) return false;
|
||||
const unsigned int num_local_players =
|
||||
race_manager->getNumLocalPlayers();
|
||||
for(unsigned int i = 0; i < num_local_players; i++)
|
||||
{
|
||||
AbstractKart* kart = world->getLocalPlayerKart(i);
|
||||
kart->setEnergy(100.0f);
|
||||
}
|
||||
}
|
||||
else if (cmdID == DEBUG_ATTACHMENT_ANVIL)
|
||||
{
|
||||
addAttachment(Attachment::ATTACH_ANVIL);
|
||||
}
|
||||
else if (cmdID == DEBUG_ATTACHMENT_BOMB)
|
||||
{
|
||||
addAttachment(Attachment::ATTACH_BOMB);
|
||||
}
|
||||
else if (cmdID == DEBUG_ATTACHMENT_PARACHUTE)
|
||||
{
|
||||
addAttachment(Attachment::ATTACH_PARACHUTE);
|
||||
}
|
||||
else if (cmdID == DEBUG_GUI_TOGGLE)
|
||||
{
|
||||
if (!world) return false;
|
||||
RaceGUIBase* gui = world->getRaceGUI();
|
||||
if (gui != NULL) gui->m_enabled = !gui->m_enabled;
|
||||
}
|
||||
else if (cmdID == DEBUG_GUI_HIDE_KARTS)
|
||||
{
|
||||
if (!world) return false;
|
||||
for (unsigned int n = 0; n<world->getNumKarts(); n++)
|
||||
{
|
||||
AbstractKart* kart = world->getKart(n);
|
||||
if (kart->getController()->isPlayerController())
|
||||
kart->getNode()->setVisible(false);
|
||||
}
|
||||
}
|
||||
else if (cmdID == DEBUG_GUI_CAM_TOP)
|
||||
{
|
||||
UserConfigParams::m_camera_debug = 1;
|
||||
irr_driver->getDevice()->getCursorControl()->setVisible(true);
|
||||
}
|
||||
else if (cmdID == DEBUG_GUI_CAM_WHEEL)
|
||||
{
|
||||
UserConfigParams::m_camera_debug = 2;
|
||||
irr_driver->getDevice()->getCursorControl()->setVisible(true);
|
||||
}
|
||||
else if (cmdID == DEBUG_GUI_CAM_BEHIND_KART)
|
||||
{
|
||||
UserConfigParams::m_camera_debug = 4;
|
||||
irr_driver->getDevice()->getCursorControl()->setVisible(true);
|
||||
}
|
||||
else if (cmdID == DEBUG_GUI_CAM_SIDE_OF_KART)
|
||||
{
|
||||
UserConfigParams::m_camera_debug = 5;
|
||||
irr_driver->getDevice()->getCursorControl()->setVisible(true);
|
||||
}
|
||||
else if (cmdID == DEBUG_GUI_CAM_FREE)
|
||||
{
|
||||
UserConfigParams::m_camera_debug = 3;
|
||||
irr_driver->getDevice()->getCursorControl()->setVisible(false);
|
||||
// Reset camera rotation
|
||||
Camera *cam = Camera::getActiveCamera();
|
||||
cam->setDirection(vector3df(0, 0, 1));
|
||||
cam->setUpVector(vector3df(0, 1, 0));
|
||||
}
|
||||
else if (cmdID == DEBUG_GUI_CAM_NORMAL)
|
||||
{
|
||||
UserConfigParams::m_camera_debug = 0;
|
||||
irr_driver->getDevice()->getCursorControl()->setVisible(true);
|
||||
}
|
||||
else if (cmdID == DEBUG_GUI_CAM_SMOOTH)
|
||||
{
|
||||
Camera *cam = Camera::getActiveCamera();
|
||||
cam->setSmoothMovement(!cam->getSmoothMovement());
|
||||
}
|
||||
else if (cmdID == DEBUG_GUI_CAM_ATTACH)
|
||||
{
|
||||
Camera *cam = Camera::getActiveCamera();
|
||||
cam->setAttachedFpsCam(!cam->getAttachedFpsCam());
|
||||
}
|
||||
else if (cmdID == DEBUG_PRINT_START_POS)
|
||||
{
|
||||
if(!world) return false;
|
||||
for(unsigned int i=0; i<world->getNumKarts(); i++)
|
||||
{
|
||||
AbstractKart *kart = world->getKart(i);
|
||||
Log::warn(kart->getIdent().c_str(),
|
||||
"<start position=\"%d\" x=\"%f\" y=\"%f\" z=\"%f\" h=\"%f\"/>",
|
||||
i, kart->getXYZ().getX(), kart->getXYZ().getY(),
|
||||
kart->getXYZ().getZ(),kart->getHeading()*RAD_TO_DEGREE
|
||||
);
|
||||
}
|
||||
}
|
||||
else if (cmdID == DEBUG_VISUAL_VALUES)
|
||||
{
|
||||
#if !defined(__APPLE__)
|
||||
DebugSliderDialog *dsd = new DebugSliderDialog();
|
||||
dsd->setSliderHook("red_slider", 0, 255,
|
||||
[](){ return int(irr_driver->getAmbientLight().r * 255.f); },
|
||||
[](int v){
|
||||
video::SColorf ambient = irr_driver->getAmbientLight();
|
||||
ambient.setColorComponentValue(0, v / 255.f);
|
||||
irr_driver->setAmbientLight(ambient); }
|
||||
);
|
||||
dsd->setSliderHook("green_slider", 0, 255,
|
||||
[](){ return int(irr_driver->getAmbientLight().g * 255.f); },
|
||||
[](int v){
|
||||
video::SColorf ambient = irr_driver->getAmbientLight();
|
||||
ambient.setColorComponentValue(1, v / 255.f);
|
||||
irr_driver->setAmbientLight(ambient); }
|
||||
);
|
||||
dsd->setSliderHook("blue_slider", 0, 255,
|
||||
[](){ return int(irr_driver->getAmbientLight().b * 255.f); },
|
||||
[](int v){
|
||||
video::SColorf ambient = irr_driver->getAmbientLight();
|
||||
ambient.setColorComponentValue(2, v / 255.f);
|
||||
irr_driver->setAmbientLight(ambient); }
|
||||
);
|
||||
dsd->setSliderHook("ssao_radius", 0, 100,
|
||||
[](){ return int(irr_driver->getSSAORadius() * 10.f); },
|
||||
[](int v){irr_driver->setSSAORadius(v / 10.f); }
|
||||
);
|
||||
dsd->setSliderHook("ssao_k", 0, 100,
|
||||
[](){ return int(irr_driver->getSSAOK() * 10.f); },
|
||||
[](int v){irr_driver->setSSAOK(v / 10.f); }
|
||||
);
|
||||
dsd->setSliderHook("ssao_sigma", 0, 100,
|
||||
[](){ return int(irr_driver->getSSAOSigma() * 10.f); },
|
||||
[](int v){irr_driver->setSSAOSigma(v / 10.f); }
|
||||
);
|
||||
#endif
|
||||
}
|
||||
else if (cmdID == DEBUG_ADJUST_LIGHTS)
|
||||
{
|
||||
#if !defined(__APPLE__)
|
||||
// Some sliders use multipliers because the spinner widget
|
||||
// only supports integers
|
||||
DebugSliderDialog *dsd = new DebugSliderDialog();
|
||||
dsd->changeLabel("Red", "Red (x10)");
|
||||
dsd->setSliderHook("red_slider", 0, 100,
|
||||
[]()
|
||||
{
|
||||
return int(findNearestLight()->getColor().X * 100);
|
||||
},
|
||||
[](int intensity)
|
||||
{
|
||||
LightNode* nearest = findNearestLight();
|
||||
core::vector3df color = nearest->getColor();
|
||||
nearest->setColor(intensity / 100.0f, color.Y, color.Z);
|
||||
}
|
||||
);
|
||||
dsd->changeLabel("Green", "Green (x10)");
|
||||
dsd->setSliderHook("green_slider", 0, 100,
|
||||
[]()
|
||||
{
|
||||
return int(findNearestLight()->getColor().Y * 100);
|
||||
},
|
||||
[](int intensity)
|
||||
{
|
||||
LightNode* nearest = findNearestLight();
|
||||
core::vector3df color = nearest->getColor();
|
||||
nearest->setColor(color.X, intensity / 100.0f, color.Z);
|
||||
}
|
||||
);
|
||||
dsd->changeLabel("Blue", "Blue (x10)");
|
||||
dsd->setSliderHook("blue_slider", 0, 100,
|
||||
[]()
|
||||
{
|
||||
return int(findNearestLight()->getColor().Z * 100);
|
||||
},
|
||||
[](int intensity)
|
||||
{
|
||||
LightNode* nearest = findNearestLight();
|
||||
core::vector3df color = nearest->getColor();
|
||||
nearest->setColor(color.X, color.Y, intensity / 100.0f);
|
||||
}
|
||||
);
|
||||
dsd->changeLabel("SSAO radius", "energy (x10)");
|
||||
dsd->setSliderHook("ssao_radius", 0, 100,
|
||||
[]() { return int(findNearestLight()->getEnergy() * 10); },
|
||||
[](int v){ findNearestLight()->setEnergy(v / 10.0f); }
|
||||
);
|
||||
dsd->changeLabel("SSAO k", "radius");
|
||||
dsd->setSliderHook("ssao_k", 0, 100,
|
||||
[]() { return int(findNearestLight()->getRadius()); },
|
||||
[](int v){ findNearestLight()->setRadius(float(v)); }
|
||||
);
|
||||
dsd->changeLabel("SSAO Sigma", "[None]");
|
||||
#endif
|
||||
}
|
||||
else if (cmdID == DEBUG_SCRIPT_CONSOLE)
|
||||
{
|
||||
ScriptingConsole* console = new ScriptingConsole();
|
||||
}
|
||||
return handleContextMenuAction(cmdID);
|
||||
}
|
||||
|
||||
return false; // event has been handled
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true; // continue event handling
|
||||
} // onEvent
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
bool handleStaticAction(int key)
|
||||
{
|
||||
if (key == KEY_F1)
|
||||
{
|
||||
handleContextMenuAction(DEBUG_GUI_CAM_FREE);
|
||||
}
|
||||
else if (key == KEY_F2)
|
||||
{
|
||||
handleContextMenuAction(DEBUG_GUI_CAM_NORMAL);
|
||||
}
|
||||
// TODO: create more keyboard shortcuts
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Returns if the debug menu is visible.
|
||||
*/
|
||||
|
@ -27,6 +27,7 @@ namespace Debug
|
||||
{
|
||||
bool onEvent(const irr::SEvent &event);
|
||||
bool isOpen();
|
||||
bool handleStaticAction(int key);
|
||||
}
|
||||
|
||||
|
||||
|
@ -42,7 +42,7 @@ private:
|
||||
public:
|
||||
// ------------------------------------------------------------------------
|
||||
/** Initialise the data and the mutex with default constructors. */
|
||||
Synchronised() : m_data(TYPE())
|
||||
Synchronised() : m_data()
|
||||
{
|
||||
pthread_mutex_init(&m_mutex, NULL);
|
||||
} // Synchronised()
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "utils/time.hpp"
|
||||
|
||||
#include "graphics/irr_driver.hpp"
|
||||
#include "utils/translation.hpp"
|
||||
|
||||
#include <ctime>
|
||||
|
||||
@ -38,6 +39,22 @@ void StkTime::init()
|
||||
m_timer->grab();
|
||||
} // init
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
/** Converts the time in this object to a human readable string. */
|
||||
std::string StkTime::toString(const TimeType &tt)
|
||||
{
|
||||
const struct tm *t = gmtime(&tt);
|
||||
|
||||
//I18N: Format for dates (%d = day, %m = month, %Y = year). See http://www.cplusplus.com/reference/ctime/strftime/ for more info about date formats.
|
||||
core::stringw w_date_format = translations->w_gettext(N_("%d/%m/%Y"));
|
||||
core::stringc c_date_format(w_date_format.c_str());
|
||||
|
||||
char s[64];
|
||||
strftime(s, 64, c_date_format.c_str(), t);
|
||||
return s;
|
||||
} // toString
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Returns a time based on an arbitrary 'epoch' (e.g. could be start
|
||||
* time of the application, 1.1.1970, ...).
|
||||
|
@ -51,14 +51,8 @@ public:
|
||||
static void init();
|
||||
static void getDate(int *day=NULL, int *month=NULL, int *year=NULL);
|
||||
|
||||
/** Converts the time in this object to a human readable string. */
|
||||
static std::string toString(const TimeType &tt)
|
||||
{
|
||||
const struct tm *t = gmtime(&tt);
|
||||
char s[16];
|
||||
strftime(s, 16, "%x", t);
|
||||
return s;
|
||||
} // toString
|
||||
/** Converts the time in this object to a human readable string. */
|
||||
static std::string toString(const TimeType &tt);
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the number of seconds since 1.1.1970. This function is used
|
||||
* to compare access times of files, e.g. news, addons data etc.
|
||||
|
Loading…
x
Reference in New Issue
Block a user