Merge branch 'master' of github.com:supertuxkart/stk-code
This commit is contained in:
commit
7a5629350c
@ -19,20 +19,22 @@ before_install:
|
||||
# so we try to use trusty (precise which is what traiv uses a too old mesa version which doesn't link)
|
||||
- sudo apt-add-repository "deb http://archive.ubuntu.com/ubuntu trusty main restricted"
|
||||
- sudo apt-key adv --recv-keys --keyserver keyserver.ubuntu.com 3B4FE6ACC0B21F32
|
||||
- sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
|
||||
- sudo apt-get update -qq
|
||||
- sudo apt-get install libgl1-mesa-dev libglu1-mesa-dev
|
||||
- sudo apt-get -qq install g++-4.8
|
||||
script:
|
||||
# First a debug build:
|
||||
- mkdir build-debug
|
||||
- cd build-debug
|
||||
- cmake .. -DCMAKE_BUILD_TYPE=Debug -DCHECK_ASSETS=off
|
||||
- cmake .. -DCMAKE_BUILD_TYPE=Debug -DCHECK_ASSETS=off -DCMAKE_CXX_COMPILER=/usr/bin/g++-4.8 -DCMAKE_C_COMPILER=/usr/bin/gcc-4.8
|
||||
- make VERBOSE=1 -j 4
|
||||
|
||||
# Then a release build:
|
||||
- cd ..
|
||||
- mkdir build-release
|
||||
- cd build-release
|
||||
- cmake .. -DCMAKE_BUILD_TYPE=Release -DCHECK_ASSETS=off
|
||||
- cmake .. -DCMAKE_BUILD_TYPE=Release -DCHECK_ASSETS=off -DCMAKE_CXX_COMPILER=/usr/bin/g++-4.8 -DCMAKE_C_COMPILER=/usr/bin/gcc-4.8
|
||||
- make VERBOSE=1 -j 4
|
||||
|
||||
notifications:
|
||||
|
@ -54,6 +54,8 @@
|
||||
I18N="Login dialog" text="Add user" label_location="bottom"/>
|
||||
<icon-button id="delete" width="64" height="64" icon="gui/gp_remove_track.png"
|
||||
I18N="Login dialog" text="Delete" label_location="bottom"/>
|
||||
<icon-button id="recover" width="64" height="64" icon="gui/main_options.png"
|
||||
I18N="Login dialog" text="Recovery" label_location="bottom"/>
|
||||
<icon-button id="rename" width="64" height="64" icon="gui/gp_rename.png"
|
||||
I18N="Login dialog" text="Rename" label_location="bottom"/>
|
||||
<icon-button id="cancel" width="64" height="64" icon="gui/main_quit.png"
|
||||
|
@ -341,7 +341,7 @@
|
||||
exp-string-response: dampen the suspension spring reaction
|
||||
exponentially.
|
||||
max-force: Maximum suspension force -->
|
||||
<suspension stiffness="248" rest="0.2" travel-cm="19"
|
||||
<suspension stiffness="140" rest="0.3" travel-cm="29"
|
||||
exp-spring-response="false" max-force="12000"/>
|
||||
|
||||
<!-- Wheel related parameters: damping-relaxation/compression: for
|
||||
@ -350,7 +350,7 @@
|
||||
position of the physics raycast wheels relative to the center of
|
||||
gravity. Default is to use the corners of the chassis to attach
|
||||
the wheels to. -->
|
||||
<wheels damping-relaxation="20" damping-compression="4.4" radius="0.25">
|
||||
<wheels damping-relaxation="35" damping-compression="5" radius="0.25">
|
||||
<front-right position="0.38 0 0.6" />
|
||||
<front-left position="-0.38 0 0.6" />
|
||||
<rear-right position="0.38 0 -0.6" />
|
||||
@ -373,12 +373,15 @@
|
||||
track-connection-accel: An artificial force that pulls a wheel to
|
||||
the ground if its off ground. Reduces the affect if a kart loses
|
||||
contact with the ground (i.e. it then can't steer or accelerate
|
||||
anymore). -->
|
||||
<stability roll-influence="0.03"
|
||||
anymore).
|
||||
smooth-flying-impulse: apply a torque impulse to flying kart to keep
|
||||
them parallel to the ground.-->
|
||||
<stability roll-influence="0.3"
|
||||
chassis-linear-damping="0.2"
|
||||
chassis-angular-damping="0"
|
||||
downward-impulse-factor="0"
|
||||
track-connection-accel="2"/>
|
||||
track-connection-accel="2"
|
||||
smooth-flying-impulse="10"/>
|
||||
|
||||
<!-- collision
|
||||
impulse-type: STK can apply an additional impulse in case of
|
||||
@ -568,9 +571,14 @@
|
||||
|
||||
<!-- Speed and acceleration related values: power and max-speed (in m/s)
|
||||
have 3 values, one for low, medium, and hard.
|
||||
brake-factor: Value used when braking. max-speed-reverse-ratio is
|
||||
the percentage of max speed for reverse gear. -->
|
||||
brake-factor: Value used when braking.
|
||||
brake-time-increase: The brake force is multiplied by
|
||||
(1+brake_time*brake_time_increase - i.e. the longer the brake was
|
||||
pressed, the harder the kart will brake.
|
||||
max-speed-reverse-ratio is the percentage of max speed for reverse gear.
|
||||
-->
|
||||
<engine power="450 475 500 510" max-speed="17 21 23 25" brake-factor="11.0"
|
||||
brake-time-increase="6"
|
||||
max-speed-reverse-ratio="0.3"/>
|
||||
|
||||
<!-- Simulated gears: switch-ratio defines at what ratio of the maximum
|
||||
|
@ -138,6 +138,7 @@ void* NewsManager::downloadNews(void *obj)
|
||||
|
||||
HTTPRequest *download_req = new HTTPRequest("news.xml");
|
||||
download_req->setAddonsURL("news.xml");
|
||||
|
||||
// Initialise the online portion of the addons manager.
|
||||
if(UserConfigParams::logAddons())
|
||||
Log::info("addons", "Downloading news.");
|
||||
@ -150,10 +151,12 @@ void* NewsManager::downloadNews(void *obj)
|
||||
// that a redirect went wrong, or a wrong/incorrect
|
||||
// address somehow made its way into the config file.
|
||||
delete download_req;
|
||||
|
||||
// We need a new object, since the state of the old
|
||||
// download request is now done.
|
||||
download_req = new HTTPRequest("news.xml");
|
||||
UserConfigParams::m_server_addons.revertToDefaults();
|
||||
|
||||
// make sure the new server address is actually used
|
||||
download_req->setAddonsURL("news.xml");
|
||||
download_req->executeNow();
|
||||
|
@ -42,8 +42,8 @@ public:
|
||||
UNLOCK_GP,
|
||||
UNLOCK_MODE,
|
||||
UNLOCK_KART,
|
||||
UNLOCK_DIFFICULTY}
|
||||
;
|
||||
UNLOCK_DIFFICULTY
|
||||
};
|
||||
// ------------------------------------------------------------------------
|
||||
class UnlockableFeature
|
||||
{
|
||||
|
@ -156,8 +156,4 @@ public:
|
||||
} // increaseAchievement
|
||||
// ------------------------------------------------------------------------
|
||||
}; // PlayerManager
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
/*EOF*/
|
||||
|
@ -127,7 +127,7 @@ public:
|
||||
/** Abstract virtual classes, to be implemented by the OnlinePlayer. */
|
||||
virtual void setUserDetails(Online::HTTPRequest *request,
|
||||
const std::string &action,
|
||||
const std::string &php_script = "") const = 0;
|
||||
const std::string &url_path = "") const = 0;
|
||||
virtual uint32_t getOnlineId() const = 0;
|
||||
virtual PlayerProfile::OnlineState getOnlineState() const = 0;
|
||||
virtual Online::OnlineProfile* getProfile() const = 0;
|
||||
|
@ -694,6 +694,12 @@ namespace UserConfigParams
|
||||
&m_online_group,
|
||||
"The server used for online multiplayer."));
|
||||
|
||||
PARAM_PREFIX IntUserConfigParam m_server_version
|
||||
PARAM_DEFAULT( IntUserConfigParam( 1,
|
||||
"server-version",
|
||||
&m_online_group,
|
||||
"Version of the server API to use."));
|
||||
|
||||
// ---- Addon server related entries
|
||||
PARAM_PREFIX GroupUserConfigParam m_addon_group
|
||||
PARAM_DEFAULT( GroupUserConfigParam("AddonAndNews",
|
||||
|
@ -243,29 +243,29 @@ void PostProcessing::renderGI(const core::matrix4 &RHMatrix, const core::vector3
|
||||
core::matrix4 InvRHMatrix;
|
||||
RHMatrix.getInverse(InvRHMatrix);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glUseProgram(FullScreenShader::GlobalIlluminationReconstructionShader::Program);
|
||||
glBindVertexArray(FullScreenShader::GlobalIlluminationReconstructionShader::vao);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glUseProgram(FullScreenShader::GlobalIlluminationReconstructionShader::getInstance()->Program);
|
||||
glBindVertexArray(FullScreenShader::GlobalIlluminationReconstructionShader::getInstance()->vao);
|
||||
glActiveTexture(GL_TEXTURE0 + FullScreenShader::GlobalIlluminationReconstructionShader::getInstance()->TU_SHR);
|
||||
glBindTexture(GL_TEXTURE_3D, shr);
|
||||
{
|
||||
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
}
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glActiveTexture(GL_TEXTURE0 + FullScreenShader::GlobalIlluminationReconstructionShader::getInstance()->TU_SHG);
|
||||
glBindTexture(GL_TEXTURE_3D, shg);
|
||||
{
|
||||
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
}
|
||||
glActiveTexture(GL_TEXTURE2);
|
||||
glActiveTexture(GL_TEXTURE0 + FullScreenShader::GlobalIlluminationReconstructionShader::getInstance()->TU_SHB);
|
||||
glBindTexture(GL_TEXTURE_3D, shb);
|
||||
{
|
||||
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
}
|
||||
setTexture(3, irr_driver->getRenderTargetTexture(RTT_NORMAL_AND_DEPTH), GL_NEAREST, GL_NEAREST);
|
||||
setTexture(4, irr_driver->getDepthStencilTexture(), GL_NEAREST, GL_NEAREST);
|
||||
FullScreenShader::GlobalIlluminationReconstructionShader::setUniforms(RHMatrix, InvRHMatrix, rh_extend, 3, 4, 0, 1, 2);
|
||||
setTexture(FullScreenShader::GlobalIlluminationReconstructionShader::getInstance()->TU_ntex, irr_driver->getRenderTargetTexture(RTT_NORMAL_AND_DEPTH), GL_NEAREST, GL_NEAREST);
|
||||
setTexture(FullScreenShader::GlobalIlluminationReconstructionShader::getInstance()->TU_dtex, irr_driver->getDepthStencilTexture(), GL_NEAREST, GL_NEAREST);
|
||||
FullScreenShader::GlobalIlluminationReconstructionShader::getInstance()->setUniforms(RHMatrix, InvRHMatrix, rh_extend);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 3);
|
||||
}
|
||||
|
||||
@ -515,10 +515,10 @@ void PostProcessing::renderSSAO()
|
||||
|
||||
// Generate linear depth buffer
|
||||
irr_driver->getFBO(FBO_LINEAR_DEPTH).Bind();
|
||||
glUseProgram(FullScreenShader::LinearizeDepthShader::Program);
|
||||
glBindVertexArray(FullScreenShader::LinearizeDepthShader::vao);
|
||||
setTexture(0, irr_driver->getDepthStencilTexture(), GL_LINEAR, GL_LINEAR);
|
||||
FullScreenShader::LinearizeDepthShader::setUniforms(irr_driver->getSceneManager()->getActiveCamera()->getNearValue(), irr_driver->getSceneManager()->getActiveCamera()->getFarValue(), 0);
|
||||
glUseProgram(FullScreenShader::LinearizeDepthShader::getInstance()->Program);
|
||||
glBindVertexArray(FullScreenShader::LinearizeDepthShader::getInstance()->vao);
|
||||
setTexture(FullScreenShader::LinearizeDepthShader::getInstance()->TU_tex, irr_driver->getDepthStencilTexture(), GL_LINEAR, GL_LINEAR);
|
||||
FullScreenShader::LinearizeDepthShader::getInstance()->setUniforms(irr_driver->getSceneManager()->getActiveCamera()->getNearValue(), irr_driver->getSceneManager()->getActiveCamera()->getFarValue());
|
||||
glDrawArrays(GL_TRIANGLES, 0, 3);
|
||||
irr_driver->getFBO(FBO_SSAO).Bind();
|
||||
|
||||
@ -557,11 +557,11 @@ void PostProcessing::renderFog()
|
||||
glBlendEquation(GL_FUNC_ADD);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
glUseProgram(FullScreenShader::FogShader::Program);
|
||||
glBindVertexArray(FullScreenShader::FogShader::vao);
|
||||
glUseProgram(FullScreenShader::FogShader::getInstance()->Program);
|
||||
glBindVertexArray(FullScreenShader::FogShader::getInstance()->vao);
|
||||
|
||||
setTexture(0, irr_driver->getDepthStencilTexture(), GL_NEAREST, GL_NEAREST);
|
||||
FullScreenShader::FogShader::setUniforms(fogmax, startH, endH, start, end, col, 0);
|
||||
setTexture(FullScreenShader::FogShader::getInstance()->TU_tex, irr_driver->getDepthStencilTexture(), GL_NEAREST, GL_NEAREST);
|
||||
FullScreenShader::FogShader::getInstance()->setUniforms(fogmax, startH, endH, start, end, col);
|
||||
|
||||
glDrawArrays(GL_TRIANGLES, 0, 3);
|
||||
glBindVertexArray(0);
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include "utils/tuple.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
|
||||
namespace RenderGeometry
|
||||
{
|
||||
@ -78,19 +79,6 @@ namespace RenderGeometry
|
||||
}
|
||||
using namespace RenderGeometry;
|
||||
|
||||
template<typename Shader, typename...uniforms>
|
||||
void draw(const GLMesh *mesh, uniforms... Args)
|
||||
{
|
||||
irr_driver->IncreaseObjectCount();
|
||||
GLenum ptype = mesh->PrimitiveType;
|
||||
GLenum itype = mesh->IndexType;
|
||||
size_t count = mesh->IndexCount;
|
||||
|
||||
Shader::setUniforms(Args...);
|
||||
glDrawElementsBaseVertex(ptype, count, itype, (GLvoid *)mesh->vaoOffset, mesh->vaoBaseVertex);
|
||||
}
|
||||
|
||||
|
||||
template<typename T, typename...uniforms>
|
||||
void draw(const T *Shader, const GLMesh *mesh, uniforms... Args)
|
||||
{
|
||||
@ -103,56 +91,65 @@ void draw(const T *Shader, const GLMesh *mesh, uniforms... Args)
|
||||
glDrawElementsBaseVertex(ptype, count, itype, (GLvoid *)mesh->vaoOffset, mesh->vaoBaseVertex);
|
||||
}
|
||||
|
||||
template<unsigned N>
|
||||
struct unroll_args_instance
|
||||
{
|
||||
template<typename T, typename ...TupleTypes, typename ...Args>
|
||||
static void exec(const T *Shader, const STK::Tuple<TupleTypes...> &t, Args... args)
|
||||
{
|
||||
unroll_args_instance<N - 1>::template exec<T>(Shader, t, STK::tuple_get<N - 1>(t), args...);
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct unroll_args_instance<0>
|
||||
{
|
||||
template<typename T, typename ...TupleTypes, typename ...Args>
|
||||
static void exec(const T *Shader, const STK::Tuple<TupleTypes...> &t, Args... args)
|
||||
{
|
||||
draw<T>(Shader, args...);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T, typename... TupleType>
|
||||
void apply_instance(const T *Shader, const STK::Tuple<TupleType...> &arg)
|
||||
{
|
||||
unroll_args_instance<sizeof...(TupleType)>::template exec<T>(Shader, arg);
|
||||
//unroll_args_instance<STK::TupleSize<STK::Tuple<TupleType...> >::value >::template exec<T>(Shader, arg);
|
||||
}
|
||||
|
||||
template<int...List>
|
||||
struct custom_unroll_args;
|
||||
struct remap_tuple;
|
||||
|
||||
template<>
|
||||
struct custom_unroll_args<>
|
||||
struct remap_tuple<>
|
||||
{
|
||||
template<typename T, typename ...TupleTypes, typename ...Args>
|
||||
static void exec(const T *Shader, const STK::Tuple<TupleTypes...> &t, Args... args)
|
||||
template<typename...OriginalTuples, typename...Args>
|
||||
static STK::Tuple <Args...> exec(const STK::Tuple<OriginalTuples...> &oldt, Args... args)
|
||||
{
|
||||
draw<T>(Shader, STK::tuple_get<0>(t), args...);
|
||||
return STK::make_tuple(args...);
|
||||
}
|
||||
};
|
||||
|
||||
template<int N, int...List>
|
||||
struct custom_unroll_args<N, List...>
|
||||
struct remap_tuple<N, List...>
|
||||
{
|
||||
template<typename T, typename ...TupleTypes, typename ...Args>
|
||||
static void exec(const T *Shader, const STK::Tuple<TupleTypes...> &t, Args... args)
|
||||
template<typename...OriginalTuples, typename...Args>
|
||||
static auto exec(const STK::Tuple<OriginalTuples...> &oldt, Args...args)
|
||||
-> decltype(remap_tuple<List...>::template exec(oldt, STK::tuple_get<N>(oldt), args...))
|
||||
{
|
||||
custom_unroll_args<List...>::template exec<T>(Shader, t, STK::tuple_get<N>(t), args...);
|
||||
return remap_tuple<List...>::template exec(oldt, STK::tuple_get<N>(oldt), args...);
|
||||
}
|
||||
};
|
||||
|
||||
template<int N>
|
||||
struct unroll_args_impl;
|
||||
|
||||
template<>
|
||||
struct unroll_args_impl<0>
|
||||
{
|
||||
template<typename ...Args>
|
||||
static void exec(std::function<void (Args...)> f, const STK::Tuple<Args...> &t, Args... args)
|
||||
{
|
||||
f(args...);
|
||||
}
|
||||
};
|
||||
|
||||
template<int N>
|
||||
struct unroll_args_impl
|
||||
{
|
||||
template<typename ...TupleType, typename ...Args>
|
||||
static void exec(std::function<void (TupleType...)> f, const STK::Tuple<TupleType...> &t, Args... args)
|
||||
{
|
||||
unroll_args_impl<N - 1>::exec(f, t, STK::tuple_get<N - 1>(t), args...);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename...Args>
|
||||
static void unroll_args(std::function<void (Args...)> f, const STK::Tuple<Args...> &t)
|
||||
{
|
||||
unroll_args_impl<sizeof...(Args) >::exec(f, t);
|
||||
}
|
||||
|
||||
template<typename T, typename... Args>
|
||||
void apply_instance(const T *Shader, const GLMesh *mesh, const STK::Tuple<Args...> &t)
|
||||
{
|
||||
std::function<void (Args...)> lambda = [&](Args...args) { draw<T>(Shader, mesh, args...); };
|
||||
unroll_args(lambda, t);
|
||||
}
|
||||
|
||||
template<typename Shader, enum E_VERTEX_TYPE VertexType, int ...List, typename... TupleType>
|
||||
void renderMeshes1stPass(const std::vector<TexUnit> &TexUnits, std::vector<STK::Tuple<TupleType...> > &meshes)
|
||||
@ -176,7 +173,8 @@ void renderMeshes1stPass(const std::vector<TexUnit> &TexUnits, std::vector<STK::
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
custom_unroll_args<List...>::template exec(Shader::getInstance(), meshes[i]);
|
||||
auto remapped_tuple = remap_tuple<List...>::exec(meshes[i]);
|
||||
apply_instance<Shader>(Shader::getInstance(), &mesh, remapped_tuple);
|
||||
}
|
||||
}
|
||||
|
||||
@ -257,7 +255,8 @@ void renderMeshes2ndPass(const std::vector<TexUnit> &TexUnits, std::vector<STK::
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
custom_unroll_args<List...>::template exec(Shader::getInstance(), meshes[i]);
|
||||
auto remapped_tuple = remap_tuple<List...>::exec(meshes[i]);
|
||||
apply_instance<Shader>(Shader::getInstance(), &mesh, remapped_tuple);
|
||||
}
|
||||
}
|
||||
|
||||
@ -501,28 +500,13 @@ void drawShadow(const T *Shader, const GLMesh *mesh, uniforms... Args)
|
||||
glDrawElementsInstancedBaseVertex(ptype, count, itype, (GLvoid *)mesh->vaoOffset, 4, mesh->vaoBaseVertex);
|
||||
}
|
||||
|
||||
template<int...List>
|
||||
struct shadow_custom_unroll_args;
|
||||
|
||||
template<>
|
||||
struct shadow_custom_unroll_args<>
|
||||
template<typename T, typename...Args>
|
||||
void drawShadowTuple(const T *Shader, const GLMesh *mesh, const STK::Tuple<Args...> &t)
|
||||
{
|
||||
template<typename T, typename ...TupleTypes, typename ...Args>
|
||||
static void exec(const T *Shader, const STK::Tuple<TupleTypes...> &t, Args... args)
|
||||
{
|
||||
drawShadow<T>(Shader, STK::tuple_get<0>(t), args...);
|
||||
}
|
||||
};
|
||||
|
||||
template<int N, int...List>
|
||||
struct shadow_custom_unroll_args<N, List...>
|
||||
{
|
||||
template<typename T, typename ...TupleTypes, typename ...Args>
|
||||
static void exec(const T *Shader, const STK::Tuple<TupleTypes...> &t, Args... args)
|
||||
{
|
||||
shadow_custom_unroll_args<List...>::template exec<T>(Shader, t, STK::tuple_get<N>(t), args...);
|
||||
}
|
||||
};
|
||||
std::function<void (Args...)> lambda = [&](Args...args) { drawShadow<T>(Shader, mesh, args...); };
|
||||
unroll_args(lambda, t);
|
||||
}
|
||||
|
||||
template<typename T, enum E_VERTEX_TYPE VertexType, int...List, typename... Args>
|
||||
void renderShadow(const std::vector<GLuint> TextureUnits, const std::vector<STK::Tuple<GLMesh *, core::matrix4, Args...> >&t)
|
||||
@ -538,36 +522,17 @@ void renderShadow(const std::vector<GLuint> TextureUnits, const std::vector<STK:
|
||||
setTexture(TextureUnits[j], getTextureGLuint(mesh->textures[j]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
|
||||
}
|
||||
|
||||
shadow_custom_unroll_args<List...>::template exec<T>(T::getInstance(), t[i]);
|
||||
auto remapped_tuple = remap_tuple<List...>::exec(t[i]);
|
||||
drawShadowTuple<T>(T::getInstance(), mesh, remapped_tuple);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<int...List>
|
||||
struct rsm_custom_unroll_args;
|
||||
|
||||
template<>
|
||||
struct rsm_custom_unroll_args<>
|
||||
template<typename T, typename... Args>
|
||||
void drawRSMTuple(const core::matrix4 &rsm_matrix, const GLMesh *mesh, const STK::Tuple<Args...> &t)
|
||||
{
|
||||
template<typename T, typename ...TupleTypes, typename ...Args>
|
||||
static void exec(const core::matrix4 &rsm_matrix, const STK::Tuple<TupleTypes...> &t, Args... args)
|
||||
{
|
||||
draw<T>(T::getInstance(), STK::tuple_get<0>(t), rsm_matrix, args...);
|
||||
}
|
||||
};
|
||||
|
||||
template<int N, int...List>
|
||||
struct rsm_custom_unroll_args<N, List...>
|
||||
{
|
||||
template<typename T, typename ...TupleTypes, typename ...Args>
|
||||
static void exec(const core::matrix4 &rsm_matrix, const STK::Tuple<TupleTypes...> &t, Args... args)
|
||||
{
|
||||
rsm_custom_unroll_args<List...>::template exec<T>(rsm_matrix, t, STK::tuple_get<N>(t), args...);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
std::function<void (Args...)> lambda = [&](Args...args) {draw<T>(T::getInstance(), mesh, rsm_matrix, args...); };
|
||||
unroll_args(lambda, t);
|
||||
}
|
||||
|
||||
template<typename T, enum E_VERTEX_TYPE VertexType, int... Selector, typename... Args>
|
||||
void drawRSM(const core::matrix4 & rsm_matrix, const std::vector<GLuint> TextureUnits, const std::vector<STK::Tuple<GLMesh *, core::matrix4, Args...> >&t)
|
||||
@ -584,7 +549,8 @@ void drawRSM(const core::matrix4 & rsm_matrix, const std::vector<GLuint> Texture
|
||||
compressTexture(mesh->textures[j], true);
|
||||
setTexture(TextureUnits[j], getTextureGLuint(mesh->textures[j]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
|
||||
}
|
||||
rsm_custom_unroll_args<Selector...>::template exec<T>(rsm_matrix, t[i]);
|
||||
auto remapped_tuple = remap_tuple<Selector...>::template exec(t[i]);
|
||||
drawRSMTuple<T>(rsm_matrix, mesh, remapped_tuple);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -136,12 +136,12 @@ void IrrDriver::renderLights(unsigned pointlightcount)
|
||||
ScopedGPUTimer timer(irr_driver->getGPUTimer(Q_RH));
|
||||
glDisable(GL_BLEND);
|
||||
m_rtts->getRH().Bind();
|
||||
glUseProgram(FullScreenShader::RadianceHintsConstructionShader::Program);
|
||||
glBindVertexArray(FullScreenShader::RadianceHintsConstructionShader::vao);
|
||||
setTexture(0, m_rtts->getRSM().getRTT()[0], GL_LINEAR, GL_LINEAR);
|
||||
setTexture(1, m_rtts->getRSM().getRTT()[1], GL_LINEAR, GL_LINEAR);
|
||||
setTexture(2, m_rtts->getRSM().getDepthTexture(), GL_LINEAR, GL_LINEAR);
|
||||
FullScreenShader::RadianceHintsConstructionShader::setUniforms(rsm_matrix, rh_matrix, rh_extend, 0, 1, 2);
|
||||
glUseProgram(FullScreenShader::RadianceHintsConstructionShader::getInstance()->Program);
|
||||
glBindVertexArray(FullScreenShader::RadianceHintsConstructionShader::getInstance()->vao);
|
||||
setTexture(FullScreenShader::RadianceHintsConstructionShader::getInstance()->TU_ctex, m_rtts->getRSM().getRTT()[0], GL_LINEAR, GL_LINEAR);
|
||||
setTexture(FullScreenShader::RadianceHintsConstructionShader::getInstance()->TU_ntex, m_rtts->getRSM().getRTT()[1], GL_LINEAR, GL_LINEAR);
|
||||
setTexture(FullScreenShader::RadianceHintsConstructionShader::getInstance()->TU_dtex, m_rtts->getRSM().getDepthTexture(), GL_LINEAR, GL_LINEAR);
|
||||
FullScreenShader::RadianceHintsConstructionShader::getInstance()->setUniforms(rsm_matrix, rh_matrix, rh_extend);
|
||||
glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, 32);
|
||||
}
|
||||
|
||||
@ -192,4 +192,4 @@ void IrrDriver::renderSSAO()
|
||||
FrameBuffer::Blit(m_rtts->getFBO(FBO_SSAO), m_rtts->getFBO(FBO_HALF1_R), GL_COLOR_BUFFER_BIT, GL_LINEAR);
|
||||
m_post_processing->renderGaussian17TapBlur(irr_driver->getFBO(FBO_HALF1_R), irr_driver->getFBO(FBO_HALF2_R));
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -375,7 +375,6 @@ void Shaders::loadShaders()
|
||||
initShadowVPMUBO();
|
||||
FullScreenShader::BloomBlendShader::init();
|
||||
FullScreenShader::BloomShader::init();
|
||||
FullScreenShader::FogShader::init();
|
||||
FullScreenShader::Gaussian17TapHShader::init();
|
||||
FullScreenShader::ComputeGaussian17TapHShader::init();
|
||||
FullScreenShader::Gaussian3HBlurShader::init();
|
||||
@ -387,11 +386,8 @@ void Shaders::loadShaders()
|
||||
FullScreenShader::GlowShader::init();
|
||||
FullScreenShader::PassThroughShader::init();
|
||||
FullScreenShader::LayerPassThroughShader::init();
|
||||
FullScreenShader::LinearizeDepthShader::init();
|
||||
FullScreenShader::DiffuseEnvMapShader::init();
|
||||
FullScreenShader::RadianceHintsConstructionShader::init();
|
||||
FullScreenShader::RHDebug::init();
|
||||
FullScreenShader::GlobalIlluminationReconstructionShader::init();
|
||||
FullScreenShader::MotionBlurShader::init();
|
||||
FullScreenShader::GodFadeShader::init();
|
||||
FullScreenShader::GodRayShader::init();
|
||||
@ -1701,16 +1697,7 @@ namespace FullScreenShader
|
||||
glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0);
|
||||
}
|
||||
|
||||
GLuint RadianceHintsConstructionShader::Program;
|
||||
GLuint RadianceHintsConstructionShader::uniform_ctex;
|
||||
GLuint RadianceHintsConstructionShader::uniform_ntex;
|
||||
GLuint RadianceHintsConstructionShader::uniform_dtex;
|
||||
GLuint RadianceHintsConstructionShader::uniform_extents;
|
||||
GLuint RadianceHintsConstructionShader::uniform_RHMatrix;
|
||||
GLuint RadianceHintsConstructionShader::uniform_RSMMatrix;
|
||||
GLuint RadianceHintsConstructionShader::vao;
|
||||
|
||||
void RadianceHintsConstructionShader::init()
|
||||
RadianceHintsConstructionShader::RadianceHintsConstructionShader()
|
||||
{
|
||||
if (irr_driver->getGLSLVersion() < 150)
|
||||
return;
|
||||
@ -1728,25 +1715,14 @@ namespace FullScreenShader
|
||||
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/rh.frag").c_str());
|
||||
}
|
||||
|
||||
uniform_ctex = glGetUniformLocation(Program, "ctex");
|
||||
uniform_ntex = glGetUniformLocation(Program, "ntex");
|
||||
uniform_dtex = glGetUniformLocation(Program, "dtex");
|
||||
uniform_extents = glGetUniformLocation(Program, "extents");
|
||||
uniform_RHMatrix = glGetUniformLocation(Program, "RHMatrix");
|
||||
uniform_RSMMatrix = glGetUniformLocation(Program, "RSMMatrix");
|
||||
AssignUniforms("RSMMatrix", "RHMatrix", "extents");
|
||||
TU_ctex = 0;
|
||||
TU_ntex = 1;
|
||||
TU_dtex = 2;
|
||||
AssignTextureUnit(Program, TexUnit(TU_ctex, "ctex"), TexUnit(TU_ntex, "ntex"), TexUnit(TU_dtex, "dtex"));
|
||||
vao = createFullScreenVAO(Program);
|
||||
}
|
||||
|
||||
void RadianceHintsConstructionShader::setUniforms(const core::matrix4 &RSMMatrix, const core::matrix4 &RHMatrix, const core::vector3df &extents, unsigned TU_ctex, unsigned TU_ntex, unsigned TU_dtex)
|
||||
{
|
||||
glUniformMatrix4fv(uniform_RSMMatrix, 1, GL_FALSE, RSMMatrix.pointer());
|
||||
glUniformMatrix4fv(uniform_RHMatrix, 1, GL_FALSE, RHMatrix.pointer());
|
||||
glUniform1i(uniform_ctex, TU_ctex);
|
||||
glUniform1i(uniform_ntex, TU_ntex);
|
||||
glUniform1i(uniform_dtex, TU_dtex);
|
||||
glUniform3f(uniform_extents, extents.X, extents.Y, extents.Z);
|
||||
}
|
||||
|
||||
GLuint RHDebug::Program;
|
||||
GLuint RHDebug::uniform_extents;
|
||||
GLuint RHDebug::uniform_SHR;
|
||||
@ -1777,49 +1753,26 @@ namespace FullScreenShader
|
||||
glUniform1i(uniform_SHB, TU_SHB);
|
||||
}
|
||||
|
||||
GLuint GlobalIlluminationReconstructionShader::Program;
|
||||
GLuint GlobalIlluminationReconstructionShader::uniform_ntex;
|
||||
GLuint GlobalIlluminationReconstructionShader::uniform_dtex;
|
||||
GLuint GlobalIlluminationReconstructionShader::uniform_SHR;
|
||||
GLuint GlobalIlluminationReconstructionShader::uniform_SHG;
|
||||
GLuint GlobalIlluminationReconstructionShader::uniform_SHB;
|
||||
GLuint GlobalIlluminationReconstructionShader::uniform_extents;
|
||||
GLuint GlobalIlluminationReconstructionShader::uniform_RHMatrix;
|
||||
GLuint GlobalIlluminationReconstructionShader::uniform_InvRHMatrix;
|
||||
GLuint GlobalIlluminationReconstructionShader::vao;
|
||||
|
||||
void GlobalIlluminationReconstructionShader::init()
|
||||
GlobalIlluminationReconstructionShader::GlobalIlluminationReconstructionShader()
|
||||
{
|
||||
Program = LoadProgram(
|
||||
GL_VERTEX_SHADER, file_manager->getAsset("shaders/screenquad.vert").c_str(),
|
||||
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/decodeNormal.frag").c_str(),
|
||||
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/getPosFromUVDepth.frag").c_str(),
|
||||
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/gi.frag").c_str());
|
||||
uniform_ntex = glGetUniformLocation(Program, "ntex");
|
||||
uniform_dtex = glGetUniformLocation(Program, "dtex");
|
||||
uniform_SHR = glGetUniformLocation(Program, "SHR");
|
||||
uniform_SHG = glGetUniformLocation(Program, "SHG");
|
||||
uniform_SHB = glGetUniformLocation(Program, "SHB");
|
||||
uniform_RHMatrix = glGetUniformLocation(Program, "RHMatrix");
|
||||
uniform_InvRHMatrix = glGetUniformLocation(Program, "InvRHMatrix");
|
||||
uniform_extents = glGetUniformLocation(Program, "extents");
|
||||
|
||||
AssignUniforms("RHMatrix", "InvRHMatrix", "extents");
|
||||
TU_ntex = 0;
|
||||
TU_dtex = 1;
|
||||
TU_SHR = 2;
|
||||
TU_SHG = 3;
|
||||
TU_SHB = 4;
|
||||
AssignTextureUnit(Program, TexUnit(TU_ntex, "ntex"), TexUnit(TU_dtex, "dtex"), TexUnit(TU_SHR, "SHR"), TexUnit(TU_SHG, "SHG"), TexUnit(TU_SHB, "SHB"));
|
||||
vao = createFullScreenVAO(Program);
|
||||
GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData");
|
||||
glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0);
|
||||
}
|
||||
|
||||
void GlobalIlluminationReconstructionShader::setUniforms(const core::matrix4 &RHMatrix, const core::matrix4 &InvRHMatrix, const core::vector3df &extents, unsigned TU_ntex, unsigned TU_dtex, unsigned TU_SHR, unsigned TU_SHG, unsigned TU_SHB)
|
||||
{
|
||||
glUniformMatrix4fv(uniform_RHMatrix, 1, GL_FALSE, RHMatrix.pointer());
|
||||
glUniformMatrix4fv(uniform_InvRHMatrix, 1, GL_FALSE, InvRHMatrix.pointer());
|
||||
glUniform1i(uniform_ntex, TU_ntex);
|
||||
glUniform1i(uniform_dtex, TU_dtex);
|
||||
glUniform1i(uniform_SHR, TU_SHR);
|
||||
glUniform1i(uniform_SHG, TU_SHG);
|
||||
glUniform1i(uniform_SHB, TU_SHB);
|
||||
glUniform3f(uniform_extents, extents.X, extents.Y, extents.Z);
|
||||
}
|
||||
|
||||
GLuint Gaussian17TapHShader::Program;
|
||||
GLuint Gaussian17TapHShader::uniform_tex;
|
||||
GLuint Gaussian17TapHShader::uniform_depth;
|
||||
@ -1968,29 +1921,17 @@ namespace FullScreenShader
|
||||
vao = createVAO(Program);
|
||||
}
|
||||
|
||||
GLuint LinearizeDepthShader::Program;
|
||||
GLuint LinearizeDepthShader::uniform_zn;
|
||||
GLuint LinearizeDepthShader::uniform_zf;
|
||||
GLuint LinearizeDepthShader::uniform_texture;
|
||||
GLuint LinearizeDepthShader::vao;
|
||||
void LinearizeDepthShader::init()
|
||||
LinearizeDepthShader::LinearizeDepthShader()
|
||||
{
|
||||
Program = LoadProgram(
|
||||
GL_VERTEX_SHADER, file_manager->getAsset("shaders/screenquad.vert").c_str(),
|
||||
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/linearizedepth.frag").c_str());
|
||||
uniform_texture = glGetUniformLocation(Program, "texture");
|
||||
uniform_zf = glGetUniformLocation(Program, "zf");
|
||||
uniform_zn = glGetUniformLocation(Program, "zn");
|
||||
AssignUniforms("zn", "zf");
|
||||
TU_tex = 0;
|
||||
AssignTextureUnit(Program, TexUnit(TU_tex, "texture"));
|
||||
vao = createFullScreenVAO(Program);
|
||||
}
|
||||
|
||||
void LinearizeDepthShader::setUniforms(float zn, float zf, unsigned TU_tex)
|
||||
{
|
||||
glUniform1f(uniform_zn, zn);
|
||||
glUniform1f(uniform_zf, zf);
|
||||
glUniform1i(uniform_texture, TU_tex);
|
||||
}
|
||||
|
||||
GLuint GlowShader::Program;
|
||||
GLuint GlowShader::uniform_tex;
|
||||
GLuint GlowShader::vao;
|
||||
@ -2019,48 +1960,21 @@ namespace FullScreenShader
|
||||
glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0);
|
||||
}
|
||||
|
||||
GLuint FogShader::Program;
|
||||
GLuint FogShader::uniform_tex;
|
||||
GLuint FogShader::uniform_fogmax;
|
||||
GLuint FogShader::uniform_startH;
|
||||
GLuint FogShader::uniform_endH;
|
||||
GLuint FogShader::uniform_start;
|
||||
GLuint FogShader::uniform_end;
|
||||
GLuint FogShader::uniform_col;
|
||||
GLuint FogShader::vao;
|
||||
|
||||
void FogShader::init()
|
||||
FogShader::FogShader()
|
||||
{
|
||||
Program = LoadProgram(
|
||||
GL_VERTEX_SHADER, file_manager->getAsset("shaders/screenquad.vert").c_str(),
|
||||
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/getPosFromUVDepth.frag").c_str(),
|
||||
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/fog.frag").c_str());
|
||||
uniform_tex = glGetUniformLocation(Program, "tex");
|
||||
uniform_fogmax = glGetUniformLocation(Program, "fogmax");
|
||||
uniform_startH = glGetUniformLocation(Program, "startH");
|
||||
uniform_endH = glGetUniformLocation(Program, "endH");
|
||||
uniform_start = glGetUniformLocation(Program, "start");
|
||||
uniform_end = glGetUniformLocation(Program, "end");
|
||||
uniform_col = glGetUniformLocation(Program, "col");
|
||||
TU_tex = 0;
|
||||
AssignUniforms("fogmax", "startH", "endH", "start", "end", "col");
|
||||
AssignTextureUnit(Program, TexUnit(TU_tex, "tex"));
|
||||
vao = createFullScreenVAO(Program);
|
||||
|
||||
GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData");
|
||||
glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0);
|
||||
}
|
||||
|
||||
void FogShader::setUniforms(float fogmax, float startH, float endH, float start, float end, const core::vector3df &col, unsigned TU_ntex)
|
||||
{
|
||||
if (irr_driver->needUBOWorkaround())
|
||||
bypassUBO(Program);
|
||||
glUniform1f(uniform_fogmax, fogmax);
|
||||
glUniform1f(uniform_startH, startH);
|
||||
glUniform1f(uniform_endH, endH);
|
||||
glUniform1f(uniform_start, start);
|
||||
glUniform1f(uniform_end, end);
|
||||
glUniform3f(uniform_col, col.X, col.Y, col.Z);
|
||||
glUniform1i(uniform_tex, TU_ntex);
|
||||
}
|
||||
|
||||
GLuint MotionBlurShader::Program;
|
||||
GLuint MotionBlurShader::uniform_boost_amount;
|
||||
GLuint MotionBlurShader::uniform_center;
|
||||
|
@ -589,15 +589,13 @@ public:
|
||||
ShadowedSunLightShader();
|
||||
};
|
||||
|
||||
class RadianceHintsConstructionShader
|
||||
class RadianceHintsConstructionShader : public ShaderHelperSingleton<RadianceHintsConstructionShader, core::matrix4, core::matrix4, core::vector3df>
|
||||
{
|
||||
public:
|
||||
static GLuint Program;
|
||||
static GLuint uniform_ctex, uniform_ntex, uniform_dtex, uniform_extents, uniform_RHMatrix, uniform_RSMMatrix;
|
||||
static GLuint vao;
|
||||
GLuint TU_ctex, TU_ntex, TU_dtex;
|
||||
GLuint vao;
|
||||
|
||||
static void init();
|
||||
static void setUniforms(const core::matrix4 &RSMMatrix, const core::matrix4 &RHMatrix, const core::vector3df &extents, unsigned TU_ctex, unsigned TU_ntex, unsigned TU_dtex);
|
||||
RadianceHintsConstructionShader();
|
||||
};
|
||||
|
||||
class RHDebug
|
||||
@ -610,15 +608,13 @@ public:
|
||||
static void setUniforms(const core::matrix4 &RHMatrix, const core::vector3df &extents, unsigned TU_SHR, unsigned TU_SHG, unsigned TU_SHB);
|
||||
};
|
||||
|
||||
class GlobalIlluminationReconstructionShader
|
||||
class GlobalIlluminationReconstructionShader : public ShaderHelperSingleton<GlobalIlluminationReconstructionShader, core::matrix4, core::matrix4, core::vector3df>
|
||||
{
|
||||
public:
|
||||
static GLuint Program;
|
||||
static GLuint uniform_ntex, uniform_dtex, uniform_extents, uniform_SHR, uniform_SHG, uniform_SHB, uniform_RHMatrix, uniform_InvRHMatrix;
|
||||
static GLuint vao;
|
||||
GLuint TU_ntex, TU_dtex, TU_SHR, TU_SHG, TU_SHB, uniform_RHMatrix;
|
||||
GLuint vao;
|
||||
|
||||
static void init();
|
||||
static void setUniforms(const core::matrix4 &RHMatrix, const core::matrix4 &InvRHMatrix, const core::vector3df &extents, unsigned TU_ntex, unsigned TU_dtex, unsigned TU_SHR, unsigned TU_SHG, unsigned TU_SHB);
|
||||
GlobalIlluminationReconstructionShader();
|
||||
};
|
||||
|
||||
class Gaussian17TapHShader
|
||||
@ -720,15 +716,13 @@ public:
|
||||
static void init();
|
||||
};
|
||||
|
||||
class LinearizeDepthShader
|
||||
class LinearizeDepthShader : public ShaderHelperSingleton<LinearizeDepthShader, float, float>
|
||||
{
|
||||
public:
|
||||
static GLuint Program;
|
||||
static GLuint uniform_zn, uniform_zf, uniform_texture;
|
||||
static GLuint vao;
|
||||
GLuint TU_tex;
|
||||
GLuint vao;
|
||||
|
||||
static void init();
|
||||
static void setUniforms(float zn, float zf, unsigned TU_tex);
|
||||
LinearizeDepthShader();
|
||||
};
|
||||
|
||||
class GlowShader
|
||||
@ -750,15 +744,13 @@ public:
|
||||
SSAOShader();
|
||||
};
|
||||
|
||||
class FogShader
|
||||
class FogShader : public ShaderHelperSingleton<FogShader, float, float, float, float, float, core::vector3df>
|
||||
{
|
||||
public:
|
||||
static GLuint Program;
|
||||
static GLuint uniform_tex, uniform_fogmax, uniform_startH, uniform_endH, uniform_start, uniform_end, uniform_col;
|
||||
static GLuint vao;
|
||||
GLuint TU_tex;
|
||||
GLuint vao;
|
||||
|
||||
static void init();
|
||||
static void setUniforms(float fogmax, float startH, float endH, float start, float end, const core::vector3df &col, unsigned TU_ntex);
|
||||
FogShader();
|
||||
};
|
||||
|
||||
class MotionBlurShader
|
||||
|
@ -343,6 +343,7 @@ void Kart::reset()
|
||||
m_has_started = false;
|
||||
m_wheel_rotation = 0;
|
||||
m_bounce_back_time = 0.0f;
|
||||
m_brake_time = 0.0f;
|
||||
m_time_last_crash = 0.0f;
|
||||
m_speed = 0.0f;
|
||||
m_current_lean = 0.0f;
|
||||
@ -1098,7 +1099,7 @@ void Kart::update(float dt)
|
||||
|
||||
// TODO: hiker said this probably will be moved to btKart or so when updating bullet engine.
|
||||
// Neutralize any yaw change if the kart leaves the ground, so the kart falls more or less
|
||||
// straight after jumping, but still allowing some "boat shake" (roll and pitch).
|
||||
// straight after jumping, but still allowing some "boat shake" (roIll and pitch).
|
||||
// Otherwise many non perfect jumps end in a total roll over or a serious change of
|
||||
// direction, sometimes 90 or even full U turn (real but less fun for a karting game).
|
||||
// As side effect steering becames a bit less responsive (any wheel on air), but not too bad.
|
||||
@ -2023,30 +2024,6 @@ void Kart::updatePhysics(float dt)
|
||||
m_max_speed->setMinSpeed(min_speed);
|
||||
m_max_speed->update(dt);
|
||||
|
||||
// If the kart is flying, keep its up-axis aligned to gravity (which in
|
||||
// turn typically means the kart is parallel to the ground). This avoids
|
||||
// that the kart rotates in mid-air and lands on its side.
|
||||
if(m_vehicle->getNumWheelsOnGround()==0)
|
||||
{
|
||||
btVector3 kart_up = getTrans().getBasis().getColumn(1); // up vector
|
||||
btVector3 terrain_up = m_body->getGravity();
|
||||
float g = World::getWorld()->getTrack()->getGravity();
|
||||
// Normalize the gravity, g is the length of the vector
|
||||
btVector3 new_up = 0.9f * kart_up + 0.1f * terrain_up/-g;
|
||||
// Get the rotation (hpr) based on current heading.
|
||||
Vec3 rotation(getHeading(), new_up);
|
||||
btMatrix3x3 m;
|
||||
m.setEulerZYX(rotation.getX(), rotation.getY(), rotation.getZ());
|
||||
// We can't use getXYZ() for the position here, since the position is
|
||||
// based on interpolation, while the actual center-of-mass-transform
|
||||
// is based on the actual value every 1/60 of a second (using getXYZ()
|
||||
// would result in the kart being pushed ahead a bit, making it jump
|
||||
// much further, depending on fps)
|
||||
btTransform new_trans(m, m_body->getCenterOfMassTransform().getOrigin());
|
||||
//setTrans(new_trans);
|
||||
m_body->setCenterOfMassTransform(new_trans);
|
||||
}
|
||||
|
||||
// To avoid tunneling (which can happen on long falls), clamp the
|
||||
// velocity in Y direction. Tunneling can happen if the Y velocity
|
||||
// is larger than the maximum suspension travel (per frame), since then
|
||||
@ -2174,6 +2151,7 @@ void Kart::updateEnginePowerAndBrakes(float dt)
|
||||
if(m_vehicle->getWheelInfo(0).m_brake &&
|
||||
!World::getWorld()->isStartPhase())
|
||||
m_vehicle->setAllBrakes(0);
|
||||
m_brake_time = 0;
|
||||
}
|
||||
else
|
||||
{ // not accelerating
|
||||
@ -2183,9 +2161,11 @@ void Kart::updateEnginePowerAndBrakes(float dt)
|
||||
if(m_speed > 0.0f)
|
||||
{ // Still going forward while braking
|
||||
applyEngineForce(0.f);
|
||||
|
||||
//apply the brakes
|
||||
m_vehicle->setAllBrakes(m_kart_properties->getBrakeFactor());
|
||||
m_brake_time += dt;
|
||||
// Apply the brakes - include the time dependent brake increase
|
||||
float f = 1 + m_brake_time
|
||||
* getKartProperties()->getBrakeTimeIncrease();
|
||||
m_vehicle->setAllBrakes(m_kart_properties->getBrakeFactor()*f);
|
||||
}
|
||||
else // m_speed < 0
|
||||
{
|
||||
@ -2209,6 +2189,7 @@ void Kart::updateEnginePowerAndBrakes(float dt)
|
||||
}
|
||||
else // !m_brake
|
||||
{
|
||||
m_brake_time = 0;
|
||||
// lift the foot from throttle, brakes with 10% engine_power
|
||||
assert(!isnan(m_controls.m_accel));
|
||||
assert(!isnan(engine_power));
|
||||
@ -2551,6 +2532,8 @@ void Kart::updateGraphics(float dt, const Vec3& offset_xyz,
|
||||
center_shift = getTrans().getBasis() * center_shift;
|
||||
|
||||
float heading = m_skidding->getVisualSkidRotation();
|
||||
center_shift = Vec3(0, m_skidding->getGraphicalJumpOffset() + lean_height, 0);
|
||||
center_shift = getTrans().getBasis() * center_shift;
|
||||
Moveable::updateGraphics(dt, center_shift,
|
||||
btQuaternion(heading, 0, m_current_lean));
|
||||
|
||||
|
@ -116,9 +116,13 @@ private:
|
||||
* determine startup boost. */
|
||||
bool m_has_started;
|
||||
|
||||
/**<Maximum engine rpm's for the current gear*/
|
||||
/** Maximum engine rpm's for the current gear. */
|
||||
float m_max_gear_rpm;
|
||||
|
||||
/** How long the brake key has been pressed - the longer the harder
|
||||
* the kart will brake. */
|
||||
float m_brake_time;
|
||||
|
||||
/** A short time after a collision acceleration is disabled to allow
|
||||
* the karts to bounce back*/
|
||||
float m_bounce_back_time;
|
||||
|
@ -64,7 +64,7 @@ KartProperties::KartProperties(const std::string &filename)
|
||||
|
||||
// Set all other values to undefined, so that it can later be tested
|
||||
// if everything is defined properly.
|
||||
m_mass = m_brake_factor =
|
||||
m_mass = m_brake_factor = m_brake_time_increase =
|
||||
m_time_reset_steer = m_nitro_consumption = m_nitro_engine_force =
|
||||
m_nitro_small_container = m_nitro_big_container = m_nitro_max =
|
||||
m_nitro_max_speed_increase = m_nitro_duration = m_nitro_fade_out_time =
|
||||
@ -92,6 +92,7 @@ KartProperties::KartProperties(const std::string &filename)
|
||||
m_squash_duration = m_downward_impulse_factor =
|
||||
m_bubblegum_fade_in_time = m_bubblegum_speed_fraction =
|
||||
m_bubblegum_time = m_bubblegum_torque = m_jump_animation_time =
|
||||
m_smooth_flying_impulse =
|
||||
UNDEFINED;
|
||||
|
||||
m_engine_power.resize(RaceManager::DIFFICULTY_COUNT, UNDEFINED);
|
||||
@ -370,6 +371,7 @@ void KartProperties::getAllData(const XMLNode * root)
|
||||
&m_downward_impulse_factor);
|
||||
stability_node->get("track-connection-accel",
|
||||
&m_track_connection_accel );
|
||||
stability_node->get("smooth-flying-impulse", &m_smooth_flying_impulse);
|
||||
}
|
||||
|
||||
if(const XMLNode *collision_node = root->getNode("collision"))
|
||||
@ -527,7 +529,8 @@ void KartProperties::getAllData(const XMLNode * root)
|
||||
|
||||
if(const XMLNode *engine_node = root->getNode("engine"))
|
||||
{
|
||||
engine_node->get("brake-factor", &m_brake_factor);
|
||||
engine_node->get("brake-factor", &m_brake_factor);
|
||||
engine_node->get("brake-time-increase", &m_brake_time_increase);
|
||||
engine_node->get("max-speed-reverse-ratio", &m_max_speed_reverse_ratio);
|
||||
engine_node->get("power", &m_engine_power);
|
||||
if(m_engine_power.size()!=RaceManager::DIFFICULTY_COUNT)
|
||||
@ -659,8 +662,10 @@ void KartProperties::checkAllSet(const std::string &filename)
|
||||
CHECK_NEG(m_chassis_angular_damping, "stability chassis-angular-damping");
|
||||
CHECK_NEG(m_downward_impulse_factor, "stability downward-impulse-factor");
|
||||
CHECK_NEG(m_track_connection_accel, "stability track-connection-accel" );
|
||||
CHECK_NEG(m_smooth_flying_impulse, "smooth-flying-impulse" );
|
||||
CHECK_NEG(m_max_speed_reverse_ratio, "engine max-speed-reverse-ratio");
|
||||
CHECK_NEG(m_brake_factor, "engine brake-factor" );
|
||||
CHECK_NEG(m_brake_time_increase, "engine brake-time-increase" );
|
||||
CHECK_NEG(m_suspension_stiffness, "suspension stiffness" );
|
||||
CHECK_NEG(m_suspension_rest, "suspension rest" );
|
||||
CHECK_NEG(m_suspension_travel_cm, "suspension travel-cm" );
|
||||
|
@ -130,12 +130,19 @@ private:
|
||||
/** Braking factor * engine_power braking force. */
|
||||
float m_brake_factor;
|
||||
|
||||
/** Brake_time * m_brake_time_increase will increase the break time
|
||||
* over time. */
|
||||
float m_brake_time_increase;
|
||||
|
||||
/** Time for player karts to reach full steer angle. */
|
||||
InterpolationArray m_time_full_steer;
|
||||
|
||||
/** Time for steering to go back to zero from full steer. */
|
||||
float m_time_reset_steer;
|
||||
|
||||
/** A torque impulse applied to keep the kart parallel to the ground. */
|
||||
float m_smooth_flying_impulse;;
|
||||
|
||||
/** The turn angle depending on speed. */
|
||||
InterpolationArray m_turn_angle_at_speed;
|
||||
|
||||
@ -501,10 +508,21 @@ public:
|
||||
/** Get braking information. */
|
||||
float getBrakeFactor () const {return m_brake_factor; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the additional brake factor which depends on time. */
|
||||
float getBrakeTimeIncrease() const { return m_brake_time_increase; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the torque scaling factor used to keep the karts parallel to
|
||||
* the ground when flying. */
|
||||
float getSmoothFlyingImpulse() const
|
||||
{
|
||||
return m_smooth_flying_impulse;
|
||||
} // getSmoothFlyingImpulse
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Get maximum reverse speed ratio. */
|
||||
float getMaxSpeedReverseRatio () const
|
||||
{return m_max_speed_reverse_ratio; }
|
||||
float getMaxSpeedReverseRatio() const {return m_max_speed_reverse_ratio; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the engine type (used to change sfx depending on kart size). */
|
||||
|
@ -45,9 +45,8 @@ void GetPeerAddress::asynchronousUpdate()
|
||||
if (m_state == NONE)
|
||||
{
|
||||
m_request = new Online::XMLRequest();
|
||||
PlayerManager::setUserDetails(m_request, "get",
|
||||
"address-management.php");
|
||||
m_request->addParameter("peer_id",m_peer_id);
|
||||
PlayerManager::setUserDetails(m_request, "get", Online::API::SERVER_PATH);
|
||||
m_request->addParameter("peer_id", m_peer_id);
|
||||
|
||||
Online::RequestManager::get()->addRequest(m_request);
|
||||
m_state = REQUEST_PENDING;
|
||||
@ -63,10 +62,12 @@ void GetPeerAddress::asynchronousUpdate()
|
||||
{
|
||||
TransportAddress* addr = static_cast<TransportAddress*>(m_callback_object);
|
||||
result->get("ip", &addr->ip);
|
||||
|
||||
if (addr->ip == NetworkManager::getInstance()->getPublicAddress().ip)
|
||||
result->get("private_port", &addr->port);
|
||||
else
|
||||
result->get("port", &addr->port);
|
||||
|
||||
Log::debug("GetPeerAddress", "Address gotten successfully.");
|
||||
}
|
||||
else
|
||||
|
@ -42,8 +42,7 @@ void HidePublicAddress::asynchronousUpdate()
|
||||
if (m_state == NONE)
|
||||
{
|
||||
m_request = new Online::XMLRequest();
|
||||
PlayerManager::setUserDetails(m_request, "unset",
|
||||
"address-management.php");
|
||||
PlayerManager::setUserDetails(m_request, "unset", Online::API::SERVER_PATH);
|
||||
|
||||
Online::RequestManager::get()->addRequest(m_request);
|
||||
m_state = REQUEST_PENDING;
|
||||
|
@ -44,8 +44,7 @@ void QuickJoinProtocol::asynchronousUpdate()
|
||||
{
|
||||
TransportAddress addr = NetworkManager::getInstance()->getPublicAddress();
|
||||
m_request = new Online::XMLRequest();
|
||||
PlayerManager::setUserDetails(m_request, "quick-join");
|
||||
m_request->setServerURL("address-management.php");
|
||||
PlayerManager::setUserDetails(m_request, "quick-join", Online::API::SERVER_PATH);
|
||||
|
||||
Online::RequestManager::get()->addRequest(m_request);
|
||||
m_state = REQUEST_PENDING;
|
||||
|
@ -72,9 +72,9 @@ void RequestConnection::asynchronousUpdate()
|
||||
case NONE:
|
||||
{
|
||||
m_request = new ServerJoinRequest();
|
||||
PlayerManager::setUserDetails(m_request, "request-connection",
|
||||
"address-management.php");
|
||||
m_request->addParameter("server_id",m_server_id);
|
||||
PlayerManager::setUserDetails(m_request, "request-connection", Online::API::SERVER_PATH);
|
||||
|
||||
m_request->addParameter("server_id", m_server_id);
|
||||
m_request->queue();
|
||||
m_state = REQUEST_PENDING;
|
||||
break;
|
||||
@ -83,6 +83,7 @@ void RequestConnection::asynchronousUpdate()
|
||||
{
|
||||
if (!m_request->isDone())
|
||||
return;
|
||||
|
||||
const XMLNode * result = m_request->getXMLData();
|
||||
std::string rec_success;
|
||||
|
||||
|
@ -183,16 +183,17 @@ void ServerLobbyRoomProtocol::checkIncomingConnectionRequests()
|
||||
last_poll_time = StkTime::getRealTime();
|
||||
TransportAddress addr = NetworkManager::getInstance()->getPublicAddress();
|
||||
Online::XMLRequest* request = new Online::XMLRequest();
|
||||
PlayerManager::setUserDetails(request, "poll-connection-requests",
|
||||
"address-management.php");
|
||||
request->addParameter("address",addr.ip);
|
||||
request->addParameter("port",addr.port);
|
||||
PlayerManager::setUserDetails(request, "poll-connection-requests", Online::API::SERVER_PATH);
|
||||
|
||||
request->addParameter("address", addr.ip);
|
||||
request->addParameter("port", addr.port);
|
||||
|
||||
request->executeNow();
|
||||
assert(request->isDone());
|
||||
|
||||
const XMLNode * result = request->getXMLData();
|
||||
std::string rec_success;
|
||||
|
||||
if(result->get("success", &rec_success))
|
||||
{
|
||||
if(rec_success == "yes")
|
||||
@ -564,7 +565,7 @@ void ServerLobbyRoomProtocol::playerMinorVote(Event* event)
|
||||
* Byte 0 1 5 6 N+6 N+7 N+8
|
||||
* -----------------------------------------------------------
|
||||
* Size | 1 | 4 | 1 | N | 1 | 1 |
|
||||
* Data | 4 | priv token | N | track name | 1 | track number (gp) |
|
||||
* Data | 4 | priv token | N | track name | 1 | track number (gp) |
|
||||
* -----------------------------------------------------------
|
||||
*/
|
||||
void ServerLobbyRoomProtocol::playerTrackVote(Event* event)
|
||||
@ -597,7 +598,7 @@ void ServerLobbyRoomProtocol::playerTrackVote(Event* event)
|
||||
* Byte 0 1 5 6 7 8 9
|
||||
* ---------------------------------------------------------
|
||||
* Size | 1 | 4 | 1 | 1 | 1 | 1 |
|
||||
* Data | 4 | priv token | 1 | reversed | 1 | track number (gp) |
|
||||
* Data | 4 | priv token | 1 | reversed | 1 | track number (gp) |
|
||||
* ---------------------------------------------------------
|
||||
*/
|
||||
void ServerLobbyRoomProtocol::playerReversedVote(Event* event)
|
||||
@ -630,7 +631,7 @@ void ServerLobbyRoomProtocol::playerReversedVote(Event* event)
|
||||
* Byte 0 1 5 6 7 8 9
|
||||
* -----------------------------------------------------
|
||||
* Size | 1 | 4 | 1 | 1 | 1 | 1 |
|
||||
* Data | 4 | priv token | 1 | laps | 1 | track number (gp) |
|
||||
* Data | 4 | priv token | 1 | laps | 1 | track number (gp) |
|
||||
* -----------------------------------------------------
|
||||
*/
|
||||
void ServerLobbyRoomProtocol::playerLapsVote(Event* event)
|
||||
|
@ -43,11 +43,12 @@ void ShowPublicAddress::asynchronousUpdate()
|
||||
{
|
||||
TransportAddress addr = NetworkManager::getInstance()->getPublicAddress();
|
||||
m_request = new Online::XMLRequest();
|
||||
PlayerManager::setUserDetails(m_request, "set",
|
||||
"address-management.php");
|
||||
m_request->addParameter("address",addr.ip);
|
||||
m_request->addParameter("port",addr.port);
|
||||
m_request->addParameter("private_port",NetworkManager::getInstance()->getHost()->getPort());
|
||||
PlayerManager::setUserDetails(m_request, "set", Online::API::SERVER_PATH);
|
||||
|
||||
m_request->addParameter("address", addr.ip);
|
||||
m_request->addParameter("port", addr.port);
|
||||
m_request->addParameter("private_port", NetworkManager::getInstance()->getHost()->getPort());
|
||||
|
||||
Log::info("ShowPublicAddress", "Showing addr %u and port %d", addr.ip, addr.port);
|
||||
|
||||
Online::RequestManager::get()->addRequest(m_request);
|
||||
|
@ -42,12 +42,13 @@ void StartServer::asynchronousUpdate()
|
||||
{
|
||||
TransportAddress addr = NetworkManager::getInstance()->getPublicAddress();
|
||||
m_request = new Online::XMLRequest();
|
||||
PlayerManager::setUserDetails(m_request, "start-server",
|
||||
"address-management.php");
|
||||
m_request->addParameter("address",addr.ip);
|
||||
m_request->addParameter("port",addr.port);
|
||||
m_request->addParameter("private_port",NetworkManager::getInstance()->getHost()->getPort());
|
||||
m_request->addParameter("max_players",UserConfigParams::m_server_max_players);
|
||||
PlayerManager::setUserDetails(m_request, "start", Online::API::SERVER_PATH);
|
||||
|
||||
m_request->addParameter("address", addr.ip);
|
||||
m_request->addParameter("port", addr.port);
|
||||
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);
|
||||
|
||||
Online::RequestManager::get()->addRequest(m_request);
|
||||
|
@ -47,10 +47,11 @@ void StopServer::asynchronousUpdate()
|
||||
{
|
||||
TransportAddress addr = NetworkManager::getInstance()->getPublicAddress();
|
||||
m_request = new Online::XMLRequest();
|
||||
PlayerManager::setUserDetails(m_request, "stop-server",
|
||||
"address-management.php");
|
||||
m_request->addParameter("address",addr.ip);
|
||||
m_request->addParameter("port",addr.port);
|
||||
PlayerManager::setUserDetails(m_request, "stop", Online::API::SERVER_PATH);
|
||||
|
||||
m_request->addParameter("address", addr.ip);
|
||||
m_request->addParameter("port", addr.port);
|
||||
|
||||
Log::info("StopServer", "address %u, port %d", addr.ip, addr.port);
|
||||
|
||||
Online::RequestManager::get()->addRequest(m_request);
|
||||
|
@ -26,12 +26,13 @@
|
||||
#endif
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
|
||||
namespace Online
|
||||
{
|
||||
const std::string API::USER_PATH = "user/";
|
||||
const std::string API::SERVER_PATH = "server/";
|
||||
|
||||
/** Creates a HTTP(S) request that will have a raw string as result. (Can
|
||||
* of course be used if the result doesn't matter.)
|
||||
* \param manage_memory whether or not the RequestManager should take care of
|
||||
@ -60,7 +61,8 @@ namespace Online
|
||||
// A http request should not even be created when internet is disabled
|
||||
assert(UserConfigParams::m_internet_status ==
|
||||
RequestManager::IPERM_ALLOWED);
|
||||
assert(filename.size()>0);
|
||||
assert(filename.size() > 0);
|
||||
|
||||
init();
|
||||
m_filename = file_manager->getAddonsFile(filename);
|
||||
} // HTTPRequest(filename ...)
|
||||
@ -76,6 +78,7 @@ namespace Online
|
||||
// A http request should not even be created when internet is disabled
|
||||
assert(UserConfigParams::m_internet_status ==
|
||||
RequestManager::IPERM_ALLOWED);
|
||||
|
||||
init();
|
||||
m_filename = file_manager->getAddonsFile(filename);
|
||||
} // HTTPRequest(filename ...)
|
||||
@ -95,25 +98,48 @@ namespace Online
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** A handy shortcut that appends the given path to the URL of the
|
||||
* mutiplayer server.
|
||||
* \param path The path to add to the server.
|
||||
* mutiplayer server. It also supports the old (version 1) api,
|
||||
* where a 'action' parameter was sent to 'client-user.php'.
|
||||
* \param path The path to add to the server.(see API::USER_*)
|
||||
* \param action The action to perform. eg: connect, pool
|
||||
*/
|
||||
void HTTPRequest::setServerURL(const std::string& path)
|
||||
void HTTPRequest::setApiURL(const std::string& path,
|
||||
const std::string &action)
|
||||
{
|
||||
setURL((std::string)UserConfigParams::m_server_multiplayer+path);
|
||||
// Old (0.8.1) API: send to client-user.php, and add action as a parameter
|
||||
if(UserConfigParams::m_server_version==1)
|
||||
{
|
||||
setURL( (std::string)UserConfigParams::m_server_multiplayer +
|
||||
"client-user.php" );
|
||||
if(action=="change-password")
|
||||
addParameter("action", "change_password");
|
||||
else if(action=="recover")
|
||||
addParameter("action", "recovery");
|
||||
else
|
||||
addParameter("action", action);
|
||||
}
|
||||
else
|
||||
{
|
||||
setURL(
|
||||
(std::string)UserConfigParams::m_server_multiplayer +
|
||||
+"v"+StringUtils::toString(UserConfigParams::m_server_version)
|
||||
+ "/" + path + // eg: /user/, /server/
|
||||
action + "/" // eg: connect/, pool/, get-server-list/
|
||||
);
|
||||
}
|
||||
} // setServerURL
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** A handy shortcut that appends the given path to the URL of the addons
|
||||
* server.
|
||||
* \param path The path to add to the server.
|
||||
* \param path The path to add to the server, without the trailing slash
|
||||
*/
|
||||
void HTTPRequest::setAddonsURL(const std::string& path)
|
||||
{
|
||||
setURL((std::string)UserConfigParams::m_server_addons
|
||||
+ "/" + path);
|
||||
setURL((std::string)UserConfigParams::m_server_addons + "/" + path);
|
||||
} // set AddonsURL
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Checks the request if it has enough (correct) information to be
|
||||
* executed (and thus allowed to add to the queue).
|
||||
*/
|
||||
@ -128,7 +154,7 @@ namespace Online
|
||||
void HTTPRequest::prepareOperation()
|
||||
{
|
||||
m_curl_session = curl_easy_init();
|
||||
if(!m_curl_session)
|
||||
if (!m_curl_session)
|
||||
{
|
||||
Log::error("HTTPRequest::prepareOperation",
|
||||
"LibCurl session not initialized.");
|
||||
@ -145,9 +171,9 @@ namespace Online
|
||||
curl_easy_setopt(m_curl_session, CURLOPT_LOW_SPEED_LIMIT, 10);
|
||||
curl_easy_setopt(m_curl_session, CURLOPT_LOW_SPEED_TIME, 20);
|
||||
//curl_easy_setopt(m_curl_session, CURLOPT_VERBOSE, 1L);
|
||||
if(m_filename.size()==0)
|
||||
if (m_filename.size() == 0)
|
||||
{
|
||||
//https
|
||||
// https, load certificate info
|
||||
struct curl_slist *chunk = NULL;
|
||||
chunk = curl_slist_append(chunk, "Host: api.stkaddons.net");
|
||||
curl_easy_setopt(m_curl_session, CURLOPT_HTTPHEADER, chunk);
|
||||
@ -163,15 +189,15 @@ namespace Online
|
||||
*/
|
||||
void HTTPRequest::operation()
|
||||
{
|
||||
if(!m_curl_session)
|
||||
if (!m_curl_session)
|
||||
return;
|
||||
|
||||
FILE *fout = NULL;
|
||||
if(m_filename.size()>0)
|
||||
if (m_filename.size() > 0)
|
||||
{
|
||||
fout = fopen((m_filename+".part").c_str(), "wb");
|
||||
|
||||
if(!fout)
|
||||
if (!fout)
|
||||
{
|
||||
Log::error("HTTPRequest",
|
||||
"Can't open '%s' for writing, ignored.",
|
||||
@ -190,23 +216,26 @@ namespace Online
|
||||
}
|
||||
|
||||
// All parameters added have a '&' added
|
||||
if(m_parameters.size()>0)
|
||||
if (m_parameters.size() > 0)
|
||||
{
|
||||
m_parameters.erase(m_parameters.size()-1);
|
||||
}
|
||||
|
||||
if(m_parameters.size()==0)
|
||||
if (m_parameters.size() == 0)
|
||||
{
|
||||
Log::info("HTTPRequest", "Downloading %s", m_url.c_str());
|
||||
else if (Log::getLogLevel()<=Log::LL_INFO)
|
||||
}
|
||||
else if (Log::getLogLevel() <= Log::LL_INFO)
|
||||
{
|
||||
// Avoid printing the password or token, just replace them with *s
|
||||
std::string param = m_parameters;
|
||||
|
||||
// List of strings whose values should not be printed. "" is the
|
||||
// end indicator.
|
||||
static std::string dont_print[] = { "&password=", "&token=", "¤t=",
|
||||
"&new1=", "&new2=", ""};
|
||||
"&new1=", "&new2=", "&password_confirm=", ""};
|
||||
unsigned int j = 0;
|
||||
while (dont_print[j].size()>0)
|
||||
while (dont_print[j].size() > 0)
|
||||
{
|
||||
// Get the string that should be replaced.
|
||||
std::size_t pos = param.find(dont_print[j]);
|
||||
@ -221,11 +250,11 @@ namespace Online
|
||||
} // if string found
|
||||
j++;
|
||||
} // while dont_print[j].size()>0
|
||||
Log::info("HTTPRequest", "Sending %s to %s",
|
||||
param.c_str(), m_url.c_str());
|
||||
}
|
||||
curl_easy_setopt(m_curl_session, CURLOPT_POSTFIELDS,
|
||||
m_parameters.c_str());
|
||||
|
||||
Log::info("HTTPRequest", "Sending %s to %s", param.c_str(), m_url.c_str());
|
||||
} // end log http request
|
||||
|
||||
curl_easy_setopt(m_curl_session, CURLOPT_POSTFIELDS, m_parameters.c_str());
|
||||
std::string uagent( std::string("SuperTuxKart/") + STK_VERSION );
|
||||
#ifdef WIN32
|
||||
uagent += (std::string)" (Windows)";
|
||||
@ -243,17 +272,18 @@ namespace Online
|
||||
m_curl_code = curl_easy_perform(m_curl_session);
|
||||
Request::operation();
|
||||
|
||||
if(fout)
|
||||
if (fout)
|
||||
{
|
||||
fclose(fout);
|
||||
if(m_curl_code==CURLE_OK)
|
||||
if (m_curl_code == CURLE_OK)
|
||||
{
|
||||
if(UserConfigParams::logAddons())
|
||||
Log::info("HTTPRequest", "Download successful.");
|
||||
|
||||
// The behaviour of rename is unspecified if the target
|
||||
// file should already exist - so remove it.
|
||||
bool ok = file_manager->removeFile(m_filename);
|
||||
if(!ok)
|
||||
if (!ok)
|
||||
{
|
||||
Log::error("addons",
|
||||
"Could not removed existing addons.xml file.");
|
||||
@ -261,8 +291,9 @@ namespace Online
|
||||
}
|
||||
int ret = rename((m_filename+".part").c_str(),
|
||||
m_filename.c_str() );
|
||||
|
||||
// In case of an error, set the status to indicate this
|
||||
if(ret!=0)
|
||||
if (ret != 0)
|
||||
{
|
||||
Log::error("addons",
|
||||
"Could not rename downloaded addons.xml file!");
|
||||
@ -279,10 +310,11 @@ namespace Online
|
||||
*/
|
||||
void HTTPRequest::afterOperation()
|
||||
{
|
||||
if(m_curl_code == CURLE_OK)
|
||||
if (m_curl_code == CURLE_OK)
|
||||
setProgress(1.0f);
|
||||
else
|
||||
setProgress(-1.0f);
|
||||
|
||||
Request::afterOperation();
|
||||
curl_easy_cleanup(m_curl_session);
|
||||
} // afterOperation
|
||||
@ -322,7 +354,7 @@ namespace Online
|
||||
|
||||
// Check if we are asked to abort the download. If so, signal this
|
||||
// back to libcurl by returning a non-zero status.
|
||||
if( (request_manager->getAbort() || request->isCancelled()) &&
|
||||
if ((request_manager->getAbort() || request->isCancelled()) &&
|
||||
request->isAbortable() )
|
||||
{
|
||||
// Indicates to abort the current download, which means that this
|
||||
@ -331,23 +363,24 @@ namespace Online
|
||||
}
|
||||
|
||||
float f;
|
||||
if(download_now < download_total)
|
||||
if (download_now < download_total)
|
||||
{
|
||||
f = (float)download_now / (float)download_total;
|
||||
|
||||
// In case of floating point rouding errors make sure that
|
||||
// 1.0 is only reached when downloadFileInternal is finished
|
||||
if (f>=1.0f) f=0.99f;
|
||||
if (f >= 1.0f)
|
||||
f = 0.99f;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Don't set progress to 1.0f; this is done in afterOperation()
|
||||
// after checking curls return code!
|
||||
f= download_total==0 ? 0 : 0.99f;
|
||||
f = (download_total == 0) ? 0 : 0.99f;
|
||||
}
|
||||
request->setProgress(f);
|
||||
|
||||
return 0;
|
||||
} // progressDownload
|
||||
|
||||
|
||||
|
||||
} // namespace Online
|
||||
|
@ -34,6 +34,13 @@
|
||||
|
||||
namespace Online
|
||||
{
|
||||
class API
|
||||
{
|
||||
public:
|
||||
static const std::string USER_PATH;
|
||||
static const std::string SERVER_PATH;
|
||||
};
|
||||
|
||||
/** A http request.
|
||||
*/
|
||||
class HTTPRequest : public Request
|
||||
@ -78,22 +85,20 @@ namespace Online
|
||||
void init();
|
||||
|
||||
public :
|
||||
HTTPRequest(bool manage_memory = false,
|
||||
int priority = 1);
|
||||
HTTPRequest(const std::string &filename,
|
||||
bool manage_memory = false,
|
||||
int priority = 1);
|
||||
HTTPRequest(const char * const filename,
|
||||
bool manage_memory = false,
|
||||
int priority = 1);
|
||||
virtual ~HTTPRequest() {};
|
||||
HTTPRequest(bool manage_memory = false, int priority = 1);
|
||||
HTTPRequest(const std::string &filename, bool manage_memory = false,
|
||||
int priority = 1);
|
||||
HTTPRequest(const char * const filename, bool manage_memory = false,
|
||||
int priority = 1);
|
||||
virtual ~HTTPRequest() {}
|
||||
virtual bool isAllowedToAdd() const OVERRIDE;
|
||||
void setServerURL(const std::string& url);
|
||||
void setApiURL(const std::string& url, const std::string &action);
|
||||
void setAddonsURL(const std::string& path);
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns true if there was an error downloading the file.
|
||||
*/
|
||||
bool hadDownloadError() const { return m_curl_code!=CURLE_OK; }
|
||||
/** Returns true if there was an error downloading the file. */
|
||||
bool hadDownloadError() const { return m_curl_code != CURLE_OK; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the curl error message if an error has occurred.
|
||||
* \pre m_curl_code!=CURLE_OK
|
||||
@ -116,47 +121,50 @@ namespace Online
|
||||
} // getData
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
/** Sets a parameter to 'value' (std::string).
|
||||
*/
|
||||
/** Sets a parameter to 'value' (std::string). */
|
||||
void addParameter(const std::string & name, const std::string &value)
|
||||
{
|
||||
// Call the template, so that the strings are escaped properly
|
||||
addParameter(name, value.c_str());
|
||||
}; // addParameter
|
||||
} // addParameter
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
/** Sets a parameter to 'value' (stringw).
|
||||
*/
|
||||
void addParameter(const std::string & name,
|
||||
/** Sets a parameter to 'value' (stringw). */
|
||||
void addParameter(const std::string &name,
|
||||
const irr::core::stringw &value)
|
||||
{
|
||||
core::stringc s = core::stringc(value.c_str());
|
||||
|
||||
// Call the template to escape strings properly
|
||||
addParameter(name, s.c_str());
|
||||
} // addParameter
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
/** Sets a parameter to 'value' (arbitrary types).
|
||||
*/
|
||||
/** Sets a parameter to 'value' (arbitrary types). */
|
||||
template <typename T>
|
||||
void addParameter(const std::string & name, const T& value)
|
||||
void addParameter(const std::string &name, const T& value)
|
||||
{
|
||||
assert(isPreparing());
|
||||
std::string s = StringUtils::toString(value);
|
||||
char *s1 = curl_easy_escape(m_curl_session, name.c_str(),
|
||||
name.size() );
|
||||
|
||||
char *s1 = curl_easy_escape(m_curl_session, name.c_str(), name.size());
|
||||
char *s2 = curl_easy_escape(m_curl_session, s.c_str(), s.size());
|
||||
m_parameters.append(std::string(s1)+"="+s2+"&");
|
||||
m_parameters.append(std::string(s1) + "=" + s2 + "&");
|
||||
curl_free(s1);
|
||||
curl_free(s2);
|
||||
} // addParameter
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
/** Returns the current progress. */
|
||||
float getProgress() const { return m_progress.getAtomic(); }
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
/** Sets the current progress. */
|
||||
void setProgress(float f) { m_progress.setAtomic(f); }
|
||||
void setProgress(float f) { m_progress.setAtomic(f); }
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
const std::string & getURL() const { assert(isBusy()); return m_url;}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
/** Sets the URL for this request. */
|
||||
void setURL(const std::string & url)
|
||||
@ -166,8 +174,5 @@ namespace Online
|
||||
} // setURL
|
||||
|
||||
}; // class HTTPRequest
|
||||
|
||||
} //namespace Online
|
||||
|
||||
#endif
|
||||
|
||||
#endif // HEADER_HTTP_REQUEST_HPP
|
||||
|
@ -16,7 +16,6 @@
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
|
||||
#include "online/online_player_profile.hpp"
|
||||
|
||||
#include "achievements/achievements_manager.hpp"
|
||||
@ -49,23 +48,25 @@ namespace Online
|
||||
/** Adds the login credential to a http request. It sets the name of
|
||||
* the script to invokce, token, and user id.
|
||||
* \param request The http request.
|
||||
* \param action If not empty, the action to be set.
|
||||
* \param action the action performed
|
||||
*/
|
||||
void OnlinePlayerProfile::setUserDetails(HTTPRequest *request,
|
||||
const std::string &action,
|
||||
const std::string &php_script) const
|
||||
const std::string &url_path) const
|
||||
{
|
||||
if (php_script.size()>0)
|
||||
request->setServerURL(php_script);
|
||||
else
|
||||
request->setServerURL("client-user.php");
|
||||
if (url_path.size())
|
||||
{
|
||||
request->setApiURL(url_path, action);
|
||||
}
|
||||
else // default path
|
||||
{
|
||||
request->setApiURL(API::USER_PATH, action);
|
||||
}
|
||||
|
||||
if (m_profile)
|
||||
request->addParameter("userid", m_profile->getID());
|
||||
if(m_online_state == OS_SIGNED_IN)
|
||||
if (m_online_state == OS_SIGNED_IN)
|
||||
request->addParameter("token", m_token);
|
||||
if (action.size() > 0)
|
||||
request->addParameter("action", action);
|
||||
} // setUserDetails
|
||||
|
||||
// ========================================================================
|
||||
@ -86,16 +87,17 @@ namespace Online
|
||||
m_profile = NULL;
|
||||
|
||||
} // OnlinePlayerProfile
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Request a login using the saved credentials of the user.
|
||||
*/
|
||||
/** Request a login using the saved credentials of the user. */
|
||||
void OnlinePlayerProfile::requestSavedSession()
|
||||
{
|
||||
SignInRequest * request = NULL;
|
||||
SignInRequest *request = NULL;
|
||||
if (m_online_state == OS_SIGNED_OUT && hasSavedSession())
|
||||
{
|
||||
request = new SignInRequest(true);
|
||||
setUserDetails(request, "saved-session");
|
||||
|
||||
// The userid must be taken from the saved data,
|
||||
// setUserDetails takes it from current data.
|
||||
request->addParameter("userid", getSavedUserId());
|
||||
@ -117,18 +119,19 @@ namespace Online
|
||||
// If the player changes the online account, there can be a
|
||||
// logout stil happening.
|
||||
assert(m_online_state == OS_SIGNED_OUT ||
|
||||
m_online_state == OS_SIGNING_OUT );
|
||||
m_online_state == OS_SIGNING_OUT);
|
||||
SignInRequest * request = new SignInRequest(false);
|
||||
|
||||
// We can't use setUserDetail here, since there is no token yet
|
||||
request->setServerURL("client-user.php");
|
||||
request->addParameter("action","connect");
|
||||
request->addParameter("username",username);
|
||||
request->addParameter("password",password);
|
||||
request->setApiURL(API::USER_PATH, "connect");
|
||||
request->addParameter("username", username);
|
||||
request->addParameter("password", password);
|
||||
request->addParameter("save-session",
|
||||
rememberPassword() ? "true"
|
||||
: "false");
|
||||
request->queue();
|
||||
m_online_state = OS_SIGNING_IN;
|
||||
|
||||
return request;
|
||||
} // requestSignIn
|
||||
|
||||
@ -143,13 +146,13 @@ namespace Online
|
||||
|
||||
// If the login is successful, reset any saved session of other
|
||||
// local players using the same online account (which are now invalid)
|
||||
if(isSuccess())
|
||||
if (isSuccess())
|
||||
{
|
||||
PlayerProfile *current = PlayerManager::getCurrentPlayer();
|
||||
for(unsigned int i=0; i<PlayerManager::get()->getNumPlayers(); i++)
|
||||
for (unsigned int i = 0; i < PlayerManager::get()->getNumPlayers(); i++)
|
||||
{
|
||||
PlayerProfile *player = PlayerManager::get()->getPlayer(i);
|
||||
if(player!=current &&
|
||||
if(player != current &&
|
||||
player->hasSavedSession() &&
|
||||
player->getLastOnlineName() == current->getLastOnlineName())
|
||||
{
|
||||
@ -157,7 +160,8 @@ namespace Online
|
||||
}
|
||||
}
|
||||
}
|
||||
if(login)
|
||||
|
||||
if (login)
|
||||
{
|
||||
if(isSuccess())
|
||||
login->loginSuccessful();
|
||||
@ -178,12 +182,14 @@ namespace Online
|
||||
{
|
||||
if (success)
|
||||
{
|
||||
int token_fetched = input->get("token", &m_token);
|
||||
core::stringw username("");
|
||||
int username_fetched = input->get("username", &username);
|
||||
uint32_t userid(0);
|
||||
|
||||
int token_fetched = input->get("token", &m_token);
|
||||
int username_fetched = input->get("username", &username);
|
||||
int userid_fetched = input->get("userid", &userid);
|
||||
setLastOnlineName(username);
|
||||
|
||||
m_profile = new OnlineProfile(userid, username, true);
|
||||
assert(token_fetched && username_fetched && userid_fetched);
|
||||
m_online_state = OS_SIGNED_IN;
|
||||
@ -191,8 +197,10 @@ namespace Online
|
||||
{
|
||||
saveSession(getOnlineId(), getToken());
|
||||
}
|
||||
|
||||
ProfileManager::get()->addPersistent(m_profile);
|
||||
std::string achieved_string("");
|
||||
|
||||
// Even if no achievements were sent, we have to call sync
|
||||
// in order to upload local achievements to the server
|
||||
input->get("achieved", &achieved_string);
|
||||
@ -260,6 +268,7 @@ namespace Online
|
||||
{
|
||||
GUIEngine::Screen *screen = GUIEngine::getCurrentScreen();
|
||||
BaseUserScreen *user_screen = dynamic_cast<BaseUserScreen*>(screen);
|
||||
|
||||
// We can't do much of error handling here, no screen waits for
|
||||
// a logout to finish, so we can only log the message to screen,
|
||||
// and otherwise mark the player logged out internally.
|
||||
@ -269,20 +278,21 @@ namespace Online
|
||||
"There were some connection issues while signing out. "
|
||||
"Report a bug if this caused issues.");
|
||||
Log::warn("OnlinePlayerProfile::signOut", core::stringc(info.c_str()).c_str());
|
||||
if(user_screen)
|
||||
if (user_screen)
|
||||
user_screen->logoutError(info);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(user_screen)
|
||||
if (user_screen)
|
||||
user_screen->logoutSuccessful();
|
||||
}
|
||||
|
||||
ProfileManager::get()->clearPersistent();
|
||||
m_profile = NULL;
|
||||
m_online_state = OS_SIGNED_OUT;
|
||||
|
||||
// Discard token if session should not be saved.
|
||||
if(!rememberPassword())
|
||||
if (!rememberPassword())
|
||||
clearSession();
|
||||
} // signOut
|
||||
|
||||
@ -293,7 +303,8 @@ namespace Online
|
||||
void OnlinePlayerProfile::requestPoll() const
|
||||
{
|
||||
assert(m_online_state == OS_SIGNED_IN);
|
||||
OnlinePlayerProfile::PollRequest * request = new OnlinePlayerProfile::PollRequest();
|
||||
|
||||
OnlinePlayerProfile::PollRequest *request = new OnlinePlayerProfile::PollRequest();
|
||||
setUserDetails(request, "poll");
|
||||
request->queue();
|
||||
} // requestPoll()
|
||||
@ -304,127 +315,137 @@ namespace Online
|
||||
*/
|
||||
void OnlinePlayerProfile::PollRequest::callback()
|
||||
{
|
||||
if(isSuccess())
|
||||
// connection error
|
||||
if (!isSuccess())
|
||||
{
|
||||
if (!PlayerManager::getCurrentPlayer()->isLoggedIn())
|
||||
return;
|
||||
if (PlayerManager::getCurrentPlayer()->getProfile()->hasFetchedFriends())
|
||||
Log::error("Online Player Profile", "Poll request failed");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!PlayerManager::getCurrentPlayer()->isLoggedIn())
|
||||
return;
|
||||
|
||||
if (PlayerManager::getCurrentPlayer()->getProfile()->hasFetchedFriends())
|
||||
{
|
||||
std::string online_friends_string("");
|
||||
if (getXMLData()->get("online", &online_friends_string) == 1)
|
||||
{
|
||||
std::string online_friends_string("");
|
||||
if(getXMLData()->get("online", &online_friends_string) == 1)
|
||||
std::vector<uint32_t> online_friends =
|
||||
StringUtils::splitToUInt(online_friends_string, ' ');
|
||||
|
||||
// flag that indicates if a current online friend went offline
|
||||
bool went_offline = false;
|
||||
|
||||
// iterate over all friends and find out if they come online or not
|
||||
// filling the notification messages
|
||||
std::vector<uint32_t> friends =
|
||||
PlayerManager::getCurrentPlayer()->getProfile()->getFriends();
|
||||
std::vector<core::stringw> to_notify;
|
||||
for (unsigned int i = 0; i < friends.size(); ++i)
|
||||
{
|
||||
std::vector<uint32_t> online_friends =
|
||||
StringUtils::splitToUInt(online_friends_string, ' ');
|
||||
bool went_offline = false;
|
||||
std::vector<uint32_t> friends =
|
||||
PlayerManager::getCurrentPlayer()->getProfile()->getFriends();
|
||||
std::vector<core::stringw> to_notify;
|
||||
for(unsigned int i = 0; i < friends.size(); ++i)
|
||||
{
|
||||
bool now_online = false;
|
||||
std::vector<uint32_t>::iterator iter =
|
||||
std::find(online_friends.begin(),
|
||||
online_friends.end(), friends[i]);
|
||||
if (iter != online_friends.end())
|
||||
{
|
||||
now_online = true;
|
||||
online_friends.erase(iter);
|
||||
}
|
||||
OnlineProfile * profile =
|
||||
ProfileManager::get()->getProfileByID(friends[i]);
|
||||
OnlineProfile::RelationInfo * relation_info =
|
||||
profile->getRelationInfo();
|
||||
if( relation_info->isOnline() )
|
||||
{
|
||||
if (!now_online)
|
||||
{
|
||||
relation_info->setOnline(false);
|
||||
went_offline = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (now_online)
|
||||
{
|
||||
//User came online
|
||||
relation_info->setOnline(true);
|
||||
// Do this because a user might have accepted
|
||||
// a pending friend request.
|
||||
profile->setFriend();
|
||||
to_notify.push_back(profile->getUserName());
|
||||
}
|
||||
}
|
||||
bool now_online = false;
|
||||
std::vector<uint32_t>::iterator found_friend =
|
||||
std::find(online_friends.begin(),
|
||||
online_friends.end(), friends[i]);
|
||||
if (found_friend != online_friends.end())
|
||||
{
|
||||
now_online = true;
|
||||
online_friends.erase(found_friend);
|
||||
}
|
||||
|
||||
}
|
||||
OnlineProfile * profile =
|
||||
ProfileManager::get()->getProfileByID(friends[i]);
|
||||
OnlineProfile::RelationInfo * relation_info =
|
||||
profile->getRelationInfo();
|
||||
|
||||
if(to_notify.size() > 0)
|
||||
{
|
||||
core::stringw message("");
|
||||
if(to_notify.size() == 1)
|
||||
{
|
||||
message = _("%s is now online.", to_notify[0]);
|
||||
}
|
||||
else if(to_notify.size() == 2)
|
||||
{
|
||||
message = _("%s and %s are now online.",
|
||||
to_notify[0], to_notify[1] );
|
||||
}
|
||||
else if(to_notify.size() == 3)
|
||||
{
|
||||
message = _("%s, %s and %s are now online.",
|
||||
to_notify[0], to_notify[1], to_notify[2]);
|
||||
}
|
||||
else if(to_notify.size() > 3)
|
||||
{
|
||||
message = _("%d friends are now online.",
|
||||
to_notify.size());
|
||||
}
|
||||
MessageQueue::add(MessageQueue::MT_FRIEND, message);
|
||||
}
|
||||
else if(went_offline)
|
||||
{
|
||||
OnlineProfileFriends::getInstance()->refreshFriendsList();
|
||||
}
|
||||
if (relation_info->isOnline())
|
||||
{
|
||||
if (!now_online) // the friend went offline
|
||||
{
|
||||
relation_info->setOnline(false);
|
||||
went_offline = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (now_online) // friend came online
|
||||
{
|
||||
relation_info->setOnline(true);
|
||||
|
||||
// Do this because a user might have accepted
|
||||
// a pending friend request.
|
||||
profile->setFriend();
|
||||
to_notify.push_back(profile->getUserName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (to_notify.size() > 0)
|
||||
{
|
||||
core::stringw message("");
|
||||
if(to_notify.size() == 1)
|
||||
{
|
||||
message = _("%s is now online.", to_notify[0]);
|
||||
}
|
||||
else if(to_notify.size() == 2)
|
||||
{
|
||||
message = _("%s and %s are now online.",
|
||||
to_notify[0], to_notify[1] );
|
||||
}
|
||||
else if(to_notify.size() == 3)
|
||||
{
|
||||
message = _("%s, %s and %s are now online.",
|
||||
to_notify[0], to_notify[1], to_notify[2]);
|
||||
}
|
||||
else if(to_notify.size() > 3)
|
||||
{
|
||||
message = _("%d friends are now online.",
|
||||
to_notify.size());
|
||||
}
|
||||
MessageQueue::add(MessageQueue::MT_FRIEND, message);
|
||||
}
|
||||
else if (went_offline)
|
||||
{
|
||||
OnlineProfileFriends::getInstance()->refreshFriendsList();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PlayerManager::getCurrentPlayer()->getProfile()->fetchFriends();
|
||||
}
|
||||
|
||||
int friend_request_count = 0;
|
||||
for (unsigned int i = 0; i < getXMLData()->getNumNodes(); i++)
|
||||
{
|
||||
const XMLNode * node = getXMLData()->getNode(i);
|
||||
if (node->getName() == "new_friend_request")
|
||||
{
|
||||
OnlineProfile::RelationInfo * ri =
|
||||
new OnlineProfile::RelationInfo("New", false, true, true);
|
||||
OnlineProfile * p = new OnlineProfile(node);
|
||||
p->setRelationInfo(ri);
|
||||
ProfileManager::get()->addPersistent(p);
|
||||
friend_request_count++;
|
||||
}
|
||||
}
|
||||
|
||||
if (friend_request_count > 0)
|
||||
{
|
||||
core::stringw message("");
|
||||
if (friend_request_count > 1)
|
||||
{
|
||||
message = _("You have %d new friend requests!",
|
||||
friend_request_count);
|
||||
}
|
||||
else
|
||||
{
|
||||
PlayerManager::getCurrentPlayer()->getProfile()->fetchFriends();
|
||||
message = _("You have a new friend request!");
|
||||
}
|
||||
|
||||
int friend_request_count = 0;
|
||||
for(unsigned int i = 0; i < getXMLData()->getNumNodes(); i++)
|
||||
{
|
||||
const XMLNode * node = getXMLData()->getNode(i);
|
||||
if(node->getName() == "new_friend_request")
|
||||
{
|
||||
OnlineProfile::RelationInfo * ri =
|
||||
new OnlineProfile::RelationInfo("New", false, true, true);
|
||||
OnlineProfile * p = new OnlineProfile(node);
|
||||
p->setRelationInfo(ri);
|
||||
ProfileManager::get()->addPersistent(p);
|
||||
friend_request_count++;
|
||||
}
|
||||
}
|
||||
if(friend_request_count > 0)
|
||||
{
|
||||
core::stringw message("");
|
||||
if(friend_request_count > 1)
|
||||
{
|
||||
message = _("You have %d new friend requests!",
|
||||
friend_request_count);
|
||||
}
|
||||
else
|
||||
{
|
||||
message = _("You have a new friend request!");
|
||||
}
|
||||
MessageQueue::add(MessageQueue::MT_FRIEND, message);
|
||||
OnlineProfileFriends::getInstance()->refreshFriendsList();
|
||||
}
|
||||
MessageQueue::add(MessageQueue::MT_FRIEND, message);
|
||||
OnlineProfileFriends::getInstance()->refreshFriendsList();
|
||||
}
|
||||
// FIXME show connection error??
|
||||
// Perhaps show something after 2 misses.
|
||||
|
||||
} // PollRequest::callback
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
@ -432,11 +453,12 @@ namespace Online
|
||||
*/
|
||||
uint32_t OnlinePlayerProfile::getOnlineId() const
|
||||
{
|
||||
if((m_online_state == OS_SIGNED_IN ))
|
||||
if (m_online_state == OS_SIGNED_IN)
|
||||
{
|
||||
assert(m_profile != NULL);
|
||||
return m_profile->getID();
|
||||
}
|
||||
|
||||
return 0;
|
||||
} // getOnlineId
|
||||
|
||||
|
@ -37,7 +37,6 @@ class PlayerManager;
|
||||
|
||||
namespace Online
|
||||
{
|
||||
|
||||
class OnlineProfile;
|
||||
|
||||
// ============================================================================
|
||||
@ -48,75 +47,73 @@ namespace Online
|
||||
*/
|
||||
class OnlinePlayerProfile : public PlayerProfile
|
||||
{
|
||||
public:
|
||||
// ----------------------------------------------------------------
|
||||
class SignInRequest : public XMLRequest
|
||||
{
|
||||
virtual void callback ();
|
||||
public:
|
||||
// ----------------------------------------------------------------
|
||||
class SignInRequest : public XMLRequest
|
||||
{
|
||||
virtual void callback ();
|
||||
public:
|
||||
SignInRequest(bool manage_memory = false)
|
||||
: XMLRequest(manage_memory, /*priority*/10) {}
|
||||
}; // SignInRequest
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
class PollRequest : public XMLRequest {
|
||||
virtual void callback ();
|
||||
public:
|
||||
PollRequest() : XMLRequest(true) {}
|
||||
}; // PollRequest
|
||||
|
||||
private:
|
||||
std::string m_token;
|
||||
OnlineProfile *m_profile;
|
||||
|
||||
/** The state of the player (logged in, logging in, ...) */
|
||||
PlayerProfile::OnlineState m_online_state;
|
||||
|
||||
virtual void signIn(bool success, const XMLNode * input);
|
||||
virtual void signOut(bool success, const XMLNode * input,
|
||||
const irr::core::stringw &info);
|
||||
virtual uint32_t getOnlineId() const;
|
||||
virtual void setUserDetails(Online::HTTPRequest *request,
|
||||
const std::string &action,
|
||||
const std::string &php_script = "") const;
|
||||
|
||||
virtual void requestPoll() const;
|
||||
// ----------------------------------------------------------------
|
||||
/** Returns if this user is logged in. */
|
||||
virtual bool isLoggedIn() const
|
||||
{
|
||||
return m_online_state == PlayerProfile::OS_SIGNED_IN;
|
||||
} // isLoggedIn
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
/** The online state of the player (i.e. logged out, logging in,
|
||||
* logged in, ...). */
|
||||
PlayerProfile::OnlineState getOnlineState() const
|
||||
{
|
||||
return m_online_state;
|
||||
} // getOnlineState
|
||||
// ----------------------------------------------------------------
|
||||
/** Returns a pointer to the profile associated with the current
|
||||
* user. */
|
||||
OnlineProfile* getProfile() const { return m_profile; }
|
||||
// ----------------------------------------------------------------
|
||||
/** Returns the session token of the signed in user. */
|
||||
const std::string& getToken() const { return m_token; }
|
||||
virtual void requestSavedSession();
|
||||
virtual void requestSignOut();
|
||||
virtual SignInRequest *requestSignIn(const irr::core::stringw &username,
|
||||
const irr::core::stringw &password);
|
||||
SignInRequest(bool manage_memory = false)
|
||||
: XMLRequest(manage_memory, /*priority*/10) {}
|
||||
}; // SignInRequest
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
class PollRequest : public XMLRequest
|
||||
{
|
||||
virtual void callback ();
|
||||
public:
|
||||
OnlinePlayerProfile(const XMLNode *player);
|
||||
OnlinePlayerProfile(const core::stringw &name, bool is_guest = false);
|
||||
virtual ~OnlinePlayerProfile() {};
|
||||
// ----------------------------------------------------------------
|
||||
PollRequest() : XMLRequest(true) {}
|
||||
}; // PollRequest
|
||||
|
||||
}; // class OnlinePlayerProfile
|
||||
private:
|
||||
std::string m_token;
|
||||
OnlineProfile *m_profile;
|
||||
|
||||
/** The state of the player (logged in, logging in, ...) */
|
||||
PlayerProfile::OnlineState m_online_state;
|
||||
|
||||
virtual void signIn(bool success, const XMLNode * input);
|
||||
virtual void signOut(bool success, const XMLNode * input,
|
||||
const irr::core::stringw &info);
|
||||
virtual uint32_t getOnlineId() const;
|
||||
virtual void setUserDetails(Online::HTTPRequest *request,
|
||||
const std::string &action,
|
||||
const std::string &url_path = "") const;
|
||||
|
||||
virtual void requestPoll() const;
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
/** Returns if this user is logged in. */
|
||||
virtual bool isLoggedIn() const
|
||||
{
|
||||
return m_online_state == PlayerProfile::OS_SIGNED_IN;
|
||||
} // isLoggedIn
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
/** The online state of the player (i.e. logged out, logging in,
|
||||
* logged in, ...). */
|
||||
PlayerProfile::OnlineState getOnlineState() const
|
||||
{
|
||||
return m_online_state;
|
||||
} // getOnlineState
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
/** Returns a pointer to the profile associated with the current user. */
|
||||
OnlineProfile* getProfile() const { return m_profile; }
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
/** Returns the session token of the signed in user. */
|
||||
const std::string& getToken() const { return m_token; }
|
||||
virtual void requestSavedSession();
|
||||
virtual void requestSignOut();
|
||||
virtual SignInRequest *requestSignIn(const irr::core::stringw &username,
|
||||
const irr::core::stringw &password);
|
||||
|
||||
public:
|
||||
OnlinePlayerProfile(const XMLNode *player);
|
||||
OnlinePlayerProfile(const core::stringw &name, bool is_guest = false);
|
||||
virtual ~OnlinePlayerProfile() {}
|
||||
// ----------------------------------------------------------------
|
||||
}; // class OnlinePlayerProfile
|
||||
} // namespace Online
|
||||
|
||||
#endif
|
||||
|
||||
/*EOF*/
|
||||
#endif // HEADER_CURRENT_ONLINE_USER_HPP
|
||||
|
@ -16,7 +16,6 @@
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
|
||||
#include "online/online_profile.hpp"
|
||||
|
||||
#include "config/player_manager.hpp"
|
||||
@ -39,10 +38,10 @@ OnlineProfile::RelationInfo::RelationInfo(const irr::core::stringw & date,
|
||||
bool is_online, bool is_pending,
|
||||
bool is_asker)
|
||||
{
|
||||
m_date = date;
|
||||
m_is_online = is_online;
|
||||
m_is_pending = is_pending;
|
||||
m_is_asker = is_asker;
|
||||
m_date = date;
|
||||
m_is_online = is_online;
|
||||
m_is_pending = is_pending;
|
||||
m_is_asker = is_asker;
|
||||
} // RelationInfo::RelationInfo
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -91,12 +90,11 @@ OnlineProfile::OnlineProfile(const XMLNode * xml, ConstructorType type)
|
||||
if (type == C_RELATION_INFO)
|
||||
{
|
||||
irr::core::stringw date("");
|
||||
bool is_pending = false, is_asker = false, is_online = false;
|
||||
|
||||
xml->get("date", &date);
|
||||
std::string is_pending_string("");
|
||||
bool is_pending = false;
|
||||
xml->get("is_pending", &is_pending);
|
||||
bool is_asker = false;
|
||||
bool is_online = false;
|
||||
|
||||
if (is_pending)
|
||||
{
|
||||
xml->get("is_asker", &is_asker);
|
||||
@ -113,7 +111,7 @@ OnlineProfile::OnlineProfile(const XMLNode * xml, ConstructorType type)
|
||||
|
||||
xml->get("id", &m_id );
|
||||
xml->get("user_name", &m_username);
|
||||
m_is_current_user = (m_id == PlayerManager::getCurrentOnlineId());
|
||||
m_is_current_user = (m_id == PlayerManager::getCurrentOnlineId());
|
||||
m_state = S_READY;
|
||||
} // OnlineProfile(XMLNode)
|
||||
|
||||
@ -133,6 +131,7 @@ void OnlineProfile::fetchAchievements()
|
||||
assert(PlayerManager::isCurrentLoggedIn());
|
||||
if (m_has_fetched_achievements || m_is_current_user)
|
||||
return;
|
||||
|
||||
m_state = S_FETCHING;
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
@ -187,6 +186,7 @@ void OnlineProfile::fetchFriends()
|
||||
assert(PlayerManager::isCurrentLoggedIn());
|
||||
if (m_has_fetched_friends)
|
||||
return;
|
||||
|
||||
m_state = S_FETCHING;
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
@ -258,9 +258,11 @@ void OnlineProfile::removeFriend(const uint32_t id)
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
++iter;
|
||||
}
|
||||
} // removeFriend
|
||||
}
|
||||
} // for friend in friends
|
||||
} // removeFriend
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Adds a friend to the friend list.
|
||||
@ -269,9 +271,14 @@ void OnlineProfile::removeFriend(const uint32_t id)
|
||||
void OnlineProfile::addFriend(const uint32_t id)
|
||||
{
|
||||
assert(m_has_fetched_friends);
|
||||
|
||||
// find if friend id is is already in the user list
|
||||
for (unsigned int i = 0; i < m_friends.size(); i++)
|
||||
if (m_friends[i] == id)
|
||||
return;
|
||||
{
|
||||
if (m_friends[i] == id)
|
||||
return;
|
||||
}
|
||||
|
||||
m_friends.push_back(id);
|
||||
} // addFriend
|
||||
|
||||
@ -310,18 +317,25 @@ const OnlineProfile::IDList& OnlineProfile::getAchievements()
|
||||
void OnlineProfile::merge(OnlineProfile *profile)
|
||||
{
|
||||
assert(profile != NULL);
|
||||
if (!this->m_has_fetched_friends && profile->m_has_fetched_friends)
|
||||
this->m_friends = profile->m_friends;
|
||||
if (!this->m_has_fetched_achievements && profile->m_has_fetched_achievements)
|
||||
this->m_achievements = profile->m_achievements;
|
||||
if (this->m_relation_info == NULL && profile->m_relation_info != NULL)
|
||||
|
||||
// profile has fetched friends, use that instead
|
||||
if (!m_has_fetched_friends && profile->m_has_fetched_friends)
|
||||
m_friends = profile->m_friends;
|
||||
|
||||
// profile has fetched achievements, use that instead
|
||||
if (!m_has_fetched_achievements && profile->m_has_fetched_achievements)
|
||||
m_achievements = profile->m_achievements;
|
||||
|
||||
// current relation is not set, use the profile one
|
||||
if (m_relation_info == NULL && profile->m_relation_info != NULL)
|
||||
{
|
||||
this->m_relation_info = profile->m_relation_info;
|
||||
m_relation_info = profile->m_relation_info;
|
||||
|
||||
// We don't want the destructor of the profile instance to destroy
|
||||
// the relation info
|
||||
profile->m_relation_info = NULL;
|
||||
}
|
||||
delete profile;
|
||||
} // merge
|
||||
|
||||
delete profile;
|
||||
} // merge
|
||||
} // namespace Online
|
||||
|
@ -24,9 +24,7 @@
|
||||
#include "utils/types.hpp"
|
||||
#include "utils/ptr_vector.hpp"
|
||||
|
||||
|
||||
#include <irrString.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace Online
|
||||
@ -54,16 +52,21 @@ public:
|
||||
bool m_is_pending;
|
||||
bool m_is_asker;
|
||||
irr::core::stringw m_date;
|
||||
|
||||
public:
|
||||
RelationInfo(const irr::core::stringw & date, bool is_online,
|
||||
bool is_pending, bool is_asker = false);
|
||||
void setOnline(bool online);
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
bool isPending() const { return m_is_pending; }
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
bool isAsker() const { return m_is_asker; }
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
const irr::core::stringw & getDate() const { return m_date; }
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
bool isOnline() const { return m_is_online; }
|
||||
}; // class RelationInfo
|
||||
@ -104,12 +107,11 @@ private:
|
||||
void storeAchievements(const XMLNode * input);
|
||||
|
||||
public:
|
||||
OnlineProfile(const uint32_t & userid,
|
||||
const irr::core::stringw & username,
|
||||
bool is_current_user = false );
|
||||
OnlineProfile(const XMLNode * xml,
|
||||
ConstructorType type = C_DEFAULT);
|
||||
~OnlineProfile();
|
||||
OnlineProfile(const uint32_t & userid,
|
||||
const irr::core::stringw & username,
|
||||
bool is_current_user = false );
|
||||
OnlineProfile(const XMLNode * xml, ConstructorType type = C_DEFAULT);
|
||||
~OnlineProfile();
|
||||
void fetchFriends();
|
||||
const IDList& getFriends();
|
||||
void fetchAchievements();
|
||||
@ -118,49 +120,55 @@ public:
|
||||
void deleteRelationalInfo();
|
||||
const IDList& getAchievements();
|
||||
void merge(OnlineProfile * profile);
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns true if the achievements for this profile have been fetched. */
|
||||
bool hasFetchedAchievements() const { return m_has_fetched_achievements; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns true if the friend list for this profile has been fetched. */
|
||||
bool hasFetchedFriends() const { return m_has_fetched_friends; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** True if the profile is not fetching data atm. */
|
||||
bool isReady() const { return m_state == S_READY; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns true if this item is the current user. */
|
||||
bool isCurrentUser() const { return m_is_current_user; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
bool isFriend() const { return m_is_friend; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
void setFriend() { m_is_friend = true; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
RelationInfo* getRelationInfo() { return m_relation_info; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
void setRelationInfo(RelationInfo * r)
|
||||
{
|
||||
delete m_relation_info; m_relation_info = r;
|
||||
} // setRelationInfo
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Sets the cache bit of this profile. Used by the cache eviction
|
||||
* algorithm. */
|
||||
void setCacheBit(bool cache_bit) { m_cache_bit = cache_bit; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the cache bit for this profile. Used by the cache eviction
|
||||
* algorithm. */
|
||||
bool getCacheBit() const { return m_cache_bit; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the online id of this profile. */
|
||||
uint32_t getID() const { return m_id; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the user name of this profile. */
|
||||
const irr::core::stringw& getUserName() const { return m_username; }
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
}; // class OnlineProfile
|
||||
|
||||
} // namespace Online
|
||||
|
||||
#endif
|
||||
|
||||
/*EOF*/
|
||||
#endif // HEADER_ONLINE_PROFILE_HPP
|
||||
|
@ -16,7 +16,6 @@
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
|
||||
#include "online/profile_manager.hpp"
|
||||
|
||||
#include "online/online_profile.hpp"
|
||||
@ -50,7 +49,8 @@ ProfileManager::~ProfileManager()
|
||||
{
|
||||
clearPersistent();
|
||||
ProfilesMap::iterator it;
|
||||
for (it = m_profiles_cache.begin(); it != m_profiles_cache.end(); ++it) {
|
||||
for (it = m_profiles_cache.begin(); it != m_profiles_cache.end(); ++it)
|
||||
{
|
||||
delete it->second;
|
||||
}
|
||||
} // ~ProfileManager
|
||||
@ -72,8 +72,8 @@ int ProfileManager::guaranteeCacheSize(unsigned int min_num)
|
||||
min_num = 100;
|
||||
m_max_cache_size = min_num;
|
||||
}
|
||||
return m_max_cache_size;
|
||||
|
||||
return m_max_cache_size;
|
||||
} // guaranteeCacheSize
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
@ -88,7 +88,8 @@ OnlineProfile* ProfileManager::getProfileByID(const uint32_t id)
|
||||
return m_profiles_persistent[id];
|
||||
if (isInCache(id))
|
||||
return m_profiles_cache[id];
|
||||
//FIXME not able to get! Now this should actually fetch the info from the
|
||||
|
||||
// FIXME not able to get! Now this should actually fetch the info from the
|
||||
// server, but I haven't come up with a good asynchronous idea yet.
|
||||
return NULL;
|
||||
} // getProfileByID
|
||||
@ -135,12 +136,14 @@ void ProfileManager::addDirectToCache(OnlineProfile* profile)
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
++iter;
|
||||
}
|
||||
}
|
||||
} // for profile in cache
|
||||
}
|
||||
|
||||
m_profiles_cache[profile->getID()] = profile;
|
||||
assert(m_profiles_cache.size() <= m_max_cache_size);
|
||||
|
||||
} // addDirectToCache
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
@ -155,6 +158,7 @@ bool ProfileManager::isInCache(const uint32_t id)
|
||||
updateCacheBits(i->second);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
} // isInCache
|
||||
|
||||
@ -180,6 +184,7 @@ void ProfileManager::updateCacheBits(OnlineProfile * profile)
|
||||
if (!iter->second->getCacheBit())
|
||||
return;
|
||||
}
|
||||
|
||||
// All cache bits are set! Set them all to zero except the one
|
||||
// currently being visited
|
||||
for (iter = m_profiles_cache.begin();
|
||||
@ -189,7 +194,6 @@ void ProfileManager::updateCacheBits(OnlineProfile * profile)
|
||||
}
|
||||
profile->setCacheBit(true);
|
||||
}
|
||||
|
||||
} // updateCacheBits
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
@ -232,11 +236,14 @@ void ProfileManager::deleteFromPersistent(const uint32_t id)
|
||||
m_profiles_persistent.erase(id);
|
||||
}
|
||||
else
|
||||
{
|
||||
Log::warn("ProfileManager",
|
||||
"Tried to remove profile with id %d from persistent while "
|
||||
"not present", id);
|
||||
}
|
||||
} // deleteFromPersistent
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Deletes all persistent profiles.
|
||||
*/
|
||||
@ -265,10 +272,11 @@ void ProfileManager::moveToCache(const uint32_t id)
|
||||
addToCache(profile);
|
||||
}
|
||||
else
|
||||
{
|
||||
Log::warn("ProfileManager",
|
||||
"Tried to move profile with id %d from persistent to "
|
||||
"cache while not present", id);
|
||||
}
|
||||
} // moveToCache
|
||||
|
||||
|
||||
} // namespace Online
|
||||
|
@ -29,7 +29,6 @@
|
||||
|
||||
namespace Online
|
||||
{
|
||||
|
||||
class OnlineProfile;
|
||||
|
||||
/** Class that manages all online profiles. Profiles are used for storing
|
||||
@ -81,6 +80,7 @@ public:
|
||||
assert(!m_profile_manager);
|
||||
m_profile_manager = new ProfileManager();
|
||||
} // create
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
/** Returns the singleton.
|
||||
* \pre create has been called to create the singleton.
|
||||
@ -109,6 +109,7 @@ public:
|
||||
bool isInCache(const uint32_t id);
|
||||
bool inPersistent(const uint32_t id);
|
||||
OnlineProfile* getProfileByID(const uint32_t id);
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
/** Marks a given profile to be the currently visited one. This
|
||||
* is used to mark the profiles that ave its data display (e.g.
|
||||
@ -117,15 +118,12 @@ public:
|
||||
{
|
||||
m_currently_visiting = getProfileByID(id);
|
||||
} // setVisiting
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
/** \return the instance of the profile that's currently being
|
||||
* visited */
|
||||
OnlineProfile* getVisitingProfile() { return m_currently_visiting; }
|
||||
|
||||
}; // class CurrentUser
|
||||
|
||||
} // namespace Online
|
||||
|
||||
#endif
|
||||
|
||||
/*EOF*/
|
||||
#endif // HEADER_ONLINE_PROFILE_MANAGER_HPP
|
||||
|
@ -25,10 +25,8 @@
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
|
||||
namespace Online
|
||||
{
|
||||
|
||||
// ========================================================================
|
||||
/**
|
||||
* Creates a request that can be handled by the RequestManager
|
||||
@ -67,6 +65,7 @@ namespace Online
|
||||
setExecuted();
|
||||
afterOperation();
|
||||
} // execute
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Executes the request now, i.e. in the main thread and without involving
|
||||
* the manager thread.. This calles prepareOperation, operation, and
|
||||
@ -81,5 +80,4 @@ namespace Online
|
||||
setDone();
|
||||
} // executeNow
|
||||
|
||||
|
||||
} // namespace Online
|
||||
|
@ -35,7 +35,6 @@
|
||||
|
||||
namespace Online
|
||||
{
|
||||
|
||||
/** Stores a request for the HTTP Manager. They will be sorted by
|
||||
* prioritiy. Requests have four different states they can be in, and
|
||||
* this state determines which thread can access it. This allows
|
||||
@ -119,9 +118,11 @@ namespace Online
|
||||
/** The actual operation to be executed. Empty as default, which
|
||||
* allows to create a 'quit' request without any additional code. */
|
||||
virtual void operation() {}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
/** Virtual function to be called before an operation. */
|
||||
virtual void prepareOperation() {}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
/** Virtual function to be called after an operation. */
|
||||
virtual void afterOperation() {}
|
||||
@ -132,71 +133,87 @@ namespace Online
|
||||
RT_QUIT = 1
|
||||
};
|
||||
|
||||
Request(bool manage_memory, int priority, int type);
|
||||
Request(bool manage_memory, int priority, int type);
|
||||
virtual ~Request() {}
|
||||
void execute();
|
||||
void executeNow();
|
||||
void queue();
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
/** Executed when a request has finished. */
|
||||
virtual void callback() {}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
/** Returns the type of the request. */
|
||||
int getType() const { return m_type; }
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
/** Returns if the memory for this object should be managed by
|
||||
* by network_http (i.e. freed once the request is handled). */
|
||||
bool manageMemory() const { return m_manage_memory; }
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
/** Sets the memory management flag of this request. This function
|
||||
* must only be called by the main thread, since it is only tested by
|
||||
* the main thread. */
|
||||
void setManageMemory(bool m) { m_manage_memory = m; }
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
/** Returns the priority of this request. */
|
||||
int getPriority() const { return m_priority; }
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
/** Signals that this request should be canceled. */
|
||||
void cancel() { m_cancel.setAtomic(true); }
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
/** Returns if this request is to be canceled. */
|
||||
bool isCancelled() const { return m_cancel.getAtomic(); }
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
/** Returns if this request can be aborted. */
|
||||
bool isAbortable() const { return m_is_abortable.getAtomic(); }
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
/** Sets if this request is abortable or not. */
|
||||
void setAbortable(bool b) { m_is_abortable.setAtomic(b); }
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
/** Sets the request state to busy. */
|
||||
void setBusy()
|
||||
{
|
||||
assert(m_state.getAtomic()==S_PREPARING);
|
||||
assert(m_state.getAtomic() == S_PREPARING);
|
||||
m_state.setAtomic(S_BUSY);
|
||||
} // setBusy
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
/** Sets the request to be completed. */
|
||||
void setExecuted()
|
||||
{
|
||||
assert(m_state.getAtomic()==S_BUSY);
|
||||
assert(m_state.getAtomic() == S_BUSY);
|
||||
m_state.setAtomic(S_EXECUTED);
|
||||
} // setExecuted
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
/** Should only be called by the manager */
|
||||
void setDone()
|
||||
{
|
||||
assert(m_state.getAtomic()==S_EXECUTED);
|
||||
assert(m_state.getAtomic() == S_EXECUTED);
|
||||
m_state.setAtomic(S_DONE);
|
||||
} // setDone
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
/** Returns if this request is done. */
|
||||
bool isDone() const { return m_state.getAtomic() == S_DONE; }
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
/** Returns if this request is being prepared. */
|
||||
bool isPreparing() const { return m_state.getAtomic() == S_PREPARING; }
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
/** Returns if this request is busy. */
|
||||
bool isBusy() const { return m_state.getAtomic() == S_BUSY; }
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
/** Checks if the request has completed or done (i.e. callbacks were
|
||||
* executed).
|
||||
@ -204,8 +221,9 @@ namespace Online
|
||||
bool hasBeenExecuted() const
|
||||
{
|
||||
State s = m_state.getAtomic();
|
||||
return s==S_EXECUTED || s==S_DONE;
|
||||
return s == S_EXECUTED || s == S_DONE;
|
||||
} // hasBeenExecuted
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
/** Virtual method to check if a request has initialized all needed
|
||||
* members to a valid value. */
|
||||
@ -226,9 +244,5 @@ namespace Online
|
||||
}
|
||||
}; // class Compare
|
||||
}; // class Request
|
||||
|
||||
|
||||
} //namespace Online
|
||||
|
||||
#endif
|
||||
|
||||
#endif // HEADER_ONLINE_REQUEST_HPP
|
||||
|
@ -111,6 +111,7 @@ namespace Online
|
||||
pthread_attr_t attr;
|
||||
pthread_attr_init(&attr);
|
||||
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
|
||||
|
||||
// Should be the default, but just in case:
|
||||
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
|
||||
//pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
|
||||
@ -118,7 +119,7 @@ namespace Online
|
||||
m_thread_id.setAtomic(new pthread_t());
|
||||
int error = pthread_create(m_thread_id.getData(), &attr,
|
||||
&RequestManager::mainLoop, this);
|
||||
if(error)
|
||||
if (error)
|
||||
{
|
||||
m_thread_id.lock();
|
||||
delete m_thread_id.getData();
|
||||
@ -128,10 +129,11 @@ namespace Online
|
||||
errno);
|
||||
}
|
||||
pthread_attr_destroy(&attr);
|
||||
|
||||
// In case that login id was not saved (or first start of stk),
|
||||
// current player would not be defined at this stage.
|
||||
PlayerProfile *player = PlayerManager::getCurrentPlayer();
|
||||
if(player && player->wasOnlineLastTime() &&
|
||||
if (player && player->wasOnlineLastTime() &&
|
||||
!UserConfigParams::m_always_show_login_screen)
|
||||
{
|
||||
PlayerManager::resumeSavedSession();
|
||||
@ -178,6 +180,7 @@ namespace Online
|
||||
request->setBusy();
|
||||
m_request_queue.lock();
|
||||
m_request_queue.getData().push(request);
|
||||
|
||||
// Wake up the network http thread
|
||||
pthread_cond_signal(&m_cond_request);
|
||||
m_request_queue.unlock();
|
||||
@ -197,27 +200,30 @@ namespace Online
|
||||
|
||||
me->m_current_request = NULL;
|
||||
me->m_request_queue.lock();
|
||||
while( me->m_request_queue.getData().empty() ||
|
||||
while (me->m_request_queue.getData().empty() ||
|
||||
me->m_request_queue.getData().top()->getType() != Request::RT_QUIT)
|
||||
{
|
||||
bool empty = me->m_request_queue.getData().empty();
|
||||
|
||||
// Wait in cond_wait for a request to arrive. The 'while' is necessary
|
||||
// since "spurious wakeups from the pthread_cond_wait ... may occur"
|
||||
// (pthread_cond_wait man page)!
|
||||
while(empty)
|
||||
while (empty)
|
||||
{
|
||||
pthread_cond_wait(&me->m_cond_request, me->m_request_queue.getMutex());
|
||||
empty = me->m_request_queue.getData().empty();
|
||||
}
|
||||
me->m_current_request = me->m_request_queue.getData().top();
|
||||
me->m_request_queue.getData().pop();
|
||||
if(me->m_current_request->getType()==Request::RT_QUIT)
|
||||
|
||||
if (me->m_current_request->getType() == Request::RT_QUIT)
|
||||
break;
|
||||
|
||||
me->m_request_queue.unlock();
|
||||
me->m_current_request->execute();
|
||||
me->addResult(me->m_current_request);
|
||||
me->m_request_queue.lock();
|
||||
} // while
|
||||
} // while handle all requests
|
||||
|
||||
// Signal that the request manager can now be deleted.
|
||||
// We signal this even before cleaning up memory, since there's no
|
||||
@ -225,16 +231,18 @@ namespace Online
|
||||
me->setCanBeDeleted();
|
||||
|
||||
// At this stage we have the lock for m_request_queue
|
||||
while(!me->m_request_queue.getData().empty())
|
||||
while (!me->m_request_queue.getData().empty())
|
||||
{
|
||||
Online::Request * request = me->m_request_queue.getData().top();
|
||||
Online::Request *request = me->m_request_queue.getData().top();
|
||||
me->m_request_queue.getData().pop();
|
||||
|
||||
// Manage memory can be ignored here, all requests
|
||||
// need to be freed.
|
||||
delete request;
|
||||
}
|
||||
me->m_request_queue.unlock();
|
||||
pthread_exit(NULL);
|
||||
|
||||
return 0;
|
||||
} // mainLoop
|
||||
|
||||
@ -259,13 +267,13 @@ namespace Online
|
||||
{
|
||||
Request * request = NULL;
|
||||
m_result_queue.lock();
|
||||
if(!m_result_queue.getData().empty())
|
||||
if (!m_result_queue.getData().empty())
|
||||
{
|
||||
request = m_result_queue.getData().front();
|
||||
m_result_queue.getData().pop();
|
||||
}
|
||||
m_result_queue.unlock();
|
||||
if(request != NULL)
|
||||
if (request != NULL)
|
||||
{
|
||||
request->callback();
|
||||
if(request->manageMemory())
|
||||
@ -298,7 +306,8 @@ namespace Online
|
||||
float interval = GAME_POLLING_INTERVAL;
|
||||
if (StateManager::get()->getGameState() == GUIEngine::MENU)
|
||||
interval = MENU_POLLING_INTERVAL;
|
||||
if(m_time_since_poll > interval)
|
||||
|
||||
if (m_time_since_poll > interval)
|
||||
{
|
||||
m_time_since_poll = 0;
|
||||
PlayerManager::requestOnlinePoll();
|
||||
@ -306,7 +315,3 @@ namespace Online
|
||||
|
||||
} // update
|
||||
} // namespace Online
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -39,10 +39,8 @@
|
||||
#include <queue>
|
||||
#include <pthread.h>
|
||||
|
||||
|
||||
namespace Online
|
||||
{
|
||||
|
||||
/** A class to execute requests in a separate thread. Typically the
|
||||
* requests involve a http(s) requests to be sent to the stk server, and
|
||||
* receive an answer (e.g. to sign in; or to download an addon). The
|
||||
@ -86,11 +84,14 @@ namespace Online
|
||||
* grant permission
|
||||
* IPERM_ALLOWED: STK is allowed to access server.
|
||||
* IPERM_NOT_ALLOWED: STK must not access external servers. */
|
||||
enum InternetPermission {IPERM_NOT_ASKED =0,
|
||||
IPERM_ALLOWED =1,
|
||||
IPERM_NOT_ALLOWED=2 };
|
||||
enum InternetPermission
|
||||
{
|
||||
IPERM_NOT_ASKED = 0,
|
||||
IPERM_ALLOWED = 1,
|
||||
IPERM_NOT_ALLOWED = 2
|
||||
};
|
||||
protected:
|
||||
|
||||
/** Time passed since the last poll request. */
|
||||
float m_time_since_poll;
|
||||
|
||||
/** The current requested being worked on. */
|
||||
@ -119,7 +120,7 @@ namespace Online
|
||||
void addResult(Online::Request *request);
|
||||
void handleResultQueue();
|
||||
|
||||
static void *mainLoop(void *obj);
|
||||
static void *mainLoop(void *obj);
|
||||
|
||||
RequestManager(); //const std::string &url
|
||||
~RequestManager();
|
||||
@ -136,12 +137,9 @@ namespace Online
|
||||
void startNetworkThread();
|
||||
void stopNetworkThread();
|
||||
|
||||
bool getAbort(){ return m_abort.getAtomic(); };
|
||||
bool getAbort(){ return m_abort.getAtomic(); }
|
||||
void update(float dt);
|
||||
|
||||
}; //class RequestManager
|
||||
} // namespace Online
|
||||
|
||||
#endif // request_manager_HPP
|
||||
|
||||
/*EOF*/
|
||||
|
@ -24,12 +24,14 @@
|
||||
#include "utils/constants.hpp"
|
||||
#include "utils/string_utils.hpp"
|
||||
|
||||
namespace Online{
|
||||
Server::SortOrder Server::m_sort_order=Server::SO_NAME; //FIXME change to some other default
|
||||
namespace Online
|
||||
{
|
||||
Server::SortOrder Server::m_sort_order = Server::SO_NAME;
|
||||
|
||||
Server::Server(const XMLNode & xml)
|
||||
{
|
||||
assert(xml.getName() == "server");
|
||||
|
||||
m_name = "";
|
||||
m_satisfaction_score = 0;
|
||||
m_server_id = 0;
|
||||
@ -45,7 +47,7 @@ namespace Online{
|
||||
xml.get("max_players", &m_max_players);
|
||||
xml.get("current_players", &m_current_players);
|
||||
|
||||
}; // Server(const XML&)
|
||||
} // Server(const XML&)
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/**
|
||||
|
@ -31,7 +31,8 @@
|
||||
|
||||
class XMLNode;
|
||||
|
||||
namespace Online{
|
||||
namespace Online
|
||||
{
|
||||
/**
|
||||
* \ingroup online
|
||||
*/
|
||||
@ -40,54 +41,64 @@ namespace Online{
|
||||
public:
|
||||
|
||||
/** Set the sort order used in the comparison function. */
|
||||
enum SortOrder { SO_SCORE = 1, // Sorted on satisfaction score
|
||||
SO_NAME = 2, // Sorted alphabetically by name
|
||||
SO_PLAYERS = 4
|
||||
enum SortOrder
|
||||
{
|
||||
SO_SCORE = 1, // Sorted on satisfaction score
|
||||
SO_NAME = 2, // Sorted alphabetically by name
|
||||
SO_PLAYERS = 4
|
||||
};
|
||||
|
||||
protected:
|
||||
/** The name to be displayed. */
|
||||
/** The server name to be displayed. */
|
||||
irr::core::stringw m_name;
|
||||
std::string m_lower_case_name; //Used for comparison
|
||||
std::string m_lower_case_name; // Used for comparison
|
||||
|
||||
uint32_t m_server_id;
|
||||
uint32_t m_host_id;
|
||||
|
||||
/** The maximum number of players that the server supports */
|
||||
int m_max_players;
|
||||
|
||||
/** The number of players currently on the server */
|
||||
int m_current_players;
|
||||
|
||||
/** The score/rating given */
|
||||
float m_satisfaction_score;
|
||||
|
||||
/** The sort order to be used in the comparison. */
|
||||
static SortOrder m_sort_order;
|
||||
|
||||
Server() {};
|
||||
Server() {}
|
||||
|
||||
public:
|
||||
|
||||
/** Initialises the object from an XML node. */
|
||||
Server(const XMLNode & xml);
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Sets the sort order used in the comparison function. It is static, so
|
||||
* that each instance can access the sort order. */
|
||||
static void setSortOrder(SortOrder so) { m_sort_order = so; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the name of the server. */
|
||||
const irr::core::stringw& getName() const { return m_name; }
|
||||
const std::string & getLowerCaseName() const { return m_lower_case_name; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
const float getScore() const { return m_satisfaction_score; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the ID of this server. */
|
||||
const uint32_t getServerId() const { return m_server_id; }
|
||||
const uint32_t getHostId() const { return m_host_id; }
|
||||
const int getMaxPlayers() const { return m_max_players; }
|
||||
const int getCurrentPlayers() const { return m_current_players; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
bool filterByWords(const irr::core::stringw words) const;
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Compares two servers according to the sort order currently defined.
|
||||
* \param a The addon to compare this addon to.
|
||||
*/
|
||||
@ -106,10 +117,10 @@ namespace Online{
|
||||
return m_current_players < server.getCurrentPlayers();
|
||||
break;
|
||||
} // switch
|
||||
|
||||
return true;
|
||||
} // operator<
|
||||
|
||||
}; // Server
|
||||
} // namespace Online
|
||||
|
||||
#endif
|
||||
#endif // HEADER_SERVER_HPP
|
||||
|
@ -16,7 +16,6 @@
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
|
||||
#include "online/servers_manager.hpp"
|
||||
|
||||
#include <string>
|
||||
@ -28,14 +27,15 @@
|
||||
|
||||
#define SERVER_REFRESH_INTERVAL 5.0f
|
||||
|
||||
namespace Online{
|
||||
|
||||
namespace Online
|
||||
{
|
||||
static ServersManager* manager_singleton(NULL);
|
||||
|
||||
ServersManager* ServersManager::get()
|
||||
{
|
||||
if (manager_singleton == NULL)
|
||||
manager_singleton = new ServersManager();
|
||||
|
||||
return manager_singleton;
|
||||
}
|
||||
|
||||
@ -46,12 +46,14 @@ namespace Online{
|
||||
} // deallocate
|
||||
|
||||
// ============================================================================
|
||||
ServersManager::ServersManager(){
|
||||
ServersManager::ServersManager()
|
||||
{
|
||||
m_last_load_time.setAtomic(0.0f);
|
||||
m_joined_server.setAtomic(NULL);
|
||||
}
|
||||
|
||||
ServersManager::~ServersManager(){
|
||||
ServersManager::~ServersManager()
|
||||
{
|
||||
cleanUpServers();
|
||||
MutexLocker(m_joined_server);
|
||||
delete m_joined_server.getData();
|
||||
@ -75,27 +77,30 @@ namespace Online{
|
||||
if(StkTime::getRealTime() - m_last_load_time.getAtomic() > SERVER_REFRESH_INTERVAL)
|
||||
{
|
||||
request = new RefreshRequest();
|
||||
request->setServerURL("client-user.php");
|
||||
request->addParameter("action","get_server_list");
|
||||
request->setApiURL(API::SERVER_PATH, "get-all");
|
||||
|
||||
if (request_now)
|
||||
RequestManager::get()->addRequest(request);
|
||||
}
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
void ServersManager::refresh(bool success, const XMLNode * input)
|
||||
{
|
||||
if (success)
|
||||
if (!success)
|
||||
{
|
||||
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)));
|
||||
}
|
||||
m_last_load_time.setAtomic((float)StkTime::getRealTime());
|
||||
Log::error("Server Manager", "Could not refresh server list");
|
||||
return;
|
||||
}
|
||||
//FIXME error message
|
||||
|
||||
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)));
|
||||
}
|
||||
m_last_load_time.setAtomic((float)StkTime::getRealTime());
|
||||
}
|
||||
|
||||
void ServersManager::RefreshRequest::callback()
|
||||
@ -117,7 +122,8 @@ namespace Online{
|
||||
{
|
||||
MutexLocker(m_joined_server);
|
||||
delete m_joined_server.getData();
|
||||
//It's a copy!
|
||||
|
||||
// It's a copy!
|
||||
m_joined_server.getData() = new Server(*getServerByID(id));
|
||||
}
|
||||
|
||||
@ -135,6 +141,7 @@ namespace Online{
|
||||
m_sorted_servers.lock();
|
||||
m_sorted_servers.getData().push_back(server);
|
||||
m_sorted_servers.unlock();
|
||||
|
||||
m_mapped_servers.lock();
|
||||
m_mapped_servers.getData()[server->getServerId()] = server;
|
||||
m_mapped_servers.unlock();
|
||||
@ -168,7 +175,8 @@ namespace Online{
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
void ServersManager::sort(bool sort_desc){
|
||||
void ServersManager::sort(bool sort_desc)
|
||||
{
|
||||
MutexLocker(m_sorted_servers);
|
||||
m_sorted_servers.getData().insertionSort(0, sort_desc);
|
||||
}
|
||||
|
@ -26,11 +26,8 @@
|
||||
#include "online/xml_request.hpp"
|
||||
#include "utils/synchronised.hpp"
|
||||
|
||||
|
||||
|
||||
|
||||
namespace Online {
|
||||
|
||||
namespace Online
|
||||
{
|
||||
/**
|
||||
* \brief
|
||||
* \ingroup online
|
||||
@ -51,8 +48,10 @@ namespace Online {
|
||||
~ServersManager();
|
||||
/** Sorted vector of servers */
|
||||
Synchronised<PtrVector<Server> > m_sorted_servers;
|
||||
|
||||
/** Maps server id's to the same servers*/
|
||||
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;
|
||||
|
||||
@ -74,14 +73,10 @@ namespace Online {
|
||||
const Server * getServerBySort (int index) const;
|
||||
void sort(bool sort_desc);
|
||||
Server * getJoinedServer() const;
|
||||
//Returns the best server to join
|
||||
|
||||
// Returns the best server to join
|
||||
const Server * getQuickPlay() const;
|
||||
|
||||
}; // class ServersManager
|
||||
|
||||
|
||||
} // namespace Online
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
/*EOF*/
|
||||
#endif // HEADER_SERVERS_MANAGER_HPP
|
||||
|
@ -24,15 +24,12 @@
|
||||
#ifdef WIN32
|
||||
# include <winsock2.h>
|
||||
#endif
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
|
||||
namespace Online
|
||||
{
|
||||
|
||||
/** Creates a HTTP(S) request that will automatically parse the answer into
|
||||
* a XML structure.
|
||||
* \param manage_memory whether or not the RequestManager should take care of
|
||||
@ -61,22 +58,26 @@ namespace Online
|
||||
void XMLRequest::afterOperation()
|
||||
{
|
||||
m_xml_data = file_manager->createXMLTreeFromString(getData());
|
||||
if(hadDownloadError())
|
||||
if (hadDownloadError())
|
||||
{
|
||||
Log::error("XMLRequest::afterOperation",
|
||||
"curl_easy_perform() failed: %s",
|
||||
getDownloadErrorMessage());
|
||||
}
|
||||
|
||||
m_success = false;
|
||||
std::string rec_success;
|
||||
if(m_xml_data->get("success", &rec_success))
|
||||
if (m_xml_data->get("success", &rec_success))
|
||||
{
|
||||
m_success = rec_success =="yes";
|
||||
m_success = (rec_success == "yes");
|
||||
m_xml_data->get("info", &m_info);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_info = _("Unable to connect to the server. Check your internet "
|
||||
"connection or try again later.");
|
||||
}
|
||||
HTTPRequest::afterOperation();
|
||||
} // afterOperation
|
||||
|
||||
|
||||
} // namespace Online
|
||||
|
@ -53,7 +53,7 @@ namespace Online
|
||||
virtual void afterOperation() OVERRIDE;
|
||||
|
||||
public :
|
||||
XMLRequest(bool manage_memory = false, int priority = 1);
|
||||
XMLRequest(bool manage_memory = false, int priority = 1);
|
||||
virtual ~XMLRequest();
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
@ -73,7 +73,7 @@ namespace Online
|
||||
* \pre request had to be executed.
|
||||
* \return get the info from the request reply
|
||||
*/
|
||||
const irr::core::stringw & getInfo() const
|
||||
const irr::core::stringw & getInfo() const
|
||||
{
|
||||
assert(hasBeenExecuted());
|
||||
return m_info;
|
||||
@ -90,8 +90,5 @@ namespace Online
|
||||
} // isSuccess
|
||||
|
||||
}; // class XMLRequest
|
||||
|
||||
} //namespace Online
|
||||
|
||||
#endif
|
||||
|
||||
#endif // HEADER_XML_REQUEST_HPP
|
||||
|
@ -387,6 +387,17 @@ void btKart::updateVehicle( btScalar step )
|
||||
if(m_wheelInfo[i].m_raycastInfo.m_isInContact)
|
||||
m_num_wheels_on_ground++;
|
||||
}
|
||||
|
||||
// If the kart is flying, try to keep it parallel to the ground.
|
||||
if(m_num_wheels_on_ground==0)
|
||||
{
|
||||
btVector3 kart_up = getChassisWorldTransform().getBasis().getColumn(1);
|
||||
btVector3 terrain_up(0,1,0);
|
||||
btVector3 axis = kart_up.cross(terrain_up);
|
||||
// Give a nicely balanced feeling for rebalancing the kart
|
||||
m_chassisBody->applyTorqueImpulse(axis * m_kart->getKartProperties()->getSmoothFlyingImpulse());
|
||||
}
|
||||
|
||||
// Work around: make sure that either both wheels on one axis
|
||||
// are on ground, or none of them. This avoids the problem of
|
||||
// the kart suddenly getting additional angular velocity because
|
||||
|
@ -139,7 +139,7 @@ void CreateServerScreen::serverCreationRequest()
|
||||
{
|
||||
|
||||
m_server_creation_request = new ServerCreationRequest();
|
||||
PlayerManager::setUserDetails(m_server_creation_request,"create_server");
|
||||
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();
|
||||
|
@ -38,8 +38,7 @@ using namespace Online;
|
||||
|
||||
/** Creates a modal dialog with given percentage of screen width and height
|
||||
*/
|
||||
ChangePasswordDialog::ChangePasswordDialog()
|
||||
: ModalDialog(0.8f,0.7f)
|
||||
ChangePasswordDialog::ChangePasswordDialog() : ModalDialog(0.8f, 0.7f)
|
||||
{
|
||||
m_self_destroy = false;
|
||||
m_success = false;
|
||||
@ -49,15 +48,15 @@ ChangePasswordDialog::ChangePasswordDialog()
|
||||
m_current_password_widget = getWidget<TextBoxWidget>("current_password");
|
||||
assert(m_current_password_widget != NULL);
|
||||
m_current_password_widget->setFocusForPlayer(PLAYER_ID_GAME_MASTER);
|
||||
m_current_password_widget->setPasswordBox(true,L'*');
|
||||
m_current_password_widget->setPasswordBox(true, L'*');
|
||||
|
||||
m_new_password1_widget = getWidget<TextBoxWidget>("new_password1");
|
||||
assert(m_new_password1_widget != NULL);
|
||||
m_new_password1_widget->setPasswordBox(true,L'*');
|
||||
m_new_password1_widget->setPasswordBox(true, L'*');
|
||||
|
||||
m_new_password2_widget = getWidget<TextBoxWidget>("new_password2");
|
||||
assert(m_new_password2_widget != NULL);
|
||||
m_new_password2_widget->setPasswordBox(true,L'*');
|
||||
m_new_password2_widget->setPasswordBox(true, L'*');
|
||||
|
||||
m_info_widget = getWidget<LabelWidget>("info");
|
||||
assert(m_info_widget != NULL);
|
||||
@ -71,7 +70,6 @@ ChangePasswordDialog::ChangePasswordDialog()
|
||||
} // ChangePasswordDialog
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
ChangePasswordDialog::~ChangePasswordDialog()
|
||||
{
|
||||
} // ~ChangePasswordDialog
|
||||
@ -93,6 +91,7 @@ void ChangePasswordDialog::changePassword(const stringw ¤t_password,
|
||||
virtual void callback()
|
||||
{
|
||||
if (!GUIEngine::ModalDialog::isADialogActive()) return;
|
||||
|
||||
ChangePasswordDialog * dialog =
|
||||
dynamic_cast<ChangePasswordDialog*>(GUIEngine::ModalDialog
|
||||
::getCurrent());
|
||||
@ -111,8 +110,9 @@ void ChangePasswordDialog::changePassword(const stringw ¤t_password,
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
ChangePasswordRequest * request = new ChangePasswordRequest();
|
||||
PlayerManager::setUserDetails(request, "change_password");
|
||||
PlayerManager::setUserDetails(request, "change-password");
|
||||
request->addParameter("current", current_password);
|
||||
|
||||
// The server code expects two passwords (and verifies again that they
|
||||
// are identical), so send the passwod twice.
|
||||
request->addParameter("new1", new_password);
|
||||
@ -126,6 +126,7 @@ void ChangePasswordDialog::submit()
|
||||
const stringw current_password = m_current_password_widget->getText().trim();
|
||||
const stringw new_password1 = m_new_password1_widget->getText().trim();
|
||||
const stringw new_password2 = m_new_password2_widget->getText().trim();
|
||||
|
||||
if (current_password.size() < 8 || current_password.size() > 30)
|
||||
{
|
||||
sfx_manager->quickSound("anvil");
|
||||
@ -149,6 +150,7 @@ void ChangePasswordDialog::submit()
|
||||
{
|
||||
m_options_widget->setDeactivated();
|
||||
m_info_widget->setDefaultColor();
|
||||
|
||||
// We don't need to use password 2 anymore, it was already confirmed
|
||||
// that both passwords are identical.
|
||||
changePassword(current_password, new_password1);
|
||||
@ -159,42 +161,45 @@ void ChangePasswordDialog::submit()
|
||||
GUIEngine::EventPropagation
|
||||
ChangePasswordDialog::processEvent(const std::string& eventSource)
|
||||
{
|
||||
|
||||
if (eventSource == m_options_widget->m_properties[PROP_ID])
|
||||
{
|
||||
const std::string& selection =
|
||||
m_options_widget->getSelectionIDString(PLAYER_ID_GAME_MASTER);
|
||||
|
||||
if (selection == m_cancel_widget->m_properties[PROP_ID])
|
||||
{
|
||||
m_self_destroy = true;
|
||||
|
||||
return GUIEngine::EVENT_BLOCK;
|
||||
}
|
||||
else if(selection == m_submit_widget->m_properties[PROP_ID])
|
||||
{
|
||||
submit();
|
||||
|
||||
return GUIEngine::EVENT_BLOCK;
|
||||
}
|
||||
}
|
||||
|
||||
return GUIEngine::EVENT_LET;
|
||||
} // processEvent
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void ChangePasswordDialog::onEnterPressedInternal()
|
||||
{
|
||||
const int playerID = PLAYER_ID_GAME_MASTER;
|
||||
if (GUIEngine::isFocusedForPlayer(m_options_widget, playerID))
|
||||
return;
|
||||
|
||||
if (m_submit_widget->isActivated())
|
||||
submit();
|
||||
} // onEnterPressedInternal
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
bool ChangePasswordDialog::onEscapePressed()
|
||||
{
|
||||
if (m_cancel_widget->isActivated())
|
||||
m_self_destroy = true;
|
||||
|
||||
return false;
|
||||
} // onEscapePressed
|
||||
|
||||
@ -222,12 +227,15 @@ void ChangePasswordDialog::error(const irr::core::stringw & error)
|
||||
} // error
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void ChangePasswordDialog::onUpdate(float dt)
|
||||
{
|
||||
if(!m_options_widget->isActivated())
|
||||
m_info_widget->setText(StringUtils::loadingDots(_("Validating info")),
|
||||
false );
|
||||
{
|
||||
m_info_widget->setText(
|
||||
StringUtils::loadingDots(_("Validating info")),
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
// It's unsafe to delete from inside the event handler so we do it here
|
||||
if (m_self_destroy)
|
||||
|
@ -125,9 +125,11 @@ void RecoveryDialog::processInput()
|
||||
{
|
||||
m_info_widget->setDefaultColor();
|
||||
m_options_widget->setDeactivated();
|
||||
|
||||
m_recovery_request = new XMLRequest();
|
||||
|
||||
// This function also works when the current user is not logged in
|
||||
PlayerManager::setUserDetails(m_recovery_request, "recovery");
|
||||
PlayerManager::setUserDetails(m_recovery_request, "recover");
|
||||
m_recovery_request->addParameter("username", username);
|
||||
m_recovery_request->addParameter("email", email );
|
||||
m_recovery_request->queue();
|
||||
@ -142,10 +144,13 @@ GUIEngine::EventPropagation
|
||||
{
|
||||
std::string selection;
|
||||
if (eventSource == m_options_widget->m_properties[PROP_ID])
|
||||
selection =
|
||||
m_options_widget->getSelectionIDString(PLAYER_ID_GAME_MASTER);
|
||||
{
|
||||
selection = m_options_widget->getSelectionIDString(PLAYER_ID_GAME_MASTER);
|
||||
}
|
||||
else
|
||||
{
|
||||
selection = eventSource;
|
||||
}
|
||||
|
||||
if (selection == m_cancel_widget->m_properties[PROP_ID])
|
||||
{
|
||||
@ -165,9 +170,9 @@ GUIEngine::EventPropagation
|
||||
*/
|
||||
void RecoveryDialog::onEnterPressedInternal()
|
||||
{
|
||||
|
||||
if (GUIEngine::isFocusedForPlayer(m_options_widget, PLAYER_ID_GAME_MASTER))
|
||||
return;
|
||||
|
||||
if (m_submit_widget->isActivated())
|
||||
processInput();
|
||||
}
|
||||
@ -194,15 +199,19 @@ void RecoveryDialog::onUpdate(float dt)
|
||||
m_info_widget->setText(m_recovery_request->getInfo(), false);
|
||||
m_options_widget->setActivated();
|
||||
}
|
||||
|
||||
delete m_recovery_request;
|
||||
m_recovery_request = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_info_widget->setText(StringUtils::loadingDots(_("Validating info")),
|
||||
false);
|
||||
m_info_widget->setText(
|
||||
StringUtils::loadingDots(_("Validating info")),
|
||||
false
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// It's unsafe to delete from inside the event handler so we do it here
|
||||
if (m_self_destroy)
|
||||
ModalDialog::dismiss();
|
||||
|
@ -78,6 +78,7 @@ EventPropagation RegistrationDialog::processEvent(const std::string& event_sourc
|
||||
assert(r);
|
||||
r->acceptTerms();
|
||||
}
|
||||
|
||||
// If it's not accept, it's cancel - anyway, close dialog
|
||||
ModalDialog::dismiss();
|
||||
return EVENT_BLOCK;
|
||||
|
@ -144,9 +144,10 @@ void UserInfoDialog::sendFriendRequest()
|
||||
*/
|
||||
virtual void callback()
|
||||
{
|
||||
core::stringw info_text("");
|
||||
uint32_t id(0);
|
||||
getXMLData()->get("friendid", &id);
|
||||
core::stringw info_text("");
|
||||
|
||||
if (isSuccess())
|
||||
{
|
||||
PlayerManager::getCurrentOnlineProfile()->addFriend(id);
|
||||
@ -158,7 +159,10 @@ void UserInfoDialog::sendFriendRequest()
|
||||
info_text = _("Friend request send!");
|
||||
}
|
||||
else
|
||||
{
|
||||
info_text = getInfo();
|
||||
}
|
||||
|
||||
UserInfoDialog *dialog = new UserInfoDialog(id, info_text,
|
||||
!isSuccess(), true);
|
||||
GUIEngine::DialogQueue::get()->pushDialog(dialog, true);
|
||||
@ -196,8 +200,9 @@ void UserInfoDialog::acceptFriendRequest()
|
||||
virtual void callback()
|
||||
{
|
||||
uint32_t id(0);
|
||||
getXMLData()->get("friendid", &id);
|
||||
core::stringw info_text("");
|
||||
getXMLData()->get("friendid", &id);
|
||||
|
||||
if (isSuccess())
|
||||
{
|
||||
OnlineProfile * profile =
|
||||
@ -211,7 +216,10 @@ void UserInfoDialog::acceptFriendRequest()
|
||||
info_text = _("Friend request accepted!");
|
||||
}
|
||||
else
|
||||
{
|
||||
info_text = getInfo();
|
||||
}
|
||||
|
||||
GUIEngine::DialogQueue::get()->pushDialog(
|
||||
new UserInfoDialog(id, info_text, !isSuccess(), true), true);
|
||||
|
||||
@ -225,6 +233,7 @@ void UserInfoDialog::acceptFriendRequest()
|
||||
PlayerManager::setUserDetails(request, "accept-friend-request");
|
||||
request->addParameter("friendid", m_online_profile->getID());
|
||||
request->queue();
|
||||
|
||||
m_processing = true;
|
||||
m_options_widget->setDeactivated();
|
||||
} // acceptFriendRequest
|
||||
@ -246,8 +255,9 @@ void UserInfoDialog::declineFriendRequest()
|
||||
virtual void callback()
|
||||
{
|
||||
uint32_t id(0);
|
||||
getXMLData()->get("friendid", &id);
|
||||
core::stringw info_text("");
|
||||
getXMLData()->get("friendid", &id);
|
||||
|
||||
if (isSuccess())
|
||||
{
|
||||
PlayerManager::getCurrentOnlineProfile()->removeFriend(id);
|
||||
@ -258,7 +268,10 @@ void UserInfoDialog::declineFriendRequest()
|
||||
info_text = _("Friend request declined!");
|
||||
}
|
||||
else
|
||||
{
|
||||
info_text = getInfo();
|
||||
}
|
||||
|
||||
GUIEngine::DialogQueue::get()->pushDialog(
|
||||
new UserInfoDialog(id, info_text, !isSuccess(),
|
||||
true), true);
|
||||
@ -286,9 +299,11 @@ void UserInfoDialog::removeExistingFriend()
|
||||
class RemoveFriendRequest : public XMLRequest
|
||||
{
|
||||
unsigned int m_id;
|
||||
|
||||
virtual void callback()
|
||||
{
|
||||
core::stringw info_text("");
|
||||
|
||||
if (isSuccess())
|
||||
{
|
||||
PlayerManager::getCurrentOnlineProfile()->removeFriend(m_id);
|
||||
@ -299,7 +314,9 @@ void UserInfoDialog::removeExistingFriend()
|
||||
info_text = _("Friend removed!");
|
||||
}
|
||||
else
|
||||
{
|
||||
info_text = getInfo();
|
||||
}
|
||||
|
||||
UserInfoDialog *info = new UserInfoDialog(m_id, info_text,
|
||||
!isSuccess(), true);
|
||||
@ -335,8 +352,9 @@ void UserInfoDialog::removePendingFriend()
|
||||
virtual void callback()
|
||||
{
|
||||
uint32_t id(0);
|
||||
getXMLData()->get("friendid", &id);
|
||||
core::stringw info_text("");
|
||||
getXMLData()->get("friendid", &id);
|
||||
|
||||
if (isSuccess())
|
||||
{
|
||||
PlayerManager::getCurrentOnlineProfile()->removeFriend(id);
|
||||
@ -347,8 +365,9 @@ void UserInfoDialog::removePendingFriend()
|
||||
info_text = _("Friend request cancelled!");
|
||||
}
|
||||
else
|
||||
{
|
||||
info_text = getInfo();
|
||||
|
||||
}
|
||||
UserInfoDialog *dia = new UserInfoDialog(id, info_text,
|
||||
!isSuccess(), true);
|
||||
GUIEngine::DialogQueue::get()->pushDialog(dia, true);
|
||||
|
@ -48,14 +48,16 @@ VoteDialog::VoteDialog(const std::string & addon_id)
|
||||
|
||||
m_rating_widget = getWidget<RatingBarWidget>("rating");
|
||||
assert(m_rating_widget != NULL);
|
||||
|
||||
m_rating_widget->setRating(0);
|
||||
m_rating_widget->allowVoting();
|
||||
m_options_widget = getWidget<RibbonWidget>("options");
|
||||
assert(m_options_widget != NULL);
|
||||
|
||||
m_cancel_widget = getWidget<IconButtonWidget>("cancel");
|
||||
assert(m_cancel_widget != NULL);
|
||||
m_options_widget->setFocusForPlayer(PLAYER_ID_GAME_MASTER);
|
||||
|
||||
m_options_widget->setFocusForPlayer(PLAYER_ID_GAME_MASTER);
|
||||
|
||||
m_fetch_vote_request = new XMLRequest();
|
||||
PlayerManager::setUserDetails(m_fetch_vote_request, "get-addon-vote");
|
||||
@ -102,8 +104,9 @@ void VoteDialog::sendVote()
|
||||
if (isSuccess())
|
||||
{
|
||||
std::string addon_id;
|
||||
getXMLData()->get("addon-id", &addon_id);
|
||||
float average;
|
||||
|
||||
getXMLData()->get("addon-id", &addon_id);
|
||||
getXMLData()->get("new-average", &average);
|
||||
addons_manager->getAddon(Addon::createAddonId(addon_id))
|
||||
->setRating(average);
|
||||
@ -112,10 +115,8 @@ void VoteDialog::sendVote()
|
||||
public:
|
||||
SetAddonVoteRequest() : XMLRequest() {}
|
||||
}; // SetAddonVoteRequest
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
|
||||
m_perform_vote_request = new SetAddonVoteRequest();
|
||||
PlayerManager::setUserDetails(m_perform_vote_request, "set-addon-vote");
|
||||
m_perform_vote_request->addParameter("addonid", m_addon_id.substr(6));
|
||||
@ -144,12 +145,15 @@ GUIEngine::EventPropagation VoteDialog::processEvent(const std::string& event)
|
||||
{
|
||||
const std::string& selection =
|
||||
m_options_widget->getSelectionIDString(PLAYER_ID_GAME_MASTER);
|
||||
|
||||
if (selection == m_cancel_widget->m_properties[PROP_ID])
|
||||
{
|
||||
m_self_destroy = true;
|
||||
|
||||
return GUIEngine::EVENT_BLOCK;
|
||||
}
|
||||
}
|
||||
|
||||
return GUIEngine::EVENT_LET;
|
||||
} // processEvent
|
||||
|
||||
@ -163,16 +167,21 @@ void VoteDialog::updateFetchVote()
|
||||
if (!m_fetch_vote_request->isDone())
|
||||
{
|
||||
// request still pending
|
||||
m_info_widget->setText(StringUtils::loadingDots(_("Fetching last vote")),
|
||||
false );
|
||||
m_info_widget->setText(
|
||||
StringUtils::loadingDots(_("Fetching last vote")),
|
||||
false
|
||||
);
|
||||
|
||||
return;
|
||||
} // !isDone
|
||||
|
||||
if (m_fetch_vote_request->isSuccess())
|
||||
{
|
||||
m_info_widget->setDefaultColor();
|
||||
std::string voted("");
|
||||
|
||||
m_info_widget->setDefaultColor();
|
||||
m_fetch_vote_request->getXMLData()->get("voted", &voted);
|
||||
|
||||
if (voted == "yes")
|
||||
{
|
||||
float rating;
|
||||
|
@ -168,36 +168,36 @@ void OnlineScreen::onUpdate(float delta)
|
||||
void OnlineScreen::doQuickPlay()
|
||||
{
|
||||
// Refresh server list.
|
||||
HTTPRequest* request = ServersManager::get()->refreshRequest(false);
|
||||
if (request != NULL) // consider request done
|
||||
HTTPRequest* refresh_request = ServersManager::get()->refreshRequest(false);
|
||||
if (refresh_request != NULL) // consider request done
|
||||
{
|
||||
request->executeNow();
|
||||
delete request;
|
||||
refresh_request->executeNow();
|
||||
delete refresh_request;
|
||||
}
|
||||
else
|
||||
{
|
||||
Log::error("OnlineScreen", "Could not get the server list.");
|
||||
return;
|
||||
}
|
||||
|
||||
// select first one
|
||||
const Server * server = ServersManager::get()->getQuickPlay();
|
||||
const Server *server = ServersManager::get()->getQuickPlay();
|
||||
|
||||
|
||||
XMLRequest *request2 = new RequestConnection::ServerJoinRequest();
|
||||
if (!request2)
|
||||
// do a join request
|
||||
XMLRequest *join_request = new RequestConnection::ServerJoinRequest();
|
||||
if (!join_request)
|
||||
{
|
||||
sfx_manager->quickSound("anvil");
|
||||
return;
|
||||
}
|
||||
|
||||
PlayerManager::setUserDetails(request2, "request-connection");
|
||||
request2->setServerURL("address-management.php");
|
||||
request2->addParameter("server_id", server->getServerId());
|
||||
PlayerManager::setUserDetails(join_request, "request-connection", Online::API::SERVER_PATH);
|
||||
join_request->addParameter("server_id", server->getServerId());
|
||||
|
||||
request2->executeNow();
|
||||
if (request2->isSuccess())
|
||||
join_request->executeNow();
|
||||
if (join_request->isSuccess())
|
||||
{
|
||||
delete request2;
|
||||
delete join_request;
|
||||
StateManager::get()->pushScreen(NetworkingLobby::getInstance());
|
||||
ConnectToServer *cts = new ConnectToServer(server->getServerId(),
|
||||
server->getHostId());
|
||||
|
@ -139,25 +139,30 @@ void OnlineUserSearch::parseResult(const XMLNode * input)
|
||||
{
|
||||
m_users.clear();
|
||||
const XMLNode * users_xml = input->getNode("users");
|
||||
|
||||
// Try to reserve enough cache space for all found entries.
|
||||
unsigned int n = ProfileManager::get()
|
||||
->guaranteeCacheSize(users_xml->getNumNodes());
|
||||
|
||||
if (n >= users_xml->getNumNodes())
|
||||
{
|
||||
n = users_xml->getNumNodes();
|
||||
}
|
||||
else
|
||||
{
|
||||
Log::warn("OnlineSearch",
|
||||
"Too many results found, only %d will be displayed.", n);
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < n; i++)
|
||||
{
|
||||
OnlineProfile * profile = new OnlineProfile(users_xml->getNode(i));
|
||||
|
||||
// The id must be pushed before adding it to the cache, since
|
||||
// the cache might merge the new data with an existing entry
|
||||
m_users.push_back(profile->getID());
|
||||
ProfileManager::get()->addToCache(profile);
|
||||
}
|
||||
} // for i = 0 ... number of display users
|
||||
} // parseResult
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -166,17 +171,19 @@ void OnlineUserSearch::parseResult(const XMLNode * input)
|
||||
void OnlineUserSearch::showList()
|
||||
{
|
||||
m_user_list_widget->clear();
|
||||
for (unsigned int i=0; i < m_users.size(); i++)
|
||||
|
||||
for (unsigned int i = 0; i < m_users.size(); i++)
|
||||
{
|
||||
std::vector<GUIEngine::ListWidget::ListCell> row;
|
||||
OnlineProfile * profile = ProfileManager::get()->getProfileByID(m_users[i]);
|
||||
|
||||
// This could still happen if something pushed results out of the cache.
|
||||
if (!profile)
|
||||
{
|
||||
Log::warn("OnlineSearch", "User %d not in cache anymore, ignored.",
|
||||
m_users[i]);
|
||||
Log::warn("OnlineSearch", "User %d not in cache anymore, ignored.", m_users[i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
row.push_back(GUIEngine::ListWidget::ListCell(profile->getUserName(),-1,3));
|
||||
m_user_list_widget->addItem("user", row);
|
||||
}
|
||||
@ -267,6 +274,7 @@ void OnlineUserSearch::onUpdate(float dt)
|
||||
sfx_manager->quickSound( "anvil" );
|
||||
new MessageDialog(m_search_request->getInfo());
|
||||
}
|
||||
|
||||
delete m_search_request;
|
||||
m_search_request = NULL;
|
||||
m_back_widget->setActivated();
|
||||
|
@ -72,9 +72,9 @@ void RegisterScreen::init()
|
||||
getWidget<TextBoxWidget>("local_username")->setText(username);
|
||||
|
||||
TextBoxWidget *password_widget = getWidget<TextBoxWidget>("password");
|
||||
password_widget->setPasswordBox(true,L'*');
|
||||
password_widget->setPasswordBox(true, L'*');
|
||||
password_widget = getWidget<TextBoxWidget>("password_confirm");
|
||||
password_widget->setPasswordBox(true,L'*');
|
||||
password_widget->setPasswordBox(true, L'*');
|
||||
|
||||
m_info_widget = getWidget<LabelWidget>("info");
|
||||
assert(m_info_widget);
|
||||
@ -129,6 +129,7 @@ void RegisterScreen::makeEntryFieldsVisible(bool online)
|
||||
getWidget<LabelWidget>("label_online")->setVisible(false);
|
||||
online = false;
|
||||
}
|
||||
|
||||
getWidget<TextBoxWidget>("username")->setVisible(online);
|
||||
getWidget<LabelWidget >("label_username")->setVisible(online);
|
||||
getWidget<TextBoxWidget>("password")->setVisible(online);
|
||||
@ -147,7 +148,7 @@ void RegisterScreen::makeEntryFieldsVisible(bool online)
|
||||
*/
|
||||
void RegisterScreen::handleLocalName(const stringw &local_name)
|
||||
{
|
||||
if (local_name.size()==0)
|
||||
if (local_name.size() == 0)
|
||||
return;
|
||||
|
||||
// If a local player with that name does not exist, create one
|
||||
@ -267,9 +268,8 @@ void RegisterScreen::acceptTerms()
|
||||
core::stringw password_confirm= getWidget<TextBoxWidget>("password_confirm")->getText().trim();
|
||||
core::stringw email = getWidget<TextBoxWidget>("email")->getText().trim();
|
||||
|
||||
m_signup_request = new XMLRequest();
|
||||
m_signup_request->setServerURL("client-user.php");
|
||||
m_signup_request->addParameter("action", "register" );
|
||||
m_signup_request = new XMLRequest();
|
||||
m_signup_request->setApiURL(API::USER_PATH, "register");
|
||||
m_signup_request->addParameter("username", username );
|
||||
m_signup_request->addParameter("password", password );
|
||||
m_signup_request->addParameter("password_confirm", password_confirm);
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "guiengine/widgets/list_widget.hpp"
|
||||
#include "guiengine/widgets/text_box_widget.hpp"
|
||||
#include "states_screens/dialogs/message_dialog.hpp"
|
||||
#include "states_screens/dialogs/recovery_dialog.hpp"
|
||||
#include "states_screens/main_menu_screen.hpp"
|
||||
#include "states_screens/options_screen_audio.hpp"
|
||||
#include "states_screens/options_screen_input.hpp"
|
||||
@ -279,6 +280,10 @@ void BaseUserScreen::eventCallback(Widget* widget,
|
||||
StateManager::get()->popMenu();
|
||||
onEscapePressed();
|
||||
}
|
||||
else if (button == "recover")
|
||||
{
|
||||
new RecoveryDialog();
|
||||
}
|
||||
else if (button == "rename")
|
||||
{
|
||||
PlayerProfile *cp = getSelectedPlayer();
|
||||
|
Loading…
Reference in New Issue
Block a user