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

This commit is contained in:
hiker 2014-08-08 11:10:56 +10:00
commit f39e22e442
54 changed files with 792 additions and 735 deletions

View File

@ -2,16 +2,15 @@ uniform mat4 ModelViewMatrix;
uniform vec3 Position; uniform vec3 Position;
uniform vec2 Size; uniform vec2 Size;
#if __VERSION__ >= 130 #if __VERSION__ >= 330
layout(location = 0) in vec2 Corner;
layout(location = 3) in vec2 Texcoord;
#else
in vec2 Corner; in vec2 Corner;
in vec2 Texcoord; in vec2 Texcoord;
out vec2 uv;
#else
attribute vec2 Corner;
attribute vec2 Texcoord;
varying vec2 uv;
#endif #endif
out vec2 uv;
void main(void) void main(void)
{ {

View File

@ -1,17 +1,13 @@
uniform sampler2D tex; uniform sampler2D tex;
#if __VERSION__ >= 130
in vec2 uv; in vec2 uv;
in vec4 color;
out vec4 FragColor; out vec4 FragColor;
#else
varying vec2 uv;
#define FragColor gl_FragColor
#endif
void main(void) void main(void)
{ {
vec4 color = texture(tex, uv); vec4 col = texture(tex, uv);
if (color.a < 0.5) discard; col.xyz *= pow(color.xyz, vec3(2.2));
FragColor = vec4(color.xyz, 1.); if (col.a < 0.5) discard;
FragColor = vec4(col.xyz, 1.);
} }

View File

@ -1,19 +1,16 @@
uniform sampler2D Albedo; uniform sampler2D Albedo;
#if __VERSION__ >= 130
in vec2 uv; in vec2 uv;
in vec4 color;
out vec4 FragColor; out vec4 FragColor;
#else
varying vec2 uv;
#define FragColor gl_FragColor
#endif
vec3 getLightFactor(float specMapValue); vec3 getLightFactor(float specMapValue);
void main(void) void main(void)
{ {
vec4 color = texture(Albedo, uv); vec4 col = texture(Albedo, uv);
if (color.a < 0.5) discard; col.xyz *= pow(color.xyz, vec3(2.2));
if (col.a * color.a < 0.5) discard;
vec3 LightFactor = getLightFactor(1.); vec3 LightFactor = getLightFactor(1.);
FragColor = vec4(color.xyz * LightFactor, 1.); FragColor = vec4(col.xyz * LightFactor, 1.);
} }

View File

@ -138,6 +138,7 @@ void* NewsManager::downloadNews(void *obj)
HTTPRequest *download_req = new HTTPRequest("news.xml"); HTTPRequest *download_req = new HTTPRequest("news.xml");
download_req->setAddonsURL("news.xml"); download_req->setAddonsURL("news.xml");
// Initialise the online portion of the addons manager. // Initialise the online portion of the addons manager.
if(UserConfigParams::logAddons()) if(UserConfigParams::logAddons())
Log::info("addons", "Downloading news."); Log::info("addons", "Downloading news.");
@ -150,10 +151,12 @@ void* NewsManager::downloadNews(void *obj)
// that a redirect went wrong, or a wrong/incorrect // that a redirect went wrong, or a wrong/incorrect
// address somehow made its way into the config file. // address somehow made its way into the config file.
delete download_req; delete download_req;
// We need a new object, since the state of the old // We need a new object, since the state of the old
// download request is now done. // download request is now done.
download_req = new HTTPRequest("news.xml"); download_req = new HTTPRequest("news.xml");
UserConfigParams::m_server_addons.revertToDefaults(); UserConfigParams::m_server_addons.revertToDefaults();
// make sure the new server address is actually used // make sure the new server address is actually used
download_req->setAddonsURL("news.xml"); download_req->setAddonsURL("news.xml");
download_req->executeNow(); download_req->executeNow();

View File

@ -42,8 +42,8 @@ public:
UNLOCK_GP, UNLOCK_GP,
UNLOCK_MODE, UNLOCK_MODE,
UNLOCK_KART, UNLOCK_KART,
UNLOCK_DIFFICULTY} UNLOCK_DIFFICULTY
; };
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
class UnlockableFeature class UnlockableFeature
{ {

View File

@ -156,8 +156,4 @@ public:
} // increaseAchievement } // increaseAchievement
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
}; // PlayerManager }; // PlayerManager
#endif #endif
/*EOF*/

View File

@ -127,7 +127,7 @@ public:
/** Abstract virtual classes, to be implemented by the OnlinePlayer. */ /** Abstract virtual classes, to be implemented by the OnlinePlayer. */
virtual void setUserDetails(Online::HTTPRequest *request, virtual void setUserDetails(Online::HTTPRequest *request,
const std::string &action, 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 uint32_t getOnlineId() const = 0;
virtual PlayerProfile::OnlineState getOnlineState() const = 0; virtual PlayerProfile::OnlineState getOnlineState() const = 0;
virtual Online::OnlineProfile* getProfile() const = 0; virtual Online::OnlineProfile* getProfile() const = 0;

View File

@ -383,6 +383,8 @@ void IrrDriver::renderScene(scene::ICameraSceneNode * const camnode, unsigned po
if (!UserConfigParams::m_dynamic_lights && !forceRTT) if (!UserConfigParams::m_dynamic_lights && !forceRTT)
{ {
glDisable(GL_FRAMEBUFFER_SRGB); glDisable(GL_FRAMEBUFFER_SRGB);
glDisable(GL_DEPTH_TEST);
glDepthMask(GL_FALSE);
return; return;
} }

View File

@ -212,9 +212,9 @@ void IrrDriver::renderSolidFirstPass()
std::vector<TexUnit> object_pass1_texunits = TexUnits(TexUnit(MeshShader::ObjectPass1Shader::getInstance()->TU_tex, true) ); std::vector<TexUnit> object_pass1_texunits = TexUnits(TexUnit(MeshShader::ObjectPass1Shader::getInstance()->TU_tex, true) );
renderMeshes1stPass<MeshShader::ObjectPass1Shader, video::EVT_STANDARD, 2, 1>(object_pass1_texunits, ListMatDefault::Arguments); renderMeshes1stPass<MeshShader::ObjectPass1Shader, video::EVT_STANDARD, 2, 1>(object_pass1_texunits, ListMatDefault::Arguments);
renderMeshes1stPass<MeshShader::ObjectPass1Shader, video::EVT_STANDARD, 2, 1>(object_pass1_texunits, ListMatSphereMap::Arguments); renderMeshes1stPass<MeshShader::ObjectPass1Shader, video::EVT_STANDARD, 2, 1>(object_pass1_texunits, ListMatSphereMap::Arguments);
renderMeshes1stPass<MeshShader::ObjectPass1Shader, video::EVT_STANDARD, 2, 1>(object_pass1_texunits, ListMatUnlit::Arguments);
renderMeshes1stPass<MeshShader::ObjectPass1Shader, video::EVT_2TCOORDS, 2, 1>(object_pass1_texunits, ListMatDetails::Arguments); renderMeshes1stPass<MeshShader::ObjectPass1Shader, video::EVT_2TCOORDS, 2, 1>(object_pass1_texunits, ListMatDetails::Arguments);
renderMeshes1stPass<MeshShader::ObjectPass1Shader, video::EVT_2TCOORDS, 2, 1>(object_pass1_texunits, ListMatSplatting::Arguments); renderMeshes1stPass<MeshShader::ObjectPass1Shader, video::EVT_2TCOORDS, 2, 1>(object_pass1_texunits, ListMatSplatting::Arguments);
renderMeshes1stPass<MeshShader::ObjectRefPass1Shader, video::EVT_STANDARD, 3, 2, 1>(object_pass1_texunits, ListMatUnlit::Arguments);
renderMeshes1stPass<MeshShader::ObjectRefPass1Shader, video::EVT_STANDARD, 3, 2, 1>(TexUnits(TexUnit(MeshShader::ObjectRefPass1Shader::getInstance()->TU_tex, true)), ListMatAlphaRef::Arguments); renderMeshes1stPass<MeshShader::ObjectRefPass1Shader, video::EVT_STANDARD, 3, 2, 1>(TexUnits(TexUnit(MeshShader::ObjectRefPass1Shader::getInstance()->TU_tex, true)), ListMatAlphaRef::Arguments);
renderMeshes1stPass<MeshShader::GrassPass1Shader, video::EVT_STANDARD, 3, 2, 1>(TexUnits(TexUnit(MeshShader::GrassPass1Shader::getInstance()->TU_tex, true)), ListMatGrass::Arguments); renderMeshes1stPass<MeshShader::GrassPass1Shader, video::EVT_STANDARD, 3, 2, 1>(TexUnits(TexUnit(MeshShader::GrassPass1Shader::getInstance()->TU_tex, true)), ListMatGrass::Arguments);
renderMeshes1stPass<MeshShader::NormalMapShader, video::EVT_TANGENTS, 2, 1>(TexUnits( renderMeshes1stPass<MeshShader::NormalMapShader, video::EVT_TANGENTS, 2, 1>(TexUnits(
@ -416,8 +416,8 @@ void IrrDriver::renderTransparent()
GLenum itype = mesh.IndexType; GLenum itype = mesh.IndexType;
size_t count = mesh.IndexCount; size_t count = mesh.IndexCount;
glUseProgram(MeshShader::DisplaceMaskShaderInstance->Program); glUseProgram(MeshShader::DisplaceMaskShader::getInstance()->Program);
MeshShader::DisplaceMaskShaderInstance->setUniforms(AbsoluteTransformation); MeshShader::DisplaceMaskShader::getInstance()->setUniforms(AbsoluteTransformation);
glDrawElementsBaseVertex(ptype, count, itype, (GLvoid *)mesh.vaoOffset, mesh.vaoBaseVertex); glDrawElementsBaseVertex(ptype, count, itype, (GLvoid *)mesh.vaoOffset, mesh.vaoBaseVertex);
} }
@ -435,12 +435,12 @@ void IrrDriver::renderTransparent()
GLenum itype = mesh.IndexType; GLenum itype = mesh.IndexType;
size_t count = mesh.IndexCount; size_t count = mesh.IndexCount;
// Render the effect // Render the effect
setTexture(MeshShader::DisplaceShaderInstance->TU_displacement_tex, getTextureGLuint(displaceTex), GL_LINEAR, GL_LINEAR, true); setTexture(MeshShader::DisplaceShader::getInstance()->TU_displacement_tex, getTextureGLuint(displaceTex), GL_LINEAR, GL_LINEAR, true);
setTexture(MeshShader::DisplaceShaderInstance->TU_mask_tex, irr_driver->getRenderTargetTexture(RTT_TMP1), GL_LINEAR, GL_LINEAR, true); setTexture(MeshShader::DisplaceShader::getInstance()->TU_mask_tex, irr_driver->getRenderTargetTexture(RTT_TMP1), GL_LINEAR, GL_LINEAR, true);
setTexture(MeshShader::DisplaceShaderInstance->TU_color_tex, irr_driver->getRenderTargetTexture(RTT_COLOR), GL_LINEAR, GL_LINEAR, true); setTexture(MeshShader::DisplaceShader::getInstance()->TU_color_tex, irr_driver->getRenderTargetTexture(RTT_COLOR), GL_LINEAR, GL_LINEAR, true);
setTexture(MeshShader::DisplaceShaderInstance->TU_tex, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR, true); setTexture(MeshShader::DisplaceShader::getInstance()->TU_tex, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR, true);
glUseProgram(MeshShader::DisplaceShaderInstance->Program); glUseProgram(MeshShader::DisplaceShader::getInstance()->Program);
MeshShader::DisplaceShaderInstance->setUniforms(AbsoluteTransformation, MeshShader::DisplaceShader::getInstance()->setUniforms(AbsoluteTransformation,
core::vector2df(cb->getDirX(), cb->getDirY()), core::vector2df(cb->getDirX(), cb->getDirY()),
core::vector2df(cb->getDir2X(), cb->getDir2Y())); core::vector2df(cb->getDir2X(), cb->getDir2Y()));
@ -490,9 +490,9 @@ struct shadow_custom_unroll_args<N, List...>
}; };
template<typename T, enum E_VERTEX_TYPE VertexType, int...List, typename... Args> template<typename T, enum E_VERTEX_TYPE VertexType, int...List, typename... Args>
void renderShadow(const T *Shader, const std::vector<GLuint> TextureUnits, const std::vector<STK::Tuple<GLMesh *, core::matrix4, Args...> >&t) void renderShadow(const std::vector<GLuint> TextureUnits, const std::vector<STK::Tuple<GLMesh *, core::matrix4, Args...> >&t)
{ {
glUseProgram(Shader->Program); glUseProgram(T::getInstance()->Program);
glBindVertexArray(getVAO(VertexType)); glBindVertexArray(getVAO(VertexType));
for (unsigned i = 0; i < t.size(); i++) for (unsigned i = 0; i < t.size(); i++)
{ {
@ -503,7 +503,7 @@ void renderShadow(const T *Shader, const std::vector<GLuint> TextureUnits, const
setTexture(TextureUnits[j], getTextureGLuint(mesh->textures[j]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true); setTexture(TextureUnits[j], getTextureGLuint(mesh->textures[j]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
} }
shadow_custom_unroll_args<List...>::template exec<T>(Shader, t[i]); shadow_custom_unroll_args<List...>::template exec<T>(T::getInstance(), t[i]);
} }
} }
@ -551,14 +551,14 @@ void IrrDriver::renderShadows()
m_scene_manager->drawAll(scene::ESNRP_SOLID); m_scene_manager->drawAll(scene::ESNRP_SOLID);
std::vector<GLuint> noTexUnits; std::vector<GLuint> noTexUnits;
renderShadow<MeshShader::ShadowShader, EVT_STANDARD, 1>(MeshShader::ShadowShaderInstance, noTexUnits, ListMatDefault::Arguments); renderShadow<MeshShader::ShadowShader, EVT_STANDARD, 1>(noTexUnits, ListMatDefault::Arguments);
renderShadow<MeshShader::ShadowShader, EVT_STANDARD, 1>(MeshShader::ShadowShaderInstance, noTexUnits, ListMatSphereMap::Arguments); renderShadow<MeshShader::ShadowShader, EVT_STANDARD, 1>(noTexUnits, ListMatSphereMap::Arguments);
renderShadow<MeshShader::ShadowShader, EVT_STANDARD, 1>(MeshShader::ShadowShaderInstance, noTexUnits, ListMatUnlit::Arguments); renderShadow<MeshShader::ShadowShader, EVT_2TCOORDS, 1>(noTexUnits, ListMatDetails::Arguments);
renderShadow<MeshShader::ShadowShader, EVT_2TCOORDS, 1>(MeshShader::ShadowShaderInstance, noTexUnits, ListMatDetails::Arguments); renderShadow<MeshShader::ShadowShader, EVT_2TCOORDS, 1>(noTexUnits, ListMatSplatting::Arguments);
renderShadow<MeshShader::ShadowShader, EVT_2TCOORDS, 1>(MeshShader::ShadowShaderInstance, noTexUnits, ListMatSplatting::Arguments); renderShadow<MeshShader::ShadowShader, EVT_TANGENTS, 1>(noTexUnits, ListMatNormalMap::Arguments);
renderShadow<MeshShader::ShadowShader, EVT_TANGENTS, 1>(MeshShader::ShadowShaderInstance, noTexUnits, ListMatNormalMap::Arguments); renderShadow<MeshShader::RefShadowShader, EVT_STANDARD, 1>(std::vector<GLuint>{ MeshShader::RefShadowShader::getInstance()->TU_tex }, ListMatAlphaRef::Arguments);
renderShadow<MeshShader::RefShadowShader, EVT_STANDARD, 1>(MeshShader::RefShadowShaderInstance, std::vector<GLuint>{ MeshShader::RefShadowShaderInstance->TU_tex }, ListMatAlphaRef::Arguments); renderShadow<MeshShader::RefShadowShader, EVT_STANDARD, 1>(std::vector<GLuint>{ MeshShader::RefShadowShader::getInstance()->TU_tex }, ListMatUnlit::Arguments);
renderShadow<MeshShader::GrassShadowShader, EVT_STANDARD, 3, 1>(MeshShader::GrassShadowShaderInstance, std::vector<GLuint>{ MeshShader::GrassShadowShaderInstance->TU_tex }, ListMatGrass::Arguments); renderShadow<MeshShader::GrassShadowShader, EVT_STANDARD, 3, 1>(std::vector<GLuint>{ MeshShader::GrassShadowShader::getInstance()->TU_tex }, ListMatGrass::Arguments);
glDisable(GL_POLYGON_OFFSET_FILL); glDisable(GL_POLYGON_OFFSET_FILL);

View File

@ -504,6 +504,14 @@ void IrrDriver::generateDiffuseCoefficients()
testSH(sh_rgba, sh_w, sh_h, blueSHCoeff, greenSHCoeff, redSHCoeff); testSH(sh_rgba, sh_w, sh_h, blueSHCoeff, greenSHCoeff, redSHCoeff);
// Diffuse env map is x 0.25, compensate
for (unsigned i = 0; i < 9; i++)
{
blueSHCoeff[i] *= 4;
greenSHCoeff[i] *= 4;
redSHCoeff[i] *= 4;
}
for (unsigned i = 0; i < 6; i++) for (unsigned i = 0; i < 6; i++)
delete[] sh_rgba[i]; delete[] sh_rgba[i];
} }

View File

@ -404,19 +404,9 @@ void Shaders::loadShaders()
FullScreenShader::MLAAColorEdgeDetectionSHader::init(); FullScreenShader::MLAAColorEdgeDetectionSHader::init();
FullScreenShader::MLAABlendWeightSHader::init(); FullScreenShader::MLAABlendWeightSHader::init();
FullScreenShader::MLAAGatherSHader::init(); FullScreenShader::MLAAGatherSHader::init();
MeshShader::ColorizeShader::init();
MeshShader::BubbleShader::init(); MeshShader::BubbleShader::init();
MeshShader::BillboardShader::init();
LightShader::PointLightShader::init(); LightShader::PointLightShader::init();
MeshShader::DisplaceShaderInstance = new MeshShader::DisplaceShader();
MeshShader::DisplaceMaskShaderInstance = new MeshShader::DisplaceMaskShader();
MeshShader::ShadowShaderInstance = new MeshShader::ShadowShader();
MeshShader::RSMShader::init(); MeshShader::RSMShader::init();
MeshShader::InstancedShadowShaderInstance = new MeshShader::InstancedShadowShader();
MeshShader::RefShadowShaderInstance = new MeshShader::RefShadowShader();
MeshShader::InstancedRefShadowShaderInstance = new MeshShader::InstancedRefShadowShader();
MeshShader::GrassShadowShaderInstance = new MeshShader::GrassShadowShader();
MeshShader::InstancedGrassShadowShaderInstance = new MeshShader::InstancedGrassShadowShader();
MeshShader::SkyboxShader::init(); MeshShader::SkyboxShader::init();
MeshShader::ViewFrustrumShader::init(); MeshShader::ViewFrustrumShader::init();
ParticleShader::FlipParticleRender::init(); ParticleShader::FlipParticleRender::init();
@ -713,7 +703,7 @@ namespace MeshShader
GL_VERTEX_SHADER, file_manager->getAsset("shaders/object_pass.vert").c_str(), GL_VERTEX_SHADER, file_manager->getAsset("shaders/object_pass.vert").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/getLightFactor.frag").c_str(), GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/getLightFactor.frag").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/object_pass2.frag").c_str()); GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/object_pass2.frag").c_str());
AssignUniforms("ModelMatrix", "TextureMatrix", "ambient"); AssignUniforms("ModelMatrix", "TextureMatrix");
GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData"); GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData");
glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0); glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0);
@ -735,7 +725,7 @@ namespace MeshShader
GL_VERTEX_SHADER, file_manager->getAsset("shaders/instanced_object_pass.vert").c_str(), GL_VERTEX_SHADER, file_manager->getAsset("shaders/instanced_object_pass.vert").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/getLightFactor.frag").c_str(), GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/getLightFactor.frag").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/object_pass2.frag").c_str()); GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/object_pass2.frag").c_str());
AssignUniforms("ambient"); AssignUniforms();
TU_Albedo = 3; TU_Albedo = 3;
AssignTextureUnit(Program, AssignTextureUnit(Program,
@ -757,7 +747,7 @@ namespace MeshShader
GL_VERTEX_SHADER, file_manager->getAsset("shaders/instanced_object_pass.vert").c_str(), GL_VERTEX_SHADER, file_manager->getAsset("shaders/instanced_object_pass.vert").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/getLightFactor.frag").c_str(), GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/getLightFactor.frag").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/objectref_pass2.frag").c_str()); GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/objectref_pass2.frag").c_str());
AssignUniforms("ambient"); AssignUniforms();
TU_Albedo = 3; TU_Albedo = 3;
AssignTextureUnit(Program, AssignTextureUnit(Program,
@ -777,7 +767,7 @@ namespace MeshShader
GL_VERTEX_SHADER, file_manager->getAsset("shaders/object_pass.vert").c_str(), GL_VERTEX_SHADER, file_manager->getAsset("shaders/object_pass.vert").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/getLightFactor.frag").c_str(), GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/getLightFactor.frag").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/detailledobject_pass2.frag").c_str()); GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/detailledobject_pass2.frag").c_str());
AssignUniforms("ModelMatrix", "ambient"); AssignUniforms("ModelMatrix");
GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData"); GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData");
glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0); glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0);
TU_Albedo = 3; TU_Albedo = 3;
@ -813,7 +803,7 @@ namespace MeshShader
GL_VERTEX_SHADER, file_manager->getAsset("shaders/object_pass.vert").c_str(), GL_VERTEX_SHADER, file_manager->getAsset("shaders/object_pass.vert").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/getLightFactor.frag").c_str(), GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/getLightFactor.frag").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/objectref_pass2.frag").c_str()); GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/objectref_pass2.frag").c_str());
AssignUniforms("ModelMatrix", "TextureMatrix", "ambient"); AssignUniforms("ModelMatrix", "TextureMatrix");
GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData"); GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData");
glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0); glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0);
@ -834,7 +824,7 @@ namespace MeshShader
GL_VERTEX_SHADER, file_manager->getAsset("shaders/grass_pass.vert").c_str(), GL_VERTEX_SHADER, file_manager->getAsset("shaders/grass_pass.vert").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/getLightFactor.frag").c_str(), GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/getLightFactor.frag").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/grass_pass2.frag").c_str()); GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/grass_pass2.frag").c_str());
AssignUniforms("ModelMatrix", "windDir", "ambient"); AssignUniforms("ModelMatrix", "windDir");
TU_Albedo = 3; TU_Albedo = 3;
AssignTextureUnit(Program, AssignTextureUnit(Program,
@ -852,7 +842,7 @@ namespace MeshShader
GL_VERTEX_SHADER, file_manager->getAsset("shaders/instanced_grass.vert").c_str(), GL_VERTEX_SHADER, file_manager->getAsset("shaders/instanced_grass.vert").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/getLightFactor.frag").c_str(), GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/getLightFactor.frag").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/grass_pass2.frag").c_str()); GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/grass_pass2.frag").c_str());
AssignUniforms("windDir", "SunDir", "ambient"); AssignUniforms("windDir", "SunDir");
TU_Albedo = 3; TU_Albedo = 3;
TU_dtex = 4; TU_dtex = 4;
@ -875,7 +865,7 @@ namespace MeshShader
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/getLightFactor.frag").c_str(), GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/getLightFactor.frag").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/getPosFromUVDepth.frag").c_str(), GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/getPosFromUVDepth.frag").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/objectpass_spheremap.frag").c_str()); GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/objectpass_spheremap.frag").c_str());
AssignUniforms("ModelMatrix", "InverseModelMatrix", "ambient"); AssignUniforms("ModelMatrix", "InverseModelMatrix");
GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData"); GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData");
glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0); glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0);
@ -895,7 +885,7 @@ namespace MeshShader
Program = LoadProgram( Program = LoadProgram(
GL_VERTEX_SHADER, file_manager->getAsset("shaders/object_pass.vert").c_str(), GL_VERTEX_SHADER, file_manager->getAsset("shaders/object_pass.vert").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/splatting.frag").c_str()); GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/splatting.frag").c_str());
AssignUniforms("ModelMatrix", "ambient"); AssignUniforms("ModelMatrix");
TU_tex_layout = 3; TU_tex_layout = 3;
TU_tex_detail0 = 4; TU_tex_detail0 = 4;
TU_tex_detail1 = 5; TU_tex_detail1 = 5;
@ -968,66 +958,32 @@ namespace MeshShader
AssignTextureUnit(Program, TexUnit(TU_tex, "tex")); AssignTextureUnit(Program, TexUnit(TU_tex, "tex"));
} }
GLuint BillboardShader::Program; BillboardShader::BillboardShader()
GLuint BillboardShader::attrib_corner;
GLuint BillboardShader::attrib_texcoord;
GLuint BillboardShader::uniform_MV;
GLuint BillboardShader::uniform_P;
GLuint BillboardShader::uniform_tex;
GLuint BillboardShader::uniform_Position;
GLuint BillboardShader::uniform_Size;
void BillboardShader::init()
{ {
Program = LoadProgram( Program = LoadProgram(
GL_VERTEX_SHADER, file_manager->getAsset("shaders/billboard.vert").c_str(), GL_VERTEX_SHADER, file_manager->getAsset("shaders/billboard.vert").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/billboard.frag").c_str()); GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/billboard.frag").c_str());
attrib_corner = glGetAttribLocation(Program, "Corner");
attrib_texcoord = glGetAttribLocation(Program, "Texcoord"); GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData");
uniform_MV = glGetUniformLocation(Program, "ModelViewMatrix"); glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0);
uniform_P = glGetUniformLocation(Program, "ProjectionMatrix"); AssignUniforms("ModelViewMatrix", "ProjectionMatrix", "Position", "Size");
uniform_Position = glGetUniformLocation(Program, "Position");
uniform_Size = glGetUniformLocation(Program, "Size"); TU_tex = 0;
uniform_tex = glGetUniformLocation(Program, "tex");
AssignTextureUnit(Program, TexUnit(TU_tex, "tex"));
} }
void BillboardShader::setUniforms(const core::matrix4 &ModelViewMatrix, ColorizeShader::ColorizeShader()
const core::matrix4 &ProjectionMatrix,
const core::vector3df &Position,
const core::dimension2d<float> &size,
unsigned TU_tex)
{
glUniformMatrix4fv(uniform_MV, 1, GL_FALSE, ModelViewMatrix.pointer());
glUniformMatrix4fv(uniform_P, 1, GL_FALSE, ProjectionMatrix.pointer());
glUniform3f(uniform_Position, Position.X, Position.Y, Position.Z);
glUniform2f(uniform_Size, size.Width, size.Height);
glUniform1i(uniform_tex, TU_tex);
}
GLuint ColorizeShader::Program;
GLuint ColorizeShader::uniform_MM;
GLuint ColorizeShader::uniform_col;
void ColorizeShader::init()
{ {
Program = LoadProgram( Program = LoadProgram(
GL_VERTEX_SHADER, file_manager->getAsset("shaders/object_pass.vert").c_str(), GL_VERTEX_SHADER, file_manager->getAsset("shaders/object_pass.vert").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/colorize.frag").c_str()); GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/colorize.frag").c_str());
uniform_MM = glGetUniformLocation(Program, "ModelMatrix"); AssignUniforms("ModelMatrix", "col");
uniform_col = glGetUniformLocation(Program, "col");
GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData"); GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData");
glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0); glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0);
} }
void ColorizeShader::setUniforms(const core::matrix4 &ModelMatrix, float r, float g, float b)
{
if (irr_driver->needUBOWorkaround())
bypassUBO(Program);
glUniformMatrix4fv(uniform_MM, 1, GL_FALSE, ModelMatrix.pointer());
glUniform3f(uniform_col, r, g, b);
}
ShadowShader::ShadowShader() ShadowShader::ShadowShader()
{ {
// Geometry shader needed // Geometry shader needed
@ -1051,8 +1007,6 @@ namespace MeshShader
glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0); glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0);
} }
ShadowShader *ShadowShaderInstance;
GLuint RSMShader::Program; GLuint RSMShader::Program;
GLuint RSMShader::uniform_MM; GLuint RSMShader::uniform_MM;
GLuint RSMShader::uniform_RSMMatrix; GLuint RSMShader::uniform_RSMMatrix;
@ -1100,8 +1054,6 @@ namespace MeshShader
glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0); glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0);
} }
InstancedShadowShader *InstancedShadowShaderInstance;
RefShadowShader::RefShadowShader() RefShadowShader::RefShadowShader()
{ {
// Geometry shader needed // Geometry shader needed
@ -1128,8 +1080,6 @@ namespace MeshShader
AssignTextureUnit(Program, { TexUnit(TU_tex, "tex") }); AssignTextureUnit(Program, { TexUnit(TU_tex, "tex") });
} }
RefShadowShader *RefShadowShaderInstance;
InstancedRefShadowShader::InstancedRefShadowShader() InstancedRefShadowShader::InstancedRefShadowShader()
{ {
// Geometry shader needed // Geometry shader needed
@ -1156,8 +1106,6 @@ namespace MeshShader
glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0); glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0);
} }
InstancedRefShadowShader *InstancedRefShadowShaderInstance;
GrassShadowShader::GrassShadowShader() GrassShadowShader::GrassShadowShader()
{ {
// Geometry shader needed // Geometry shader needed
@ -1184,8 +1132,6 @@ namespace MeshShader
AssignTextureUnit(Program, { TexUnit(TU_tex, "tex") }); AssignTextureUnit(Program, { TexUnit(TU_tex, "tex") });
} }
GrassShadowShader *GrassShadowShaderInstance;
InstancedGrassShadowShader::InstancedGrassShadowShader() InstancedGrassShadowShader::InstancedGrassShadowShader()
{ {
// Geometry shader needed // Geometry shader needed
@ -1214,8 +1160,6 @@ namespace MeshShader
glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0); glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0);
} }
InstancedGrassShadowShader *InstancedGrassShadowShaderInstance;
DisplaceMaskShader::DisplaceMaskShader() DisplaceMaskShader::DisplaceMaskShader()
{ {
Program = LoadProgram( Program = LoadProgram(
@ -1227,8 +1171,6 @@ namespace MeshShader
glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0); glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0);
} }
DisplaceMaskShader *DisplaceMaskShaderInstance;
DisplaceShader::DisplaceShader() DisplaceShader::DisplaceShader()
{ {
@ -1250,8 +1192,6 @@ namespace MeshShader
glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0); glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0);
} }
DisplaceShader *DisplaceShaderInstance;
GLuint SkyboxShader::Program; GLuint SkyboxShader::Program;
GLuint SkyboxShader::attrib_position; GLuint SkyboxShader::attrib_position;
GLuint SkyboxShader::uniform_MM; GLuint SkyboxShader::uniform_MM;

View File

@ -94,6 +94,13 @@ struct UniformHelper
setUniformsHelper<N + 1>(uniforms, arg...); setUniformsHelper<N + 1>(uniforms, arg...);
} }
template<unsigned N = 0, typename... Args>
static void setUniformsHelper(const std::vector<GLuint> &uniforms, const core::dimension2df &v, Args... arg)
{
glUniform2fWraper(uniforms[N], v.Width, v.Height);
setUniformsHelper<N + 1>(uniforms, arg...);
}
template<unsigned N = 0, typename... Args> template<unsigned N = 0, typename... Args>
static void setUniformsHelper(const std::vector<GLuint> &uniforms, float f, Args... arg) static void setUniformsHelper(const std::vector<GLuint> &uniforms, float f, Args... arg)
{ {
@ -106,51 +113,28 @@ struct UniformHelper
void bypassUBO(GLuint Program); void bypassUBO(GLuint Program);
GLuint getUniformLocation(GLuint program, const char* name); GLuint getUniformLocation(GLuint program, const char* name);
template<typename... Args>
class ShaderHelper
{
protected:
std::vector<GLuint> uniforms;
void AssignUniforms(const char* name)
{
uniforms.push_back(getUniformLocation(Program, name));
}
template<typename... T>
void AssignUniforms(const char* name, T... rest)
{
uniforms.push_back(getUniformLocation(Program, name));
AssignUniforms(rest...);
}
public:
GLuint Program;
void setUniforms(const Args & ... args) const
{
if (needsUBO())
bypassUBO(Program);
UniformHelper::setUniformsHelper(uniforms, args...);
}
};
template<typename T, typename... Args> template<typename T, typename... Args>
class ShaderHelperSingleton : public Singleton<T> class ShaderHelperSingleton : public Singleton<T>
{ {
protected: protected:
std::vector<GLuint> uniforms; std::vector<GLuint> uniforms;
void AssignUniforms(const char* name) void AssignUniforms_impl()
{ {
uniforms.push_back(getUniformLocation(Program, name));
} }
template<typename... U> template<typename... U>
void AssignUniforms(const char* name, U... rest) void AssignUniforms_impl(const char* name, U... rest)
{ {
uniforms.push_back(getUniformLocation(Program, name)); uniforms.push_back(getUniformLocation(Program, name));
AssignUniforms(rest...); AssignUniforms_impl(rest...);
}
template<typename... U>
void AssignUniforms(U... rest)
{
static_assert(sizeof...(rest) == sizeof...(Args), "Count of Uniform's name mismatch");
AssignUniforms_impl(rest...);
} }
public: public:
@ -326,36 +310,27 @@ public:
TransparentFogShader(); TransparentFogShader();
}; };
class BillboardShader class BillboardShader : public ShaderHelperSingleton<BillboardShader, core::matrix4, core::matrix4, core::vector3df, core::dimension2df>
{ {
public: public:
static GLuint Program; GLuint TU_tex;
static GLuint attrib_corner, attrib_texcoord;
static GLuint uniform_MV, uniform_P, uniform_tex, uniform_Position, uniform_Size;
static void init(); BillboardShader();
static void setUniforms(const core::matrix4 &ModelViewMatrix, const core::matrix4 &ProjectionMatrix, const core::vector3df &Position, const core::dimension2d<float> &size, unsigned TU_tex);
}; };
class ColorizeShader class ColorizeShader : public ShaderHelperSingleton<ColorizeShader, core::matrix4, video::SColorf>
{ {
public: public:
static GLuint Program; ColorizeShader();
static GLuint uniform_MM, uniform_col;
static void init();
static void setUniforms(const core::matrix4 &ModelMatrix, float r, float g, float b);
}; };
class ShadowShader : public ShaderHelper<core::matrix4> class ShadowShader : public ShaderHelperSingleton<ShadowShader, core::matrix4>
{ {
public: public:
ShadowShader(); ShadowShader();
}; };
extern ShadowShader *ShadowShaderInstance;
class RSMShader class RSMShader
{ {
public: public:
@ -367,61 +342,47 @@ public:
static void setUniforms(const core::matrix4 &RSMMatrix, const core::matrix4 &ModelMatrix); static void setUniforms(const core::matrix4 &RSMMatrix, const core::matrix4 &ModelMatrix);
}; };
class InstancedShadowShader : public ShaderHelper<> class InstancedShadowShader : public ShaderHelperSingleton<InstancedShadowShader>
{ {
public: public:
InstancedShadowShader(); InstancedShadowShader();
}; };
extern InstancedShadowShader *InstancedShadowShaderInstance; class RefShadowShader : public ShaderHelperSingleton<RefShadowShader, core::matrix4>
class RefShadowShader : public ShaderHelper<core::matrix4>
{ {
public: public:
GLuint TU_tex; GLuint TU_tex;
RefShadowShader(); RefShadowShader();
}; };
extern RefShadowShader *RefShadowShaderInstance; class InstancedRefShadowShader : public ShaderHelperSingleton<InstancedRefShadowShader>
class InstancedRefShadowShader : public ShaderHelper<>
{ {
public: public:
GLuint TU_tex; GLuint TU_tex;
InstancedRefShadowShader(); InstancedRefShadowShader();
}; };
extern InstancedRefShadowShader *InstancedRefShadowShaderInstance; class GrassShadowShader : public ShaderHelperSingleton<GrassShadowShader, core::matrix4, core::vector3df>
class GrassShadowShader : public ShaderHelper<core::matrix4, core::vector3df>
{ {
public: public:
GLuint TU_tex; GLuint TU_tex;
GrassShadowShader(); GrassShadowShader();
}; };
extern GrassShadowShader *GrassShadowShaderInstance; class InstancedGrassShadowShader : public ShaderHelperSingleton<InstancedGrassShadowShader, core::vector3df>
class InstancedGrassShadowShader : public ShaderHelper<core::vector3df>
{ {
public: public:
GLuint TU_tex; GLuint TU_tex;
InstancedGrassShadowShader(); InstancedGrassShadowShader();
}; };
extern InstancedGrassShadowShader *InstancedGrassShadowShaderInstance; class DisplaceMaskShader : public ShaderHelperSingleton<DisplaceMaskShader, core::matrix4>
class DisplaceMaskShader : public ShaderHelper<core::matrix4>
{ {
public: public:
DisplaceMaskShader(); DisplaceMaskShader();
}; };
extern DisplaceMaskShader *DisplaceMaskShaderInstance; class DisplaceShader : public ShaderHelperSingleton<DisplaceShader, core::matrix4, core::vector2df, core::vector2df>
class DisplaceShader : public ShaderHelper<core::matrix4, core::vector2df, core::vector2df>
{ {
public: public:
GLuint TU_displacement_tex, TU_mask_tex, TU_color_tex, TU_tex; GLuint TU_displacement_tex, TU_mask_tex, TU_color_tex, TU_tex;
@ -429,8 +390,6 @@ public:
DisplaceShader(); DisplaceShader();
}; };
extern DisplaceShader *DisplaceShaderInstance;
class SkyboxShader class SkyboxShader
{ {
public: public:

View File

@ -29,7 +29,6 @@ STKTextBillboard::STKTextBillboard(core::stringw text, gui::ScalableFont* font,
createGLMeshes(); createGLMeshes();
Mesh->drop(); Mesh->drop();
//setAutomaticCulling(0); //setAutomaticCulling(0);
setReloadEachFrame(true); // FIXME: should not need that!!
updateAbsolutePosition(); updateAbsolutePosition();
} }
@ -93,7 +92,7 @@ scene::IMesh* STKTextBillboard::getTextMesh(core::stringw text, gui::ScalableFon
{ {
buffer = new scene::SMeshBuffer(); buffer = new scene::SMeshBuffer();
buffer->getMaterial().setTexture(0, m_chars[i].m_texture); buffer->getMaterial().setTexture(0, m_chars[i].m_texture);
buffer->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; buffer->getMaterial().MaterialType = irr_driver->getShader(ES_OBJECT_UNLIT);
buffers[m_chars[i].m_texture] = buffer; buffers[m_chars[i].m_texture] = buffer;
} }
else else
@ -148,7 +147,7 @@ scene::IMesh* STKTextBillboard::getTextMesh(core::stringw text, gui::ScalableFon
map_itr->second->drop(); map_itr->second->drop();
} }
getMaterial(0).MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; getMaterial(0).MaterialType = irr_driver->getShader(ES_OBJECT_UNLIT);
return Mesh; return Mesh;
} }
@ -157,13 +156,14 @@ void STKTextBillboard::OnRegisterSceneNode()
{ {
if (IsVisible) if (IsVisible)
{ {
SceneManager->registerNodeForRendering(this, scene::ESNRP_TRANSPARENT); SceneManager->registerNodeForRendering(this, scene::ESNRP_SOLID);
scene::ICameraSceneNode* curr_cam = irr_driver->getSceneManager()->getActiveCamera(); scene::ICameraSceneNode* curr_cam = irr_driver->getSceneManager()->getActiveCamera();
core::vector3df cam_pos = curr_cam->getPosition(); core::vector3df cam_pos = curr_cam->getPosition();
core::vector3df text_pos = this->getAbsolutePosition(); core::vector3df text_pos = this->getAbsolutePosition();
float angle = atan2(text_pos.X - cam_pos.X, text_pos.Z - cam_pos.Z); float angle = atan2(text_pos.X - cam_pos.X, text_pos.Z - cam_pos.Z);
this->setRotation(core::vector3df(0.0f, angle * 180.0f / M_PI, 0.0f)); this->setRotation(core::vector3df(0.0f, angle * 180.0f / M_PI, 0.0f));
updateAbsolutePosition();
} }
ISceneNode::OnRegisterSceneNode(); ISceneNode::OnRegisterSceneNode();

View File

@ -151,7 +151,7 @@ void STKAnimatedMesh::render()
pushVector(ListMatDetails::Arguments, mesh, AbsoluteTransformation, invmodel, mesh->TextureMatrix); pushVector(ListMatDetails::Arguments, mesh, AbsoluteTransformation, invmodel, mesh->TextureMatrix);
for_in(mesh, MeshSolidMaterial[MAT_UNLIT]) for_in(mesh, MeshSolidMaterial[MAT_UNLIT])
pushVector(ListMatUnlit::Arguments, mesh, AbsoluteTransformation, core::matrix4::EM4CONST_IDENTITY); pushVector(ListMatUnlit::Arguments, mesh, AbsoluteTransformation, core::matrix4::EM4CONST_IDENTITY, mesh->TextureMatrix);
return; return;
} }

View File

@ -13,10 +13,10 @@ static void createbillboardvao()
glGenVertexArrays(1, &billboardvao); glGenVertexArrays(1, &billboardvao);
glBindVertexArray(billboardvao); glBindVertexArray(billboardvao);
glBindBuffer(GL_ARRAY_BUFFER, SharedObject::billboardvbo); glBindBuffer(GL_ARRAY_BUFFER, SharedObject::billboardvbo);
glEnableVertexAttribArray(MeshShader::BillboardShader::attrib_corner); glEnableVertexAttribArray(0);
glEnableVertexAttribArray(MeshShader::BillboardShader::attrib_texcoord); glEnableVertexAttribArray(3);
glVertexAttribPointer(MeshShader::BillboardShader::attrib_corner, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0); glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0);
glVertexAttribPointer(MeshShader::BillboardShader::attrib_texcoord, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (GLvoid*) (2 * sizeof(float))); glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (GLvoid*) (2 * sizeof(float)));
glBindVertexArray(0); glBindVertexArray(0);
} }
@ -50,8 +50,8 @@ void STKBillboard::render()
compressTexture(tex, true, true); compressTexture(tex, true, true);
GLuint texid = getTextureGLuint(tex); GLuint texid = getTextureGLuint(tex);
setTexture(0, texid, GL_LINEAR, GL_LINEAR); setTexture(0, texid, GL_LINEAR, GL_LINEAR);
glUseProgram(MeshShader::BillboardShader::Program); glUseProgram(MeshShader::BillboardShader::getInstance()->Program);
MeshShader::BillboardShader::setUniforms(irr_driver->getViewMatrix(), irr_driver->getProjMatrix(), pos, Size, 0); MeshShader::BillboardShader::getInstance()->setUniforms(irr_driver->getViewMatrix(), irr_driver->getProjMatrix(), pos, Size);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glBindVertexArray(0); glBindVertexArray(0);
return; return;

View File

@ -156,7 +156,7 @@ static void drawShadowDefault(GLMesh &mesh, size_t instance_count)
GLenum itype = mesh.IndexType; GLenum itype = mesh.IndexType;
size_t count = mesh.IndexCount; size_t count = mesh.IndexCount;
MeshShader::InstancedShadowShaderInstance->setUniforms(); MeshShader::InstancedShadowShader::getInstance()->setUniforms();
glBindVertexArray(mesh.vao_shadow_pass); glBindVertexArray(mesh.vao_shadow_pass);
glDrawElementsInstanced(ptype, count, itype, 0, 4 * instance_count); glDrawElementsInstanced(ptype, count, itype, 0, 4 * instance_count);
@ -185,8 +185,8 @@ static void drawShadowAlphaRefTexture(GLMesh &mesh, size_t instance_count)
size_t count = mesh.IndexCount; size_t count = mesh.IndexCount;
compressTexture(mesh.textures[0], true); compressTexture(mesh.textures[0], true);
setTexture(MeshShader::InstancedRefShadowShaderInstance->TU_tex, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true); setTexture(MeshShader::InstancedRefShadowShader::getInstance()->TU_tex, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
MeshShader::InstancedRefShadowShaderInstance->setUniforms(); MeshShader::InstancedRefShadowShader::getInstance()->setUniforms();
glBindVertexArray(mesh.vao_shadow_pass); glBindVertexArray(mesh.vao_shadow_pass);
glDrawElementsInstanced(ptype, count, itype, 0, 4 * instance_count); glDrawElementsInstanced(ptype, count, itype, 0, 4 * instance_count);
@ -200,8 +200,8 @@ static void drawShadowGrass(GLMesh &mesh, const core::vector3df &windDir, size_t
size_t count = mesh.IndexCount; size_t count = mesh.IndexCount;
compressTexture(mesh.textures[0], true); compressTexture(mesh.textures[0], true);
setTexture(MeshShader::InstancedGrassShadowShaderInstance->TU_tex, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true); setTexture(MeshShader::InstancedGrassShadowShader::getInstance()->TU_tex, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
MeshShader::InstancedGrassShadowShaderInstance->setUniforms(windDir); MeshShader::InstancedGrassShadowShader::getInstance()->setUniforms(windDir);
glBindVertexArray(mesh.vao_shadow_pass); glBindVertexArray(mesh.vao_shadow_pass);
glDrawElementsInstanced(ptype, count, itype, 0, 4 * instance_count); glDrawElementsInstanced(ptype, count, itype, 0, 4 * instance_count);
@ -356,17 +356,17 @@ void STKInstancedSceneNode::render()
if (irr_driver->getPhase() == SHADOW_PASS) if (irr_driver->getPhase() == SHADOW_PASS)
{ {
if (!MeshSolidMaterial[MAT_DEFAULT].empty()) if (!MeshSolidMaterial[MAT_DEFAULT].empty())
glUseProgram(MeshShader::InstancedShadowShaderInstance->Program); glUseProgram(MeshShader::InstancedShadowShader::getInstance()->Program);
for (unsigned i = 0; i < MeshSolidMaterial[MAT_DEFAULT].size(); i++) for (unsigned i = 0; i < MeshSolidMaterial[MAT_DEFAULT].size(); i++)
drawShadowDefault(*MeshSolidMaterial[MAT_DEFAULT][i], instance_pos.size() / 9); drawShadowDefault(*MeshSolidMaterial[MAT_DEFAULT][i], instance_pos.size() / 9);
if (!MeshSolidMaterial[MAT_ALPHA_REF].empty()) if (!MeshSolidMaterial[MAT_ALPHA_REF].empty())
glUseProgram(MeshShader::InstancedRefShadowShaderInstance->Program); glUseProgram(MeshShader::InstancedRefShadowShader::getInstance()->Program);
for (unsigned i = 0; i < MeshSolidMaterial[MAT_ALPHA_REF].size(); i++) for (unsigned i = 0; i < MeshSolidMaterial[MAT_ALPHA_REF].size(); i++)
drawShadowAlphaRefTexture(*MeshSolidMaterial[MAT_ALPHA_REF][i], instance_pos.size() / 9); drawShadowAlphaRefTexture(*MeshSolidMaterial[MAT_ALPHA_REF][i], instance_pos.size() / 9);
if (!MeshSolidMaterial[MAT_GRASS].empty()) if (!MeshSolidMaterial[MAT_GRASS].empty())
glUseProgram(MeshShader::InstancedGrassShadowShaderInstance->Program); glUseProgram(MeshShader::InstancedGrassShadowShader::getInstance()->Program);
for (unsigned i = 0; i < MeshSolidMaterial[MAT_GRASS].size(); i++) for (unsigned i = 0; i < MeshSolidMaterial[MAT_GRASS].size(); i++)
drawShadowGrass(*MeshSolidMaterial[MAT_GRASS][i], windDir, instance_pos.size() / 9); drawShadowGrass(*MeshSolidMaterial[MAT_GRASS][i], windDir, instance_pos.size() / 9);
return; return;

View File

@ -298,7 +298,7 @@ std::vector<STK::Tuple<GLMesh *, core::matrix4, core::matrix4, core::matrix4> >
std::vector<STK::Tuple<GLMesh *, core::matrix4, core::matrix4, core::matrix4> > ListMatSphereMap::Arguments; std::vector<STK::Tuple<GLMesh *, core::matrix4, core::matrix4, core::matrix4> > ListMatSphereMap::Arguments;
std::vector<STK::Tuple<GLMesh *, core::matrix4, core::matrix4, core::matrix4> > ListMatDetails::Arguments; std::vector<STK::Tuple<GLMesh *, core::matrix4, core::matrix4, core::matrix4> > ListMatDetails::Arguments;
std::vector<STK::Tuple<GLMesh *, core::matrix4, core::matrix4, core::vector3df> > ListMatGrass::Arguments; std::vector<STK::Tuple<GLMesh *, core::matrix4, core::matrix4, core::vector3df> > ListMatGrass::Arguments;
std::vector<STK::Tuple<GLMesh *, core::matrix4, core::matrix4> > ListMatUnlit::Arguments; std::vector<STK::Tuple<GLMesh *, core::matrix4, core::matrix4, core::matrix4> > ListMatUnlit::Arguments;
std::vector<STK::Tuple<GLMesh *, core::matrix4, core::matrix4> > ListMatSplatting::Arguments; std::vector<STK::Tuple<GLMesh *, core::matrix4, core::matrix4> > ListMatSplatting::Arguments;
std::vector<STK::Tuple<GLMesh *, core::matrix4, core::matrix4, core::matrix4> > ListMatNormalMap::Arguments; std::vector<STK::Tuple<GLMesh *, core::matrix4, core::matrix4, core::matrix4> > ListMatNormalMap::Arguments;

View File

@ -98,7 +98,7 @@ public:
class ListMatUnlit class ListMatUnlit
{ {
public: public:
static std::vector<STK::Tuple<GLMesh *, core::matrix4, core::matrix4> > Arguments; static std::vector<STK::Tuple<GLMesh *, core::matrix4, core::matrix4, core::matrix4> > Arguments;
}; };
class ListMatDetails class ListMatDetails

View File

@ -142,7 +142,7 @@ void STKMeshSceneNode::drawGlow(const GLMesh &mesh)
GLenum itype = mesh.IndexType; GLenum itype = mesh.IndexType;
size_t count = mesh.IndexCount; size_t count = mesh.IndexCount;
MeshShader::ColorizeShader::setUniforms(AbsoluteTransformation, cb->getRed(), cb->getGreen(), cb->getBlue()); MeshShader::ColorizeShader::getInstance()->setUniforms(AbsoluteTransformation, video::SColorf(cb->getRed(), cb->getGreen(), cb->getBlue()));
glDrawElementsBaseVertex(ptype, count, itype, (GLvoid *)mesh.vaoOffset, mesh.vaoBaseVertex); glDrawElementsBaseVertex(ptype, count, itype, (GLvoid *)mesh.vaoOffset, mesh.vaoBaseVertex);
} }
@ -265,7 +265,7 @@ void STKMeshSceneNode::render()
pushVector(ListMatGrass::Arguments, mesh, AbsoluteTransformation, invmodel, windDir); pushVector(ListMatGrass::Arguments, mesh, AbsoluteTransformation, invmodel, windDir);
for_in(mesh, MeshSolidMaterials[MAT_UNLIT]) for_in(mesh, MeshSolidMaterials[MAT_UNLIT])
pushVector(ListMatUnlit::Arguments, mesh, AbsoluteTransformation, core::matrix4::EM4CONST_IDENTITY); pushVector(ListMatUnlit::Arguments, mesh, AbsoluteTransformation, core::matrix4::EM4CONST_IDENTITY, mesh->TextureMatrix);
for_in(mesh, MeshSolidMaterials[MAT_SPLATTING]) for_in(mesh, MeshSolidMaterials[MAT_SPLATTING])
pushVector(ListMatSplatting::Arguments, mesh, AbsoluteTransformation, invmodel); pushVector(ListMatSplatting::Arguments, mesh, AbsoluteTransformation, invmodel);
@ -312,7 +312,7 @@ void STKMeshSceneNode::render()
if (irr_driver->getPhase() == GLOW_PASS) if (irr_driver->getPhase() == GLOW_PASS)
{ {
glUseProgram(MeshShader::ColorizeShader::Program); glUseProgram(MeshShader::ColorizeShader::getInstance()->Program);
for (u32 i = 0; i < Mesh->getMeshBufferCount(); ++i) for (u32 i = 0; i < Mesh->getMeshBufferCount(); ++i)
{ {
scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i); scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i);

View File

@ -45,9 +45,8 @@ void GetPeerAddress::asynchronousUpdate()
if (m_state == NONE) if (m_state == NONE)
{ {
m_request = new Online::XMLRequest(); m_request = new Online::XMLRequest();
PlayerManager::setUserDetails(m_request, "get", PlayerManager::setUserDetails(m_request, "get", Online::API::SERVER_PATH);
"address-management.php"); m_request->addParameter("peer_id", m_peer_id);
m_request->addParameter("peer_id",m_peer_id);
Online::RequestManager::get()->addRequest(m_request); Online::RequestManager::get()->addRequest(m_request);
m_state = REQUEST_PENDING; m_state = REQUEST_PENDING;
@ -63,10 +62,12 @@ void GetPeerAddress::asynchronousUpdate()
{ {
TransportAddress* addr = static_cast<TransportAddress*>(m_callback_object); TransportAddress* addr = static_cast<TransportAddress*>(m_callback_object);
result->get("ip", &addr->ip); result->get("ip", &addr->ip);
if (addr->ip == NetworkManager::getInstance()->getPublicAddress().ip) if (addr->ip == NetworkManager::getInstance()->getPublicAddress().ip)
result->get("private_port", &addr->port); result->get("private_port", &addr->port);
else else
result->get("port", &addr->port); result->get("port", &addr->port);
Log::debug("GetPeerAddress", "Address gotten successfully."); Log::debug("GetPeerAddress", "Address gotten successfully.");
} }
else else

View File

@ -42,8 +42,7 @@ void HidePublicAddress::asynchronousUpdate()
if (m_state == NONE) if (m_state == NONE)
{ {
m_request = new Online::XMLRequest(); m_request = new Online::XMLRequest();
PlayerManager::setUserDetails(m_request, "unset", PlayerManager::setUserDetails(m_request, "unset", Online::API::SERVER_PATH);
"address-management.php");
Online::RequestManager::get()->addRequest(m_request); Online::RequestManager::get()->addRequest(m_request);
m_state = REQUEST_PENDING; m_state = REQUEST_PENDING;

View File

@ -44,8 +44,7 @@ void QuickJoinProtocol::asynchronousUpdate()
{ {
TransportAddress addr = NetworkManager::getInstance()->getPublicAddress(); TransportAddress addr = NetworkManager::getInstance()->getPublicAddress();
m_request = new Online::XMLRequest(); m_request = new Online::XMLRequest();
PlayerManager::setUserDetails(m_request, "quick-join"); PlayerManager::setUserDetails(m_request, "quick-join", Online::API::SERVER_PATH);
m_request->setServerURL("address-management.php");
Online::RequestManager::get()->addRequest(m_request); Online::RequestManager::get()->addRequest(m_request);
m_state = REQUEST_PENDING; m_state = REQUEST_PENDING;

View File

@ -72,9 +72,9 @@ void RequestConnection::asynchronousUpdate()
case NONE: case NONE:
{ {
m_request = new ServerJoinRequest(); m_request = new ServerJoinRequest();
PlayerManager::setUserDetails(m_request, "request-connection", PlayerManager::setUserDetails(m_request, "request-connection", Online::API::SERVER_PATH);
"address-management.php");
m_request->addParameter("server_id",m_server_id); m_request->addParameter("server_id", m_server_id);
m_request->queue(); m_request->queue();
m_state = REQUEST_PENDING; m_state = REQUEST_PENDING;
break; break;
@ -83,6 +83,7 @@ void RequestConnection::asynchronousUpdate()
{ {
if (!m_request->isDone()) if (!m_request->isDone())
return; return;
const XMLNode * result = m_request->getXMLData(); const XMLNode * result = m_request->getXMLData();
std::string rec_success; std::string rec_success;

View File

@ -183,16 +183,17 @@ void ServerLobbyRoomProtocol::checkIncomingConnectionRequests()
last_poll_time = StkTime::getRealTime(); last_poll_time = StkTime::getRealTime();
TransportAddress addr = NetworkManager::getInstance()->getPublicAddress(); TransportAddress addr = NetworkManager::getInstance()->getPublicAddress();
Online::XMLRequest* request = new Online::XMLRequest(); Online::XMLRequest* request = new Online::XMLRequest();
PlayerManager::setUserDetails(request, "poll-connection-requests", PlayerManager::setUserDetails(request, "poll-connection-requests", Online::API::SERVER_PATH);
"address-management.php");
request->addParameter("address",addr.ip); request->addParameter("address", addr.ip);
request->addParameter("port",addr.port); request->addParameter("port", addr.port);
request->executeNow(); request->executeNow();
assert(request->isDone()); assert(request->isDone());
const XMLNode * result = request->getXMLData(); const XMLNode * result = request->getXMLData();
std::string rec_success; std::string rec_success;
if(result->get("success", &rec_success)) if(result->get("success", &rec_success))
{ {
if(rec_success == "yes") if(rec_success == "yes")
@ -564,7 +565,7 @@ void ServerLobbyRoomProtocol::playerMinorVote(Event* event)
* Byte 0 1 5 6 N+6 N+7 N+8 * Byte 0 1 5 6 N+6 N+7 N+8
* ----------------------------------------------------------- * -----------------------------------------------------------
* Size | 1 | 4 | 1 | N | 1 | 1 | * 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) void ServerLobbyRoomProtocol::playerTrackVote(Event* event)
@ -597,7 +598,7 @@ void ServerLobbyRoomProtocol::playerTrackVote(Event* event)
* Byte 0 1 5 6 7 8 9 * Byte 0 1 5 6 7 8 9
* --------------------------------------------------------- * ---------------------------------------------------------
* Size | 1 | 4 | 1 | 1 | 1 | 1 | * 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) void ServerLobbyRoomProtocol::playerReversedVote(Event* event)
@ -630,7 +631,7 @@ void ServerLobbyRoomProtocol::playerReversedVote(Event* event)
* Byte 0 1 5 6 7 8 9 * Byte 0 1 5 6 7 8 9
* ----------------------------------------------------- * -----------------------------------------------------
* Size | 1 | 4 | 1 | 1 | 1 | 1 | * 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) void ServerLobbyRoomProtocol::playerLapsVote(Event* event)

View File

@ -43,11 +43,12 @@ void ShowPublicAddress::asynchronousUpdate()
{ {
TransportAddress addr = NetworkManager::getInstance()->getPublicAddress(); TransportAddress addr = NetworkManager::getInstance()->getPublicAddress();
m_request = new Online::XMLRequest(); m_request = new Online::XMLRequest();
PlayerManager::setUserDetails(m_request, "set", PlayerManager::setUserDetails(m_request, "set", Online::API::SERVER_PATH);
"address-management.php");
m_request->addParameter("address",addr.ip); m_request->addParameter("address", addr.ip);
m_request->addParameter("port",addr.port); m_request->addParameter("port", addr.port);
m_request->addParameter("private_port",NetworkManager::getInstance()->getHost()->getPort()); m_request->addParameter("private_port", NetworkManager::getInstance()->getHost()->getPort());
Log::info("ShowPublicAddress", "Showing addr %u and port %d", addr.ip, addr.port); Log::info("ShowPublicAddress", "Showing addr %u and port %d", addr.ip, addr.port);
Online::RequestManager::get()->addRequest(m_request); Online::RequestManager::get()->addRequest(m_request);

View File

@ -42,12 +42,13 @@ void StartServer::asynchronousUpdate()
{ {
TransportAddress addr = NetworkManager::getInstance()->getPublicAddress(); TransportAddress addr = NetworkManager::getInstance()->getPublicAddress();
m_request = new Online::XMLRequest(); m_request = new Online::XMLRequest();
PlayerManager::setUserDetails(m_request, "start-server", PlayerManager::setUserDetails(m_request, "start", Online::API::SERVER_PATH);
"address-management.php");
m_request->addParameter("address",addr.ip); m_request->addParameter("address", addr.ip);
m_request->addParameter("port",addr.port); m_request->addParameter("port", addr.port);
m_request->addParameter("private_port",NetworkManager::getInstance()->getHost()->getPort()); m_request->addParameter("private_port", NetworkManager::getInstance()->getHost()->getPort());
m_request->addParameter("max_players",UserConfigParams::m_server_max_players); m_request->addParameter("max_players", UserConfigParams::m_server_max_players);
Log::info("ShowPublicAddress", "Showing addr %u and port %d", addr.ip, addr.port); Log::info("ShowPublicAddress", "Showing addr %u and port %d", addr.ip, addr.port);
Online::RequestManager::get()->addRequest(m_request); Online::RequestManager::get()->addRequest(m_request);

View File

@ -47,10 +47,11 @@ void StopServer::asynchronousUpdate()
{ {
TransportAddress addr = NetworkManager::getInstance()->getPublicAddress(); TransportAddress addr = NetworkManager::getInstance()->getPublicAddress();
m_request = new Online::XMLRequest(); m_request = new Online::XMLRequest();
PlayerManager::setUserDetails(m_request, "stop-server", PlayerManager::setUserDetails(m_request, "stop", Online::API::SERVER_PATH);
"address-management.php");
m_request->addParameter("address",addr.ip); m_request->addParameter("address", addr.ip);
m_request->addParameter("port",addr.port); m_request->addParameter("port", addr.port);
Log::info("StopServer", "address %u, port %d", addr.ip, addr.port); Log::info("StopServer", "address %u, port %d", addr.ip, addr.port);
Online::RequestManager::get()->addRequest(m_request); Online::RequestManager::get()->addRequest(m_request);

View File

@ -26,12 +26,14 @@
#endif #endif
#include <curl/curl.h> #include <curl/curl.h>
#include <assert.h> #include <assert.h>
namespace Online namespace Online
{ {
const std::string API::VERSION = "v2";
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 /** Creates a HTTP(S) request that will have a raw string as result. (Can
* of course be used if the result doesn't matter.) * of course be used if the result doesn't matter.)
* \param manage_memory whether or not the RequestManager should take care of * \param manage_memory whether or not the RequestManager should take care of
@ -60,7 +62,8 @@ namespace Online
// A http request should not even be created when internet is disabled // A http request should not even be created when internet is disabled
assert(UserConfigParams::m_internet_status == assert(UserConfigParams::m_internet_status ==
RequestManager::IPERM_ALLOWED); RequestManager::IPERM_ALLOWED);
assert(filename.size()>0); assert(filename.size() > 0);
init(); init();
m_filename = file_manager->getAddonsFile(filename); m_filename = file_manager->getAddonsFile(filename);
} // HTTPRequest(filename ...) } // HTTPRequest(filename ...)
@ -76,6 +79,7 @@ namespace Online
// A http request should not even be created when internet is disabled // A http request should not even be created when internet is disabled
assert(UserConfigParams::m_internet_status == assert(UserConfigParams::m_internet_status ==
RequestManager::IPERM_ALLOWED); RequestManager::IPERM_ALLOWED);
init(); init();
m_filename = file_manager->getAddonsFile(filename); m_filename = file_manager->getAddonsFile(filename);
} // HTTPRequest(filename ...) } // HTTPRequest(filename ...)
@ -96,24 +100,30 @@ namespace Online
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** A handy shortcut that appends the given path to the URL of the /** A handy shortcut that appends the given path to the URL of the
* mutiplayer server. * mutiplayer server.
* \param path The path to add to the server. * \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); setURL(
(std::string)UserConfigParams::m_server_multiplayer +
API::VERSION + "/" + // eg: v1, v2, etc
path + // eg: user/, server/
action + "/" // eg: connect/, pool/, get-server-list/
);
} // setServerURL } // setServerURL
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** A handy shortcut that appends the given path to the URL of the addons /** A handy shortcut that appends the given path to the URL of the addons
* server. * 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) void HTTPRequest::setAddonsURL(const std::string& path)
{ {
setURL((std::string)UserConfigParams::m_server_addons setURL((std::string)UserConfigParams::m_server_addons + "/" + path);
+ "/" + path);
} // set AddonsURL } // set AddonsURL
// ------------------------------------------------------------------------
// ------------------------------------------------------------------------
/** Checks the request if it has enough (correct) information to be /** Checks the request if it has enough (correct) information to be
* executed (and thus allowed to add to the queue). * executed (and thus allowed to add to the queue).
*/ */
@ -128,7 +138,7 @@ namespace Online
void HTTPRequest::prepareOperation() void HTTPRequest::prepareOperation()
{ {
m_curl_session = curl_easy_init(); m_curl_session = curl_easy_init();
if(!m_curl_session) if (!m_curl_session)
{ {
Log::error("HTTPRequest::prepareOperation", Log::error("HTTPRequest::prepareOperation",
"LibCurl session not initialized."); "LibCurl session not initialized.");
@ -145,9 +155,9 @@ namespace Online
curl_easy_setopt(m_curl_session, CURLOPT_LOW_SPEED_LIMIT, 10); 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_LOW_SPEED_TIME, 20);
//curl_easy_setopt(m_curl_session, CURLOPT_VERBOSE, 1L); //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; struct curl_slist *chunk = NULL;
chunk = curl_slist_append(chunk, "Host: api.stkaddons.net"); chunk = curl_slist_append(chunk, "Host: api.stkaddons.net");
curl_easy_setopt(m_curl_session, CURLOPT_HTTPHEADER, chunk); curl_easy_setopt(m_curl_session, CURLOPT_HTTPHEADER, chunk);
@ -163,15 +173,15 @@ namespace Online
*/ */
void HTTPRequest::operation() void HTTPRequest::operation()
{ {
if(!m_curl_session) if (!m_curl_session)
return; return;
FILE *fout = NULL; FILE *fout = NULL;
if(m_filename.size()>0) if (m_filename.size() > 0)
{ {
fout = fopen((m_filename+".part").c_str(), "wb"); fout = fopen((m_filename+".part").c_str(), "wb");
if(!fout) if (!fout)
{ {
Log::error("HTTPRequest", Log::error("HTTPRequest",
"Can't open '%s' for writing, ignored.", "Can't open '%s' for writing, ignored.",
@ -190,23 +200,26 @@ namespace Online
} }
// All parameters added have a '&' added // All parameters added have a '&' added
if(m_parameters.size()>0) if (m_parameters.size() > 0)
{ {
m_parameters.erase(m_parameters.size()-1); 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()); 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 // Avoid printing the password or token, just replace them with *s
std::string param = m_parameters; std::string param = m_parameters;
// List of strings whose values should not be printed. "" is the // List of strings whose values should not be printed. "" is the
// end indicator. // end indicator.
static std::string dont_print[] = { "&password=", "&token=", "&current=", static std::string dont_print[] = { "&password=", "&token=", "&current=",
"&new1=", "&new2=", ""}; "&new1=", "&new2=", "&password_confirm=", ""};
unsigned int j = 0; unsigned int j = 0;
while (dont_print[j].size()>0) while (dont_print[j].size() > 0)
{ {
// Get the string that should be replaced. // Get the string that should be replaced.
std::size_t pos = param.find(dont_print[j]); std::size_t pos = param.find(dont_print[j]);
@ -221,11 +234,11 @@ namespace Online
} // if string found } // if string found
j++; j++;
} // while dont_print[j].size()>0 } // while dont_print[j].size()>0
Log::info("HTTPRequest", "Sending %s to %s",
param.c_str(), m_url.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()); curl_easy_setopt(m_curl_session, CURLOPT_POSTFIELDS, m_parameters.c_str());
std::string uagent( std::string("SuperTuxKart/") + STK_VERSION ); std::string uagent( std::string("SuperTuxKart/") + STK_VERSION );
#ifdef WIN32 #ifdef WIN32
uagent += (std::string)" (Windows)"; uagent += (std::string)" (Windows)";
@ -243,17 +256,18 @@ namespace Online
m_curl_code = curl_easy_perform(m_curl_session); m_curl_code = curl_easy_perform(m_curl_session);
Request::operation(); Request::operation();
if(fout) if (fout)
{ {
fclose(fout); fclose(fout);
if(m_curl_code==CURLE_OK) if (m_curl_code == CURLE_OK)
{ {
if(UserConfigParams::logAddons()) if(UserConfigParams::logAddons())
Log::info("HTTPRequest", "Download successful."); Log::info("HTTPRequest", "Download successful.");
// The behaviour of rename is unspecified if the target // The behaviour of rename is unspecified if the target
// file should already exist - so remove it. // file should already exist - so remove it.
bool ok = file_manager->removeFile(m_filename); bool ok = file_manager->removeFile(m_filename);
if(!ok) if (!ok)
{ {
Log::error("addons", Log::error("addons",
"Could not removed existing addons.xml file."); "Could not removed existing addons.xml file.");
@ -261,8 +275,9 @@ namespace Online
} }
int ret = rename((m_filename+".part").c_str(), int ret = rename((m_filename+".part").c_str(),
m_filename.c_str() ); m_filename.c_str() );
// In case of an error, set the status to indicate this // In case of an error, set the status to indicate this
if(ret!=0) if (ret != 0)
{ {
Log::error("addons", Log::error("addons",
"Could not rename downloaded addons.xml file!"); "Could not rename downloaded addons.xml file!");
@ -279,10 +294,11 @@ namespace Online
*/ */
void HTTPRequest::afterOperation() void HTTPRequest::afterOperation()
{ {
if(m_curl_code == CURLE_OK) if (m_curl_code == CURLE_OK)
setProgress(1.0f); setProgress(1.0f);
else else
setProgress(-1.0f); setProgress(-1.0f);
Request::afterOperation(); Request::afterOperation();
curl_easy_cleanup(m_curl_session); curl_easy_cleanup(m_curl_session);
} // afterOperation } // afterOperation
@ -322,7 +338,7 @@ namespace Online
// Check if we are asked to abort the download. If so, signal this // Check if we are asked to abort the download. If so, signal this
// back to libcurl by returning a non-zero status. // back to libcurl by returning a non-zero status.
if( (request_manager->getAbort() || request->isCancelled()) && if ((request_manager->getAbort() || request->isCancelled()) &&
request->isAbortable() ) request->isAbortable() )
{ {
// Indicates to abort the current download, which means that this // Indicates to abort the current download, which means that this
@ -331,23 +347,24 @@ namespace Online
} }
float f; float f;
if(download_now < download_total) if (download_now < download_total)
{ {
f = (float)download_now / (float)download_total; f = (float)download_now / (float)download_total;
// In case of floating point rouding errors make sure that // In case of floating point rouding errors make sure that
// 1.0 is only reached when downloadFileInternal is finished // 1.0 is only reached when downloadFileInternal is finished
if (f>=1.0f) f=0.99f; if (f >= 1.0f)
f = 0.99f;
} }
else else
{ {
// Don't set progress to 1.0f; this is done in afterOperation() // Don't set progress to 1.0f; this is done in afterOperation()
// after checking curls return code! // after checking curls return code!
f= download_total==0 ? 0 : 0.99f; f = (download_total == 0) ? 0 : 0.99f;
} }
request->setProgress(f); request->setProgress(f);
return 0; return 0;
} // progressDownload } // progressDownload
} // namespace Online } // namespace Online

View File

@ -34,6 +34,14 @@
namespace Online namespace Online
{ {
class API
{
public:
static const std::string VERSION;
static const std::string USER_PATH;
static const std::string SERVER_PATH;
};
/** A http request. /** A http request.
*/ */
class HTTPRequest : public Request class HTTPRequest : public Request
@ -78,22 +86,20 @@ namespace Online
void init(); void init();
public : public :
HTTPRequest(bool manage_memory = false, HTTPRequest(bool manage_memory = false, int priority = 1);
int priority = 1); HTTPRequest(const std::string &filename, bool manage_memory = false,
HTTPRequest(const std::string &filename, int priority = 1);
bool manage_memory = false, HTTPRequest(const char * const filename, bool manage_memory = false,
int priority = 1); int priority = 1);
HTTPRequest(const char * const filename, virtual ~HTTPRequest() {}
bool manage_memory = false,
int priority = 1);
virtual ~HTTPRequest() {};
virtual bool isAllowedToAdd() const OVERRIDE; 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); void setAddonsURL(const std::string& path);
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Returns true if there was an error downloading the file. /** Returns true if there was an error downloading the file. */
*/ bool hadDownloadError() const { return m_curl_code != CURLE_OK; }
bool hadDownloadError() const { return m_curl_code!=CURLE_OK; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Returns the curl error message if an error has occurred. /** Returns the curl error message if an error has occurred.
* \pre m_curl_code!=CURLE_OK * \pre m_curl_code!=CURLE_OK
@ -116,47 +122,50 @@ namespace Online
} // getData } // 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) void addParameter(const std::string & name, const std::string &value)
{ {
// Call the template, so that the strings are escaped properly // Call the template, so that the strings are escaped properly
addParameter(name, value.c_str()); addParameter(name, value.c_str());
}; // addParameter } // addParameter
// -------------------------------------------------------------------- // --------------------------------------------------------------------
/** Sets a parameter to 'value' (stringw). /** Sets a parameter to 'value' (stringw). */
*/ void addParameter(const std::string &name,
void addParameter(const std::string & name,
const irr::core::stringw &value) const irr::core::stringw &value)
{ {
core::stringc s = core::stringc(value.c_str()); core::stringc s = core::stringc(value.c_str());
// Call the template to escape strings properly // Call the template to escape strings properly
addParameter(name, s.c_str()); addParameter(name, s.c_str());
} // addParameter } // addParameter
// -------------------------------------------------------------------- // --------------------------------------------------------------------
/** Sets a parameter to 'value' (arbitrary types). /** Sets a parameter to 'value' (arbitrary types). */
*/
template <typename T> template <typename T>
void addParameter(const std::string & name, const T& value) void addParameter(const std::string &name, const T& value)
{ {
assert(isPreparing()); assert(isPreparing());
std::string s = StringUtils::toString(value); 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()); 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(s1);
curl_free(s2); curl_free(s2);
} // addParameter } // addParameter
// -------------------------------------------------------------------- // --------------------------------------------------------------------
/** Returns the current progress. */ /** Returns the current progress. */
float getProgress() const { return m_progress.getAtomic(); } float getProgress() const { return m_progress.getAtomic(); }
// -------------------------------------------------------------------- // --------------------------------------------------------------------
/** Sets the current progress. */ /** 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;} const std::string & getURL() const { assert(isBusy()); return m_url;}
// -------------------------------------------------------------------- // --------------------------------------------------------------------
/** Sets the URL for this request. */ /** Sets the URL for this request. */
void setURL(const std::string & url) void setURL(const std::string & url)
@ -166,8 +175,5 @@ namespace Online
} // setURL } // setURL
}; // class HTTPRequest }; // class HTTPRequest
} //namespace Online } //namespace Online
#endif // HEADER_HTTP_REQUEST_HPP
#endif

View File

@ -16,7 +16,6 @@
// along with this program; if not, write to the Free Software // along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "online/online_player_profile.hpp" #include "online/online_player_profile.hpp"
#include "achievements/achievements_manager.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 /** Adds the login credential to a http request. It sets the name of
* the script to invokce, token, and user id. * the script to invokce, token, and user id.
* \param request The http request. * \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, void OnlinePlayerProfile::setUserDetails(HTTPRequest *request,
const std::string &action, const std::string &action,
const std::string &php_script) const const std::string &url_path) const
{ {
if (php_script.size()>0) if (url_path.size())
request->setServerURL(php_script); {
else request->setApiURL(url_path, action);
request->setServerURL("client-user.php"); }
else // default path
{
request->setApiURL(API::USER_PATH, action);
}
if (m_profile) if (m_profile)
request->addParameter("userid", m_profile->getID()); 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); request->addParameter("token", m_token);
if (action.size() > 0)
request->addParameter("action", action);
} // setUserDetails } // setUserDetails
// ======================================================================== // ========================================================================
@ -86,16 +87,17 @@ namespace Online
m_profile = NULL; m_profile = NULL;
} // OnlinePlayerProfile } // OnlinePlayerProfile
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Request a login using the saved credentials of the user. /** Request a login using the saved credentials of the user. */
*/
void OnlinePlayerProfile::requestSavedSession() void OnlinePlayerProfile::requestSavedSession()
{ {
SignInRequest * request = NULL; SignInRequest *request = NULL;
if (m_online_state == OS_SIGNED_OUT && hasSavedSession()) if (m_online_state == OS_SIGNED_OUT && hasSavedSession())
{ {
request = new SignInRequest(true); request = new SignInRequest(true);
setUserDetails(request, "saved-session"); setUserDetails(request, "saved-session");
// The userid must be taken from the saved data, // The userid must be taken from the saved data,
// setUserDetails takes it from current data. // setUserDetails takes it from current data.
request->addParameter("userid", getSavedUserId()); request->addParameter("userid", getSavedUserId());
@ -117,18 +119,19 @@ namespace Online
// If the player changes the online account, there can be a // If the player changes the online account, there can be a
// logout stil happening. // logout stil happening.
assert(m_online_state == OS_SIGNED_OUT || assert(m_online_state == OS_SIGNED_OUT ||
m_online_state == OS_SIGNING_OUT ); m_online_state == OS_SIGNING_OUT);
SignInRequest * request = new SignInRequest(false); SignInRequest * request = new SignInRequest(false);
// We can't use setUserDetail here, since there is no token yet // We can't use setUserDetail here, since there is no token yet
request->setServerURL("client-user.php"); request->setApiURL(API::USER_PATH, "connect");
request->addParameter("action","connect"); request->addParameter("username", username);
request->addParameter("username",username); request->addParameter("password", password);
request->addParameter("password",password);
request->addParameter("save-session", request->addParameter("save-session",
rememberPassword() ? "true" rememberPassword() ? "true"
: "false"); : "false");
request->queue(); request->queue();
m_online_state = OS_SIGNING_IN; m_online_state = OS_SIGNING_IN;
return request; return request;
} // requestSignIn } // requestSignIn
@ -143,13 +146,13 @@ namespace Online
// If the login is successful, reset any saved session of other // If the login is successful, reset any saved session of other
// local players using the same online account (which are now invalid) // local players using the same online account (which are now invalid)
if(isSuccess()) if (isSuccess())
{ {
PlayerProfile *current = PlayerManager::getCurrentPlayer(); 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); PlayerProfile *player = PlayerManager::get()->getPlayer(i);
if(player!=current && if(player != current &&
player->hasSavedSession() && player->hasSavedSession() &&
player->getLastOnlineName() == current->getLastOnlineName()) player->getLastOnlineName() == current->getLastOnlineName())
{ {
@ -157,7 +160,8 @@ namespace Online
} }
} }
} }
if(login)
if (login)
{ {
if(isSuccess()) if(isSuccess())
login->loginSuccessful(); login->loginSuccessful();
@ -178,12 +182,14 @@ namespace Online
{ {
if (success) if (success)
{ {
int token_fetched = input->get("token", &m_token);
core::stringw username(""); core::stringw username("");
int username_fetched = input->get("username", &username);
uint32_t userid(0); 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); int userid_fetched = input->get("userid", &userid);
setLastOnlineName(username); setLastOnlineName(username);
m_profile = new OnlineProfile(userid, username, true); m_profile = new OnlineProfile(userid, username, true);
assert(token_fetched && username_fetched && userid_fetched); assert(token_fetched && username_fetched && userid_fetched);
m_online_state = OS_SIGNED_IN; m_online_state = OS_SIGNED_IN;
@ -191,8 +197,10 @@ namespace Online
{ {
saveSession(getOnlineId(), getToken()); saveSession(getOnlineId(), getToken());
} }
ProfileManager::get()->addPersistent(m_profile); ProfileManager::get()->addPersistent(m_profile);
std::string achieved_string(""); std::string achieved_string("");
// Even if no achievements were sent, we have to call sync // Even if no achievements were sent, we have to call sync
// in order to upload local achievements to the server // in order to upload local achievements to the server
input->get("achieved", &achieved_string); input->get("achieved", &achieved_string);
@ -260,6 +268,7 @@ namespace Online
{ {
GUIEngine::Screen *screen = GUIEngine::getCurrentScreen(); GUIEngine::Screen *screen = GUIEngine::getCurrentScreen();
BaseUserScreen *user_screen = dynamic_cast<BaseUserScreen*>(screen); BaseUserScreen *user_screen = dynamic_cast<BaseUserScreen*>(screen);
// We can't do much of error handling here, no screen waits for // 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, // a logout to finish, so we can only log the message to screen,
// and otherwise mark the player logged out internally. // and otherwise mark the player logged out internally.
@ -269,20 +278,21 @@ namespace Online
"There were some connection issues while signing out. " "There were some connection issues while signing out. "
"Report a bug if this caused issues."); "Report a bug if this caused issues.");
Log::warn("OnlinePlayerProfile::signOut", core::stringc(info.c_str()).c_str()); Log::warn("OnlinePlayerProfile::signOut", core::stringc(info.c_str()).c_str());
if(user_screen) if (user_screen)
user_screen->logoutError(info); user_screen->logoutError(info);
} }
else else
{ {
if(user_screen) if (user_screen)
user_screen->logoutSuccessful(); user_screen->logoutSuccessful();
} }
ProfileManager::get()->clearPersistent(); ProfileManager::get()->clearPersistent();
m_profile = NULL; m_profile = NULL;
m_online_state = OS_SIGNED_OUT; m_online_state = OS_SIGNED_OUT;
// Discard token if session should not be saved. // Discard token if session should not be saved.
if(!rememberPassword()) if (!rememberPassword())
clearSession(); clearSession();
} // signOut } // signOut
@ -293,7 +303,8 @@ namespace Online
void OnlinePlayerProfile::requestPoll() const void OnlinePlayerProfile::requestPoll() const
{ {
assert(m_online_state == OS_SIGNED_IN); assert(m_online_state == OS_SIGNED_IN);
OnlinePlayerProfile::PollRequest * request = new OnlinePlayerProfile::PollRequest();
OnlinePlayerProfile::PollRequest *request = new OnlinePlayerProfile::PollRequest();
setUserDetails(request, "poll"); setUserDetails(request, "poll");
request->queue(); request->queue();
} // requestPoll() } // requestPoll()
@ -304,127 +315,137 @@ namespace Online
*/ */
void OnlinePlayerProfile::PollRequest::callback() void OnlinePlayerProfile::PollRequest::callback()
{ {
if(isSuccess()) // connection error
if (!isSuccess())
{ {
if (!PlayerManager::getCurrentPlayer()->isLoggedIn()) Log::error("Online Player Profile", "Poll request failed");
return; return;
if (PlayerManager::getCurrentPlayer()->getProfile()->hasFetchedFriends()) }
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(""); std::vector<uint32_t> online_friends =
if(getXMLData()->get("online", &online_friends_string) == 1) 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 = bool now_online = false;
StringUtils::splitToUInt(online_friends_string, ' '); std::vector<uint32_t>::iterator found_friend =
bool went_offline = false; std::find(online_friends.begin(),
std::vector<uint32_t> friends = online_friends.end(), friends[i]);
PlayerManager::getCurrentPlayer()->getProfile()->getFriends(); if (found_friend != online_friends.end())
std::vector<core::stringw> to_notify; {
for(unsigned int i = 0; i < friends.size(); ++i) now_online = true;
{ online_friends.erase(found_friend);
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());
}
}
} OnlineProfile * profile =
ProfileManager::get()->getProfileByID(friends[i]);
OnlineProfile::RelationInfo * relation_info =
profile->getRelationInfo();
if(to_notify.size() > 0) if (relation_info->isOnline())
{ {
core::stringw message(""); if (!now_online) // the friend went offline
if(to_notify.size() == 1) {
{ relation_info->setOnline(false);
message = _("%s is now online.", to_notify[0]); went_offline = true;
} }
else if(to_notify.size() == 2) }
{ else
message = _("%s and %s are now online.", {
to_notify[0], to_notify[1] ); if (now_online) // friend came online
} {
else if(to_notify.size() == 3) relation_info->setOnline(true);
{
message = _("%s, %s and %s are now online.", // Do this because a user might have accepted
to_notify[0], to_notify[1], to_notify[2]); // a pending friend request.
} profile->setFriend();
else if(to_notify.size() > 3) to_notify.push_back(profile->getUserName());
{ }
message = _("%d friends are now online.", }
to_notify.size());
}
MessageQueue::add(MessageQueue::MT_FRIEND, message);
}
else if(went_offline)
{
OnlineProfileFriends::getInstance()->refreshFriendsList();
}
} }
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 else
{ {
PlayerManager::getCurrentPlayer()->getProfile()->fetchFriends(); message = _("You have a new friend request!");
} }
int friend_request_count = 0; MessageQueue::add(MessageQueue::MT_FRIEND, message);
for(unsigned int i = 0; i < getXMLData()->getNumNodes(); i++) OnlineProfileFriends::getInstance()->refreshFriendsList();
{
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();
}
} }
// FIXME show connection error??
// Perhaps show something after 2 misses.
} // PollRequest::callback } // PollRequest::callback
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
@ -432,11 +453,12 @@ namespace Online
*/ */
uint32_t OnlinePlayerProfile::getOnlineId() const uint32_t OnlinePlayerProfile::getOnlineId() const
{ {
if((m_online_state == OS_SIGNED_IN )) if (m_online_state == OS_SIGNED_IN)
{ {
assert(m_profile != NULL); assert(m_profile != NULL);
return m_profile->getID(); return m_profile->getID();
} }
return 0; return 0;
} // getOnlineId } // getOnlineId

View File

@ -37,7 +37,6 @@ class PlayerManager;
namespace Online namespace Online
{ {
class OnlineProfile; class OnlineProfile;
// ============================================================================ // ============================================================================
@ -48,75 +47,73 @@ namespace Online
*/ */
class OnlinePlayerProfile : public PlayerProfile class OnlinePlayerProfile : public PlayerProfile
{ {
public:
// ----------------------------------------------------------------
class SignInRequest : public XMLRequest
{
virtual void callback ();
public: public:
// ---------------------------------------------------------------- SignInRequest(bool manage_memory = false)
class SignInRequest : public XMLRequest : XMLRequest(manage_memory, /*priority*/10) {}
{ }; // SignInRequest
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);
// ----------------------------------------------------------------
class PollRequest : public XMLRequest
{
virtual void callback ();
public: public:
OnlinePlayerProfile(const XMLNode *player); PollRequest() : XMLRequest(true) {}
OnlinePlayerProfile(const core::stringw &name, bool is_guest = false); }; // PollRequest
virtual ~OnlinePlayerProfile() {};
// ----------------------------------------------------------------
}; // 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 } // namespace Online
#endif // HEADER_CURRENT_ONLINE_USER_HPP
#endif
/*EOF*/

View File

@ -16,7 +16,6 @@
// along with this program; if not, write to the Free Software // along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "online/online_profile.hpp" #include "online/online_profile.hpp"
#include "config/player_manager.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_online, bool is_pending,
bool is_asker) bool is_asker)
{ {
m_date = date; m_date = date;
m_is_online = is_online; m_is_online = is_online;
m_is_pending = is_pending; m_is_pending = is_pending;
m_is_asker = is_asker; m_is_asker = is_asker;
} // RelationInfo::RelationInfo } // RelationInfo::RelationInfo
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@ -91,12 +90,11 @@ OnlineProfile::OnlineProfile(const XMLNode * xml, ConstructorType type)
if (type == C_RELATION_INFO) if (type == C_RELATION_INFO)
{ {
irr::core::stringw date(""); irr::core::stringw date("");
bool is_pending = false, is_asker = false, is_online = false;
xml->get("date", &date); xml->get("date", &date);
std::string is_pending_string("");
bool is_pending = false;
xml->get("is_pending", &is_pending); xml->get("is_pending", &is_pending);
bool is_asker = false;
bool is_online = false;
if (is_pending) if (is_pending)
{ {
xml->get("is_asker", &is_asker); xml->get("is_asker", &is_asker);
@ -113,7 +111,7 @@ OnlineProfile::OnlineProfile(const XMLNode * xml, ConstructorType type)
xml->get("id", &m_id ); xml->get("id", &m_id );
xml->get("user_name", &m_username); 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; m_state = S_READY;
} // OnlineProfile(XMLNode) } // OnlineProfile(XMLNode)
@ -133,6 +131,7 @@ void OnlineProfile::fetchAchievements()
assert(PlayerManager::isCurrentLoggedIn()); assert(PlayerManager::isCurrentLoggedIn());
if (m_has_fetched_achievements || m_is_current_user) if (m_has_fetched_achievements || m_is_current_user)
return; return;
m_state = S_FETCHING; m_state = S_FETCHING;
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
@ -187,6 +186,7 @@ void OnlineProfile::fetchFriends()
assert(PlayerManager::isCurrentLoggedIn()); assert(PlayerManager::isCurrentLoggedIn());
if (m_has_fetched_friends) if (m_has_fetched_friends)
return; return;
m_state = S_FETCHING; m_state = S_FETCHING;
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
@ -258,9 +258,11 @@ void OnlineProfile::removeFriend(const uint32_t id)
break; break;
} }
else else
{
++iter; ++iter;
} }
} // removeFriend } // for friend in friends
} // removeFriend
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
/** Adds a friend to the friend list. /** 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) void OnlineProfile::addFriend(const uint32_t id)
{ {
assert(m_has_fetched_friends); 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++) 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); m_friends.push_back(id);
} // addFriend } // addFriend
@ -310,18 +317,25 @@ const OnlineProfile::IDList& OnlineProfile::getAchievements()
void OnlineProfile::merge(OnlineProfile *profile) void OnlineProfile::merge(OnlineProfile *profile)
{ {
assert(profile != NULL); assert(profile != NULL);
if (!this->m_has_fetched_friends && profile->m_has_fetched_friends)
this->m_friends = profile->m_friends; // profile has fetched friends, use that instead
if (!this->m_has_fetched_achievements && profile->m_has_fetched_achievements) if (!m_has_fetched_friends && profile->m_has_fetched_friends)
this->m_achievements = profile->m_achievements; m_friends = profile->m_friends;
if (this->m_relation_info == NULL && profile->m_relation_info != NULL)
// 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 // We don't want the destructor of the profile instance to destroy
// the relation info // the relation info
profile->m_relation_info = NULL; profile->m_relation_info = NULL;
} }
delete profile;
} // merge
delete profile;
} // merge
} // namespace Online } // namespace Online

View File

@ -24,9 +24,7 @@
#include "utils/types.hpp" #include "utils/types.hpp"
#include "utils/ptr_vector.hpp" #include "utils/ptr_vector.hpp"
#include <irrString.h> #include <irrString.h>
#include <string> #include <string>
namespace Online namespace Online
@ -54,16 +52,21 @@ public:
bool m_is_pending; bool m_is_pending;
bool m_is_asker; bool m_is_asker;
irr::core::stringw m_date; irr::core::stringw m_date;
public: public:
RelationInfo(const irr::core::stringw & date, bool is_online, RelationInfo(const irr::core::stringw & date, bool is_online,
bool is_pending, bool is_asker = false); bool is_pending, bool is_asker = false);
void setOnline(bool online); void setOnline(bool online);
// -------------------------------------------------------------------- // --------------------------------------------------------------------
bool isPending() const { return m_is_pending; } bool isPending() const { return m_is_pending; }
// -------------------------------------------------------------------- // --------------------------------------------------------------------
bool isAsker() const { return m_is_asker; } bool isAsker() const { return m_is_asker; }
// -------------------------------------------------------------------- // --------------------------------------------------------------------
const irr::core::stringw & getDate() const { return m_date; } const irr::core::stringw & getDate() const { return m_date; }
// -------------------------------------------------------------------- // --------------------------------------------------------------------
bool isOnline() const { return m_is_online; } bool isOnline() const { return m_is_online; }
}; // class RelationInfo }; // class RelationInfo
@ -104,12 +107,11 @@ private:
void storeAchievements(const XMLNode * input); void storeAchievements(const XMLNode * input);
public: public:
OnlineProfile(const uint32_t & userid, OnlineProfile(const uint32_t & userid,
const irr::core::stringw & username, const irr::core::stringw & username,
bool is_current_user = false ); bool is_current_user = false );
OnlineProfile(const XMLNode * xml, OnlineProfile(const XMLNode * xml, ConstructorType type = C_DEFAULT);
ConstructorType type = C_DEFAULT); ~OnlineProfile();
~OnlineProfile();
void fetchFriends(); void fetchFriends();
const IDList& getFriends(); const IDList& getFriends();
void fetchAchievements(); void fetchAchievements();
@ -118,49 +120,55 @@ public:
void deleteRelationalInfo(); void deleteRelationalInfo();
const IDList& getAchievements(); const IDList& getAchievements();
void merge(OnlineProfile * profile); void merge(OnlineProfile * profile);
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Returns true if the achievements for this profile have been fetched. */ /** Returns true if the achievements for this profile have been fetched. */
bool hasFetchedAchievements() const { return m_has_fetched_achievements; } bool hasFetchedAchievements() const { return m_has_fetched_achievements; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Returns true if the friend list for this profile has been fetched. */ /** Returns true if the friend list for this profile has been fetched. */
bool hasFetchedFriends() const { return m_has_fetched_friends; } bool hasFetchedFriends() const { return m_has_fetched_friends; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** True if the profile is not fetching data atm. */ /** True if the profile is not fetching data atm. */
bool isReady() const { return m_state == S_READY; } bool isReady() const { return m_state == S_READY; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Returns true if this item is the current user. */ /** Returns true if this item is the current user. */
bool isCurrentUser() const { return m_is_current_user; } bool isCurrentUser() const { return m_is_current_user; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
bool isFriend() const { return m_is_friend; } bool isFriend() const { return m_is_friend; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
void setFriend() { m_is_friend = true; } void setFriend() { m_is_friend = true; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
RelationInfo* getRelationInfo() { return m_relation_info; } RelationInfo* getRelationInfo() { return m_relation_info; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
void setRelationInfo(RelationInfo * r) void setRelationInfo(RelationInfo * r)
{ {
delete m_relation_info; m_relation_info = r; delete m_relation_info; m_relation_info = r;
} // setRelationInfo } // setRelationInfo
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Sets the cache bit of this profile. Used by the cache eviction /** Sets the cache bit of this profile. Used by the cache eviction
* algorithm. */ * algorithm. */
void setCacheBit(bool cache_bit) { m_cache_bit = cache_bit; } void setCacheBit(bool cache_bit) { m_cache_bit = cache_bit; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Returns the cache bit for this profile. Used by the cache eviction /** Returns the cache bit for this profile. Used by the cache eviction
* algorithm. */ * algorithm. */
bool getCacheBit() const { return m_cache_bit; } bool getCacheBit() const { return m_cache_bit; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Returns the online id of this profile. */ /** Returns the online id of this profile. */
uint32_t getID() const { return m_id; } uint32_t getID() const { return m_id; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Returns the user name of this profile. */ /** Returns the user name of this profile. */
const irr::core::stringw& getUserName() const { return m_username; } const irr::core::stringw& getUserName() const { return m_username; }
// ------------------------------------------------------------------------
}; // class OnlineProfile }; // class OnlineProfile
} // namespace Online } // namespace Online
#endif // HEADER_ONLINE_PROFILE_HPP
#endif
/*EOF*/

View File

@ -16,7 +16,6 @@
// along with this program; if not, write to the Free Software // along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "online/profile_manager.hpp" #include "online/profile_manager.hpp"
#include "online/online_profile.hpp" #include "online/online_profile.hpp"
@ -50,7 +49,8 @@ ProfileManager::~ProfileManager()
{ {
clearPersistent(); clearPersistent();
ProfilesMap::iterator it; 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; delete it->second;
} }
} // ~ProfileManager } // ~ProfileManager
@ -72,8 +72,8 @@ int ProfileManager::guaranteeCacheSize(unsigned int min_num)
min_num = 100; min_num = 100;
m_max_cache_size = min_num; m_max_cache_size = min_num;
} }
return m_max_cache_size;
return m_max_cache_size;
} // guaranteeCacheSize } // guaranteeCacheSize
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
@ -88,7 +88,8 @@ OnlineProfile* ProfileManager::getProfileByID(const uint32_t id)
return m_profiles_persistent[id]; return m_profiles_persistent[id];
if (isInCache(id)) if (isInCache(id))
return m_profiles_cache[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. // server, but I haven't come up with a good asynchronous idea yet.
return NULL; return NULL;
} // getProfileByID } // getProfileByID
@ -135,12 +136,14 @@ void ProfileManager::addDirectToCache(OnlineProfile* profile)
break; break;
} }
else else
{
++iter; ++iter;
} }
} // for profile in cache
} }
m_profiles_cache[profile->getID()] = profile; m_profiles_cache[profile->getID()] = profile;
assert(m_profiles_cache.size() <= m_max_cache_size); assert(m_profiles_cache.size() <= m_max_cache_size);
} // addDirectToCache } // addDirectToCache
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
@ -155,6 +158,7 @@ bool ProfileManager::isInCache(const uint32_t id)
updateCacheBits(i->second); updateCacheBits(i->second);
return true; return true;
} }
return false; return false;
} // isInCache } // isInCache
@ -180,6 +184,7 @@ void ProfileManager::updateCacheBits(OnlineProfile * profile)
if (!iter->second->getCacheBit()) if (!iter->second->getCacheBit())
return; return;
} }
// All cache bits are set! Set them all to zero except the one // All cache bits are set! Set them all to zero except the one
// currently being visited // currently being visited
for (iter = m_profiles_cache.begin(); for (iter = m_profiles_cache.begin();
@ -189,7 +194,6 @@ void ProfileManager::updateCacheBits(OnlineProfile * profile)
} }
profile->setCacheBit(true); profile->setCacheBit(true);
} }
} // updateCacheBits } // updateCacheBits
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
@ -232,11 +236,14 @@ void ProfileManager::deleteFromPersistent(const uint32_t id)
m_profiles_persistent.erase(id); m_profiles_persistent.erase(id);
} }
else else
{
Log::warn("ProfileManager", Log::warn("ProfileManager",
"Tried to remove profile with id %d from persistent while " "Tried to remove profile with id %d from persistent while "
"not present", id); "not present", id);
}
} // deleteFromPersistent } // deleteFromPersistent
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Deletes all persistent profiles. /** Deletes all persistent profiles.
*/ */
@ -265,10 +272,11 @@ void ProfileManager::moveToCache(const uint32_t id)
addToCache(profile); addToCache(profile);
} }
else else
{
Log::warn("ProfileManager", Log::warn("ProfileManager",
"Tried to move profile with id %d from persistent to " "Tried to move profile with id %d from persistent to "
"cache while not present", id); "cache while not present", id);
}
} // moveToCache } // moveToCache
} // namespace Online } // namespace Online

View File

@ -29,7 +29,6 @@
namespace Online namespace Online
{ {
class OnlineProfile; class OnlineProfile;
/** Class that manages all online profiles. Profiles are used for storing /** Class that manages all online profiles. Profiles are used for storing
@ -81,6 +80,7 @@ public:
assert(!m_profile_manager); assert(!m_profile_manager);
m_profile_manager = new ProfileManager(); m_profile_manager = new ProfileManager();
} // create } // create
// ---------------------------------------------------------------- // ----------------------------------------------------------------
/** Returns the singleton. /** Returns the singleton.
* \pre create has been called to create the singleton. * \pre create has been called to create the singleton.
@ -109,6 +109,7 @@ public:
bool isInCache(const uint32_t id); bool isInCache(const uint32_t id);
bool inPersistent(const uint32_t id); bool inPersistent(const uint32_t id);
OnlineProfile* getProfileByID(const uint32_t id); OnlineProfile* getProfileByID(const uint32_t id);
// ---------------------------------------------------------------- // ----------------------------------------------------------------
/** Marks a given profile to be the currently visited one. This /** Marks a given profile to be the currently visited one. This
* is used to mark the profiles that ave its data display (e.g. * is used to mark the profiles that ave its data display (e.g.
@ -117,15 +118,12 @@ public:
{ {
m_currently_visiting = getProfileByID(id); m_currently_visiting = getProfileByID(id);
} // setVisiting } // setVisiting
// ---------------------------------------------------------------- // ----------------------------------------------------------------
/** \return the instance of the profile that's currently being /** \return the instance of the profile that's currently being
* visited */ * visited */
OnlineProfile* getVisitingProfile() { return m_currently_visiting; } OnlineProfile* getVisitingProfile() { return m_currently_visiting; }
}; // class CurrentUser }; // class CurrentUser
} // namespace Online } // namespace Online
#endif // HEADER_ONLINE_PROFILE_MANAGER_HPP
#endif
/*EOF*/

View File

@ -25,10 +25,8 @@
#include <assert.h> #include <assert.h>
namespace Online namespace Online
{ {
// ======================================================================== // ========================================================================
/** /**
* Creates a request that can be handled by the RequestManager * Creates a request that can be handled by the RequestManager
@ -67,6 +65,7 @@ namespace Online
setExecuted(); setExecuted();
afterOperation(); afterOperation();
} // execute } // execute
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Executes the request now, i.e. in the main thread and without involving /** Executes the request now, i.e. in the main thread and without involving
* the manager thread.. This calles prepareOperation, operation, and * the manager thread.. This calles prepareOperation, operation, and
@ -81,5 +80,4 @@ namespace Online
setDone(); setDone();
} // executeNow } // executeNow
} // namespace Online } // namespace Online

View File

@ -35,7 +35,6 @@
namespace Online namespace Online
{ {
/** Stores a request for the HTTP Manager. They will be sorted by /** Stores a request for the HTTP Manager. They will be sorted by
* prioritiy. Requests have four different states they can be in, and * prioritiy. Requests have four different states they can be in, and
* this state determines which thread can access it. This allows * 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 /** The actual operation to be executed. Empty as default, which
* allows to create a 'quit' request without any additional code. */ * allows to create a 'quit' request without any additional code. */
virtual void operation() {} virtual void operation() {}
// -------------------------------------------------------------------- // --------------------------------------------------------------------
/** Virtual function to be called before an operation. */ /** Virtual function to be called before an operation. */
virtual void prepareOperation() {} virtual void prepareOperation() {}
// -------------------------------------------------------------------- // --------------------------------------------------------------------
/** Virtual function to be called after an operation. */ /** Virtual function to be called after an operation. */
virtual void afterOperation() {} virtual void afterOperation() {}
@ -132,71 +133,87 @@ namespace Online
RT_QUIT = 1 RT_QUIT = 1
}; };
Request(bool manage_memory, int priority, int type); Request(bool manage_memory, int priority, int type);
virtual ~Request() {} virtual ~Request() {}
void execute(); void execute();
void executeNow(); void executeNow();
void queue(); void queue();
// -------------------------------------------------------------------- // --------------------------------------------------------------------
/** Executed when a request has finished. */ /** Executed when a request has finished. */
virtual void callback() {} virtual void callback() {}
// -------------------------------------------------------------------- // --------------------------------------------------------------------
/** Returns the type of the request. */ /** Returns the type of the request. */
int getType() const { return m_type; } int getType() const { return m_type; }
// -------------------------------------------------------------------- // --------------------------------------------------------------------
/** Returns if the memory for this object should be managed by /** Returns if the memory for this object should be managed by
* by network_http (i.e. freed once the request is handled). */ * by network_http (i.e. freed once the request is handled). */
bool manageMemory() const { return m_manage_memory; } bool manageMemory() const { return m_manage_memory; }
// -------------------------------------------------------------------- // --------------------------------------------------------------------
/** Sets the memory management flag of this request. This function /** Sets the memory management flag of this request. This function
* must only be called by the main thread, since it is only tested by * must only be called by the main thread, since it is only tested by
* the main thread. */ * the main thread. */
void setManageMemory(bool m) { m_manage_memory = m; } void setManageMemory(bool m) { m_manage_memory = m; }
// -------------------------------------------------------------------- // --------------------------------------------------------------------
/** Returns the priority of this request. */ /** Returns the priority of this request. */
int getPriority() const { return m_priority; } int getPriority() const { return m_priority; }
// -------------------------------------------------------------------- // --------------------------------------------------------------------
/** Signals that this request should be canceled. */ /** Signals that this request should be canceled. */
void cancel() { m_cancel.setAtomic(true); } void cancel() { m_cancel.setAtomic(true); }
// -------------------------------------------------------------------- // --------------------------------------------------------------------
/** Returns if this request is to be canceled. */ /** Returns if this request is to be canceled. */
bool isCancelled() const { return m_cancel.getAtomic(); } bool isCancelled() const { return m_cancel.getAtomic(); }
// -------------------------------------------------------------------- // --------------------------------------------------------------------
/** Returns if this request can be aborted. */ /** Returns if this request can be aborted. */
bool isAbortable() const { return m_is_abortable.getAtomic(); } bool isAbortable() const { return m_is_abortable.getAtomic(); }
// -------------------------------------------------------------------- // --------------------------------------------------------------------
/** Sets if this request is abortable or not. */ /** Sets if this request is abortable or not. */
void setAbortable(bool b) { m_is_abortable.setAtomic(b); } void setAbortable(bool b) { m_is_abortable.setAtomic(b); }
// -------------------------------------------------------------------- // --------------------------------------------------------------------
/** Sets the request state to busy. */ /** Sets the request state to busy. */
void setBusy() void setBusy()
{ {
assert(m_state.getAtomic()==S_PREPARING); assert(m_state.getAtomic() == S_PREPARING);
m_state.setAtomic(S_BUSY); m_state.setAtomic(S_BUSY);
} // setBusy } // setBusy
// -------------------------------------------------------------------- // --------------------------------------------------------------------
/** Sets the request to be completed. */ /** Sets the request to be completed. */
void setExecuted() void setExecuted()
{ {
assert(m_state.getAtomic()==S_BUSY); assert(m_state.getAtomic() == S_BUSY);
m_state.setAtomic(S_EXECUTED); m_state.setAtomic(S_EXECUTED);
} // setExecuted } // setExecuted
// -------------------------------------------------------------------- // --------------------------------------------------------------------
/** Should only be called by the manager */ /** Should only be called by the manager */
void setDone() void setDone()
{ {
assert(m_state.getAtomic()==S_EXECUTED); assert(m_state.getAtomic() == S_EXECUTED);
m_state.setAtomic(S_DONE); m_state.setAtomic(S_DONE);
} // setDone } // setDone
// -------------------------------------------------------------------- // --------------------------------------------------------------------
/** Returns if this request is done. */ /** Returns if this request is done. */
bool isDone() const { return m_state.getAtomic() == S_DONE; } bool isDone() const { return m_state.getAtomic() == S_DONE; }
// -------------------------------------------------------------------- // --------------------------------------------------------------------
/** Returns if this request is being prepared. */ /** Returns if this request is being prepared. */
bool isPreparing() const { return m_state.getAtomic() == S_PREPARING; } bool isPreparing() const { return m_state.getAtomic() == S_PREPARING; }
// -------------------------------------------------------------------- // --------------------------------------------------------------------
/** Returns if this request is busy. */ /** Returns if this request is busy. */
bool isBusy() const { return m_state.getAtomic() == S_BUSY; } bool isBusy() const { return m_state.getAtomic() == S_BUSY; }
// -------------------------------------------------------------------- // --------------------------------------------------------------------
/** Checks if the request has completed or done (i.e. callbacks were /** Checks if the request has completed or done (i.e. callbacks were
* executed). * executed).
@ -204,8 +221,9 @@ namespace Online
bool hasBeenExecuted() const bool hasBeenExecuted() const
{ {
State s = m_state.getAtomic(); State s = m_state.getAtomic();
return s==S_EXECUTED || s==S_DONE; return s == S_EXECUTED || s == S_DONE;
} // hasBeenExecuted } // hasBeenExecuted
// -------------------------------------------------------------------- // --------------------------------------------------------------------
/** Virtual method to check if a request has initialized all needed /** Virtual method to check if a request has initialized all needed
* members to a valid value. */ * members to a valid value. */
@ -226,9 +244,5 @@ namespace Online
} }
}; // class Compare }; // class Compare
}; // class Request }; // class Request
} //namespace Online } //namespace Online
#endif // HEADER_ONLINE_REQUEST_HPP
#endif

View File

@ -111,6 +111,7 @@ namespace Online
pthread_attr_t attr; pthread_attr_t attr;
pthread_attr_init(&attr); pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
// Should be the default, but just in case: // Should be the default, but just in case:
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
//pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); //pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
@ -118,7 +119,7 @@ namespace Online
m_thread_id.setAtomic(new pthread_t()); m_thread_id.setAtomic(new pthread_t());
int error = pthread_create(m_thread_id.getData(), &attr, int error = pthread_create(m_thread_id.getData(), &attr,
&RequestManager::mainLoop, this); &RequestManager::mainLoop, this);
if(error) if (error)
{ {
m_thread_id.lock(); m_thread_id.lock();
delete m_thread_id.getData(); delete m_thread_id.getData();
@ -128,10 +129,11 @@ namespace Online
errno); errno);
} }
pthread_attr_destroy(&attr); pthread_attr_destroy(&attr);
// In case that login id was not saved (or first start of stk), // In case that login id was not saved (or first start of stk),
// current player would not be defined at this stage. // current player would not be defined at this stage.
PlayerProfile *player = PlayerManager::getCurrentPlayer(); PlayerProfile *player = PlayerManager::getCurrentPlayer();
if(player && player->wasOnlineLastTime() && if (player && player->wasOnlineLastTime() &&
!UserConfigParams::m_always_show_login_screen) !UserConfigParams::m_always_show_login_screen)
{ {
PlayerManager::resumeSavedSession(); PlayerManager::resumeSavedSession();
@ -178,6 +180,7 @@ namespace Online
request->setBusy(); request->setBusy();
m_request_queue.lock(); m_request_queue.lock();
m_request_queue.getData().push(request); m_request_queue.getData().push(request);
// Wake up the network http thread // Wake up the network http thread
pthread_cond_signal(&m_cond_request); pthread_cond_signal(&m_cond_request);
m_request_queue.unlock(); m_request_queue.unlock();
@ -197,27 +200,30 @@ namespace Online
me->m_current_request = NULL; me->m_current_request = NULL;
me->m_request_queue.lock(); 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) me->m_request_queue.getData().top()->getType() != Request::RT_QUIT)
{ {
bool empty = me->m_request_queue.getData().empty(); bool empty = me->m_request_queue.getData().empty();
// Wait in cond_wait for a request to arrive. The 'while' is necessary // Wait in cond_wait for a request to arrive. The 'while' is necessary
// since "spurious wakeups from the pthread_cond_wait ... may occur" // since "spurious wakeups from the pthread_cond_wait ... may occur"
// (pthread_cond_wait man page)! // (pthread_cond_wait man page)!
while(empty) while (empty)
{ {
pthread_cond_wait(&me->m_cond_request, me->m_request_queue.getMutex()); pthread_cond_wait(&me->m_cond_request, me->m_request_queue.getMutex());
empty = me->m_request_queue.getData().empty(); empty = me->m_request_queue.getData().empty();
} }
me->m_current_request = me->m_request_queue.getData().top(); me->m_current_request = me->m_request_queue.getData().top();
me->m_request_queue.getData().pop(); 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; break;
me->m_request_queue.unlock(); me->m_request_queue.unlock();
me->m_current_request->execute(); me->m_current_request->execute();
me->addResult(me->m_current_request); me->addResult(me->m_current_request);
me->m_request_queue.lock(); me->m_request_queue.lock();
} // while } // while handle all requests
// Signal that the request manager can now be deleted. // Signal that the request manager can now be deleted.
// We signal this even before cleaning up memory, since there's no // We signal this even before cleaning up memory, since there's no
@ -225,16 +231,18 @@ namespace Online
me->setCanBeDeleted(); me->setCanBeDeleted();
// At this stage we have the lock for m_request_queue // 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(); me->m_request_queue.getData().pop();
// Manage memory can be ignored here, all requests // Manage memory can be ignored here, all requests
// need to be freed. // need to be freed.
delete request; delete request;
} }
me->m_request_queue.unlock(); me->m_request_queue.unlock();
pthread_exit(NULL); pthread_exit(NULL);
return 0; return 0;
} // mainLoop } // mainLoop
@ -259,13 +267,13 @@ namespace Online
{ {
Request * request = NULL; Request * request = NULL;
m_result_queue.lock(); m_result_queue.lock();
if(!m_result_queue.getData().empty()) if (!m_result_queue.getData().empty())
{ {
request = m_result_queue.getData().front(); request = m_result_queue.getData().front();
m_result_queue.getData().pop(); m_result_queue.getData().pop();
} }
m_result_queue.unlock(); m_result_queue.unlock();
if(request != NULL) if (request != NULL)
{ {
request->callback(); request->callback();
if(request->manageMemory()) if(request->manageMemory())
@ -298,7 +306,8 @@ namespace Online
float interval = GAME_POLLING_INTERVAL; float interval = GAME_POLLING_INTERVAL;
if (StateManager::get()->getGameState() == GUIEngine::MENU) if (StateManager::get()->getGameState() == GUIEngine::MENU)
interval = MENU_POLLING_INTERVAL; interval = MENU_POLLING_INTERVAL;
if(m_time_since_poll > interval)
if (m_time_since_poll > interval)
{ {
m_time_since_poll = 0; m_time_since_poll = 0;
PlayerManager::requestOnlinePoll(); PlayerManager::requestOnlinePoll();
@ -306,7 +315,3 @@ namespace Online
} // update } // update
} // namespace Online } // namespace Online

View File

@ -39,10 +39,8 @@
#include <queue> #include <queue>
#include <pthread.h> #include <pthread.h>
namespace Online namespace Online
{ {
/** A class to execute requests in a separate thread. Typically the /** 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 * 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 * receive an answer (e.g. to sign in; or to download an addon). The
@ -86,11 +84,14 @@ namespace Online
* grant permission * grant permission
* IPERM_ALLOWED: STK is allowed to access server. * IPERM_ALLOWED: STK is allowed to access server.
* IPERM_NOT_ALLOWED: STK must not access external servers. */ * IPERM_NOT_ALLOWED: STK must not access external servers. */
enum InternetPermission {IPERM_NOT_ASKED =0, enum InternetPermission
IPERM_ALLOWED =1, {
IPERM_NOT_ALLOWED=2 }; IPERM_NOT_ASKED = 0,
IPERM_ALLOWED = 1,
IPERM_NOT_ALLOWED = 2
};
protected: protected:
/** Time passed since the last poll request. */
float m_time_since_poll; float m_time_since_poll;
/** The current requested being worked on. */ /** The current requested being worked on. */
@ -119,7 +120,7 @@ namespace Online
void addResult(Online::Request *request); void addResult(Online::Request *request);
void handleResultQueue(); void handleResultQueue();
static void *mainLoop(void *obj); static void *mainLoop(void *obj);
RequestManager(); //const std::string &url RequestManager(); //const std::string &url
~RequestManager(); ~RequestManager();
@ -136,12 +137,9 @@ namespace Online
void startNetworkThread(); void startNetworkThread();
void stopNetworkThread(); void stopNetworkThread();
bool getAbort(){ return m_abort.getAtomic(); }; bool getAbort(){ return m_abort.getAtomic(); }
void update(float dt); void update(float dt);
}; //class RequestManager }; //class RequestManager
} // namespace Online } // namespace Online
#endif // request_manager_HPP #endif // request_manager_HPP
/*EOF*/

View File

@ -24,12 +24,14 @@
#include "utils/constants.hpp" #include "utils/constants.hpp"
#include "utils/string_utils.hpp" #include "utils/string_utils.hpp"
namespace Online{ namespace Online
Server::SortOrder Server::m_sort_order=Server::SO_NAME; //FIXME change to some other default {
Server::SortOrder Server::m_sort_order = Server::SO_NAME;
Server::Server(const XMLNode & xml) Server::Server(const XMLNode & xml)
{ {
assert(xml.getName() == "server"); assert(xml.getName() == "server");
m_name = ""; m_name = "";
m_satisfaction_score = 0; m_satisfaction_score = 0;
m_server_id = 0; m_server_id = 0;
@ -45,7 +47,7 @@ namespace Online{
xml.get("max_players", &m_max_players); xml.get("max_players", &m_max_players);
xml.get("current_players", &m_current_players); xml.get("current_players", &m_current_players);
}; // Server(const XML&) } // Server(const XML&)
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
/** /**

View File

@ -31,7 +31,8 @@
class XMLNode; class XMLNode;
namespace Online{ namespace Online
{
/** /**
* \ingroup online * \ingroup online
*/ */
@ -40,54 +41,64 @@ namespace Online{
public: public:
/** Set the sort order used in the comparison function. */ /** Set the sort order used in the comparison function. */
enum SortOrder { SO_SCORE = 1, // Sorted on satisfaction score enum SortOrder
SO_NAME = 2, // Sorted alphabetically by name {
SO_PLAYERS = 4 SO_SCORE = 1, // Sorted on satisfaction score
SO_NAME = 2, // Sorted alphabetically by name
SO_PLAYERS = 4
}; };
protected: protected:
/** The name to be displayed. */ /** The server name to be displayed. */
irr::core::stringw m_name; 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_server_id;
uint32_t m_host_id; uint32_t m_host_id;
/** The maximum number of players that the server supports */
int m_max_players; int m_max_players;
/** The number of players currently on the server */
int m_current_players; int m_current_players;
/** The score/rating given */
float m_satisfaction_score; float m_satisfaction_score;
/** The sort order to be used in the comparison. */ /** The sort order to be used in the comparison. */
static SortOrder m_sort_order; static SortOrder m_sort_order;
Server() {}; Server() {}
public: public:
/** Initialises the object from an XML node. */ /** Initialises the object from an XML node. */
Server(const XMLNode & xml); Server(const XMLNode & xml);
// ------------------------------------------------------------------------
// ------------------------------------------------------------------------
/** Sets the sort order used in the comparison function. It is static, so /** Sets the sort order used in the comparison function. It is static, so
* that each instance can access the sort order. */ * that each instance can access the sort order. */
static void setSortOrder(SortOrder so) { m_sort_order = so; } static void setSortOrder(SortOrder so) { m_sort_order = so; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Returns the name of the server. */ /** Returns the name of the server. */
const irr::core::stringw& getName() const { return m_name; } const irr::core::stringw& getName() const { return m_name; }
const std::string & getLowerCaseName() const { return m_lower_case_name; } const std::string & getLowerCaseName() const { return m_lower_case_name; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
const float getScore() const { return m_satisfaction_score; } const float getScore() const { return m_satisfaction_score; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Returns the ID of this server. */ /** Returns the ID of this server. */
const uint32_t getServerId() const { return m_server_id; } const uint32_t getServerId() const { return m_server_id; }
const uint32_t getHostId() const { return m_host_id; } const uint32_t getHostId() const { return m_host_id; }
const int getMaxPlayers() const { return m_max_players; } const int getMaxPlayers() const { return m_max_players; }
const int getCurrentPlayers() const { return m_current_players; } const int getCurrentPlayers() const { return m_current_players; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
bool filterByWords(const irr::core::stringw words) const; bool filterByWords(const irr::core::stringw words) const;
// ------------------------------------------------------------------------
// ------------------------------------------------------------------------
/** Compares two servers according to the sort order currently defined. /** Compares two servers according to the sort order currently defined.
* \param a The addon to compare this addon to. * \param a The addon to compare this addon to.
*/ */
@ -106,10 +117,10 @@ namespace Online{
return m_current_players < server.getCurrentPlayers(); return m_current_players < server.getCurrentPlayers();
break; break;
} // switch } // switch
return true; return true;
} // operator< } // operator<
}; // Server }; // Server
} // namespace Online } // namespace Online
#endif // HEADER_SERVER_HPP
#endif

View File

@ -16,7 +16,6 @@
// along with this program; if not, write to the Free Software // along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "online/servers_manager.hpp" #include "online/servers_manager.hpp"
#include <string> #include <string>
@ -28,14 +27,15 @@
#define SERVER_REFRESH_INTERVAL 5.0f #define SERVER_REFRESH_INTERVAL 5.0f
namespace Online{ namespace Online
{
static ServersManager* manager_singleton(NULL); static ServersManager* manager_singleton(NULL);
ServersManager* ServersManager::get() ServersManager* ServersManager::get()
{ {
if (manager_singleton == NULL) if (manager_singleton == NULL)
manager_singleton = new ServersManager(); manager_singleton = new ServersManager();
return manager_singleton; return manager_singleton;
} }
@ -46,12 +46,14 @@ namespace Online{
} // deallocate } // deallocate
// ============================================================================ // ============================================================================
ServersManager::ServersManager(){ ServersManager::ServersManager()
{
m_last_load_time.setAtomic(0.0f); m_last_load_time.setAtomic(0.0f);
m_joined_server.setAtomic(NULL); m_joined_server.setAtomic(NULL);
} }
ServersManager::~ServersManager(){ ServersManager::~ServersManager()
{
cleanUpServers(); cleanUpServers();
MutexLocker(m_joined_server); MutexLocker(m_joined_server);
delete m_joined_server.getData(); delete m_joined_server.getData();
@ -75,27 +77,30 @@ namespace Online{
if(StkTime::getRealTime() - m_last_load_time.getAtomic() > SERVER_REFRESH_INTERVAL) if(StkTime::getRealTime() - m_last_load_time.getAtomic() > SERVER_REFRESH_INTERVAL)
{ {
request = new RefreshRequest(); request = new RefreshRequest();
request->setServerURL("client-user.php"); request->setApiURL(API::SERVER_PATH, "get-all");
request->addParameter("action","get_server_list");
if (request_now) if (request_now)
RequestManager::get()->addRequest(request); RequestManager::get()->addRequest(request);
} }
return request; return request;
} }
void ServersManager::refresh(bool success, const XMLNode * input) void ServersManager::refresh(bool success, const XMLNode * input)
{ {
if (success) if (!success)
{ {
const XMLNode * servers_xml = input->getNode("servers"); Log::error("Server Manager", "Could not refresh server list");
cleanUpServers(); return;
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());
} }
//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() void ServersManager::RefreshRequest::callback()
@ -117,7 +122,8 @@ namespace Online{
{ {
MutexLocker(m_joined_server); MutexLocker(m_joined_server);
delete m_joined_server.getData(); delete m_joined_server.getData();
//It's a copy!
// It's a copy!
m_joined_server.getData() = new Server(*getServerByID(id)); m_joined_server.getData() = new Server(*getServerByID(id));
} }
@ -135,6 +141,7 @@ namespace Online{
m_sorted_servers.lock(); m_sorted_servers.lock();
m_sorted_servers.getData().push_back(server); m_sorted_servers.getData().push_back(server);
m_sorted_servers.unlock(); m_sorted_servers.unlock();
m_mapped_servers.lock(); m_mapped_servers.lock();
m_mapped_servers.getData()[server->getServerId()] = server; m_mapped_servers.getData()[server->getServerId()] = server;
m_mapped_servers.unlock(); 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); MutexLocker(m_sorted_servers);
m_sorted_servers.getData().insertionSort(0, sort_desc); m_sorted_servers.getData().insertionSort(0, sort_desc);
} }

View File

@ -26,11 +26,8 @@
#include "online/xml_request.hpp" #include "online/xml_request.hpp"
#include "utils/synchronised.hpp" #include "utils/synchronised.hpp"
namespace Online
{
namespace Online {
/** /**
* \brief * \brief
* \ingroup online * \ingroup online
@ -51,8 +48,10 @@ namespace Online {
~ServersManager(); ~ServersManager();
/** Sorted vector of servers */ /** Sorted vector of servers */
Synchronised<PtrVector<Server> > m_sorted_servers; Synchronised<PtrVector<Server> > m_sorted_servers;
/** Maps server id's to the same servers*/ /** Maps server id's to the same servers*/
Synchronised<std::map<uint32_t, Server*> > m_mapped_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 */ /** This is a pointer to a copy of the server, the moment it got joined */
Synchronised<Server *> m_joined_server; Synchronised<Server *> m_joined_server;
@ -74,14 +73,10 @@ namespace Online {
const Server * getServerBySort (int index) const; const Server * getServerBySort (int index) const;
void sort(bool sort_desc); void sort(bool sort_desc);
Server * getJoinedServer() const; Server * getJoinedServer() const;
//Returns the best server to join
// Returns the best server to join
const Server * getQuickPlay() const; const Server * getQuickPlay() const;
}; // class ServersManager }; // class ServersManager
} // namespace Online } // namespace Online
#endif // HEADER_SERVERS_MANAGER_HPP
#endif
/*EOF*/

View File

@ -24,15 +24,12 @@
#ifdef WIN32 #ifdef WIN32
# include <winsock2.h> # include <winsock2.h>
#endif #endif
#include <curl/curl.h> #include <curl/curl.h>
#include <assert.h> #include <assert.h>
namespace Online namespace Online
{ {
/** Creates a HTTP(S) request that will automatically parse the answer into /** Creates a HTTP(S) request that will automatically parse the answer into
* a XML structure. * a XML structure.
* \param manage_memory whether or not the RequestManager should take care of * \param manage_memory whether or not the RequestManager should take care of
@ -61,22 +58,26 @@ namespace Online
void XMLRequest::afterOperation() void XMLRequest::afterOperation()
{ {
m_xml_data = file_manager->createXMLTreeFromString(getData()); m_xml_data = file_manager->createXMLTreeFromString(getData());
if(hadDownloadError()) if (hadDownloadError())
{
Log::error("XMLRequest::afterOperation", Log::error("XMLRequest::afterOperation",
"curl_easy_perform() failed: %s", "curl_easy_perform() failed: %s",
getDownloadErrorMessage()); getDownloadErrorMessage());
}
m_success = false; m_success = false;
std::string rec_success; 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); m_xml_data->get("info", &m_info);
} }
else else
{
m_info = _("Unable to connect to the server. Check your internet " m_info = _("Unable to connect to the server. Check your internet "
"connection or try again later."); "connection or try again later.");
}
HTTPRequest::afterOperation(); HTTPRequest::afterOperation();
} // afterOperation } // afterOperation
} // namespace Online } // namespace Online

View File

@ -53,7 +53,7 @@ namespace Online
virtual void afterOperation() OVERRIDE; virtual void afterOperation() OVERRIDE;
public : public :
XMLRequest(bool manage_memory = false, int priority = 1); XMLRequest(bool manage_memory = false, int priority = 1);
virtual ~XMLRequest(); virtual ~XMLRequest();
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
@ -73,7 +73,7 @@ namespace Online
* \pre request had to be executed. * \pre request had to be executed.
* \return get the info from the request reply * \return get the info from the request reply
*/ */
const irr::core::stringw & getInfo() const const irr::core::stringw & getInfo() const
{ {
assert(hasBeenExecuted()); assert(hasBeenExecuted());
return m_info; return m_info;
@ -90,8 +90,5 @@ namespace Online
} // isSuccess } // isSuccess
}; // class XMLRequest }; // class XMLRequest
} //namespace Online } //namespace Online
#endif // HEADER_XML_REQUEST_HPP
#endif

View File

@ -139,7 +139,7 @@ void CreateServerScreen::serverCreationRequest()
{ {
m_server_creation_request = new 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("name", name);
m_server_creation_request->addParameter("max_players", max_players); m_server_creation_request->addParameter("max_players", max_players);
m_server_creation_request->queue(); m_server_creation_request->queue();

View File

@ -38,8 +38,7 @@ using namespace Online;
/** Creates a modal dialog with given percentage of screen width and height /** Creates a modal dialog with given percentage of screen width and height
*/ */
ChangePasswordDialog::ChangePasswordDialog() ChangePasswordDialog::ChangePasswordDialog() : ModalDialog(0.8f, 0.7f)
: ModalDialog(0.8f,0.7f)
{ {
m_self_destroy = false; m_self_destroy = false;
m_success = false; m_success = false;
@ -49,15 +48,15 @@ ChangePasswordDialog::ChangePasswordDialog()
m_current_password_widget = getWidget<TextBoxWidget>("current_password"); m_current_password_widget = getWidget<TextBoxWidget>("current_password");
assert(m_current_password_widget != NULL); assert(m_current_password_widget != NULL);
m_current_password_widget->setFocusForPlayer(PLAYER_ID_GAME_MASTER); 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"); m_new_password1_widget = getWidget<TextBoxWidget>("new_password1");
assert(m_new_password1_widget != NULL); 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"); m_new_password2_widget = getWidget<TextBoxWidget>("new_password2");
assert(m_new_password2_widget != NULL); 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"); m_info_widget = getWidget<LabelWidget>("info");
assert(m_info_widget != NULL); assert(m_info_widget != NULL);
@ -71,7 +70,6 @@ ChangePasswordDialog::ChangePasswordDialog()
} // ChangePasswordDialog } // ChangePasswordDialog
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
ChangePasswordDialog::~ChangePasswordDialog() ChangePasswordDialog::~ChangePasswordDialog()
{ {
} // ~ChangePasswordDialog } // ~ChangePasswordDialog
@ -93,6 +91,7 @@ void ChangePasswordDialog::changePassword(const stringw &current_password,
virtual void callback() virtual void callback()
{ {
if (!GUIEngine::ModalDialog::isADialogActive()) return; if (!GUIEngine::ModalDialog::isADialogActive()) return;
ChangePasswordDialog * dialog = ChangePasswordDialog * dialog =
dynamic_cast<ChangePasswordDialog*>(GUIEngine::ModalDialog dynamic_cast<ChangePasswordDialog*>(GUIEngine::ModalDialog
::getCurrent()); ::getCurrent());
@ -111,8 +110,9 @@ void ChangePasswordDialog::changePassword(const stringw &current_password,
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
ChangePasswordRequest * request = new ChangePasswordRequest(); ChangePasswordRequest * request = new ChangePasswordRequest();
PlayerManager::setUserDetails(request, "change_password"); PlayerManager::setUserDetails(request, "change-password");
request->addParameter("current", current_password); request->addParameter("current", current_password);
// The server code expects two passwords (and verifies again that they // The server code expects two passwords (and verifies again that they
// are identical), so send the passwod twice. // are identical), so send the passwod twice.
request->addParameter("new1", new_password); request->addParameter("new1", new_password);
@ -126,6 +126,7 @@ void ChangePasswordDialog::submit()
const stringw current_password = m_current_password_widget->getText().trim(); const stringw current_password = m_current_password_widget->getText().trim();
const stringw new_password1 = m_new_password1_widget->getText().trim(); const stringw new_password1 = m_new_password1_widget->getText().trim();
const stringw new_password2 = m_new_password2_widget->getText().trim(); const stringw new_password2 = m_new_password2_widget->getText().trim();
if (current_password.size() < 8 || current_password.size() > 30) if (current_password.size() < 8 || current_password.size() > 30)
{ {
sfx_manager->quickSound("anvil"); sfx_manager->quickSound("anvil");
@ -149,6 +150,7 @@ void ChangePasswordDialog::submit()
{ {
m_options_widget->setDeactivated(); m_options_widget->setDeactivated();
m_info_widget->setDefaultColor(); m_info_widget->setDefaultColor();
// We don't need to use password 2 anymore, it was already confirmed // We don't need to use password 2 anymore, it was already confirmed
// that both passwords are identical. // that both passwords are identical.
changePassword(current_password, new_password1); changePassword(current_password, new_password1);
@ -159,42 +161,45 @@ void ChangePasswordDialog::submit()
GUIEngine::EventPropagation GUIEngine::EventPropagation
ChangePasswordDialog::processEvent(const std::string& eventSource) ChangePasswordDialog::processEvent(const std::string& eventSource)
{ {
if (eventSource == m_options_widget->m_properties[PROP_ID]) if (eventSource == m_options_widget->m_properties[PROP_ID])
{ {
const std::string& selection = const std::string& selection =
m_options_widget->getSelectionIDString(PLAYER_ID_GAME_MASTER); m_options_widget->getSelectionIDString(PLAYER_ID_GAME_MASTER);
if (selection == m_cancel_widget->m_properties[PROP_ID]) if (selection == m_cancel_widget->m_properties[PROP_ID])
{ {
m_self_destroy = true; m_self_destroy = true;
return GUIEngine::EVENT_BLOCK; return GUIEngine::EVENT_BLOCK;
} }
else if(selection == m_submit_widget->m_properties[PROP_ID]) else if(selection == m_submit_widget->m_properties[PROP_ID])
{ {
submit(); submit();
return GUIEngine::EVENT_BLOCK; return GUIEngine::EVENT_BLOCK;
} }
} }
return GUIEngine::EVENT_LET; return GUIEngine::EVENT_LET;
} // processEvent } // processEvent
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
void ChangePasswordDialog::onEnterPressedInternal() void ChangePasswordDialog::onEnterPressedInternal()
{ {
const int playerID = PLAYER_ID_GAME_MASTER; const int playerID = PLAYER_ID_GAME_MASTER;
if (GUIEngine::isFocusedForPlayer(m_options_widget, playerID)) if (GUIEngine::isFocusedForPlayer(m_options_widget, playerID))
return; return;
if (m_submit_widget->isActivated()) if (m_submit_widget->isActivated())
submit(); submit();
} // onEnterPressedInternal } // onEnterPressedInternal
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
bool ChangePasswordDialog::onEscapePressed() bool ChangePasswordDialog::onEscapePressed()
{ {
if (m_cancel_widget->isActivated()) if (m_cancel_widget->isActivated())
m_self_destroy = true; m_self_destroy = true;
return false; return false;
} // onEscapePressed } // onEscapePressed
@ -222,12 +227,15 @@ void ChangePasswordDialog::error(const irr::core::stringw & error)
} // error } // error
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
void ChangePasswordDialog::onUpdate(float dt) void ChangePasswordDialog::onUpdate(float dt)
{ {
if(!m_options_widget->isActivated()) 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 // It's unsafe to delete from inside the event handler so we do it here
if (m_self_destroy) if (m_self_destroy)

View File

@ -125,9 +125,11 @@ void RecoveryDialog::processInput()
{ {
m_info_widget->setDefaultColor(); m_info_widget->setDefaultColor();
m_options_widget->setDeactivated(); m_options_widget->setDeactivated();
m_recovery_request = new XMLRequest(); m_recovery_request = new XMLRequest();
// This function also works when the current user is not logged in // 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("username", username);
m_recovery_request->addParameter("email", email ); m_recovery_request->addParameter("email", email );
m_recovery_request->queue(); m_recovery_request->queue();
@ -142,10 +144,13 @@ GUIEngine::EventPropagation
{ {
std::string selection; std::string selection;
if (eventSource == m_options_widget->m_properties[PROP_ID]) 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 else
{
selection = eventSource; selection = eventSource;
}
if (selection == m_cancel_widget->m_properties[PROP_ID]) if (selection == m_cancel_widget->m_properties[PROP_ID])
{ {
@ -165,9 +170,9 @@ GUIEngine::EventPropagation
*/ */
void RecoveryDialog::onEnterPressedInternal() void RecoveryDialog::onEnterPressedInternal()
{ {
if (GUIEngine::isFocusedForPlayer(m_options_widget, PLAYER_ID_GAME_MASTER)) if (GUIEngine::isFocusedForPlayer(m_options_widget, PLAYER_ID_GAME_MASTER))
return; return;
if (m_submit_widget->isActivated()) if (m_submit_widget->isActivated())
processInput(); processInput();
} }
@ -194,15 +199,19 @@ void RecoveryDialog::onUpdate(float dt)
m_info_widget->setText(m_recovery_request->getInfo(), false); m_info_widget->setText(m_recovery_request->getInfo(), false);
m_options_widget->setActivated(); m_options_widget->setActivated();
} }
delete m_recovery_request; delete m_recovery_request;
m_recovery_request = NULL; m_recovery_request = NULL;
} }
else else
{ {
m_info_widget->setText(StringUtils::loadingDots(_("Validating info")), m_info_widget->setText(
false); StringUtils::loadingDots(_("Validating info")),
false
);
} }
} }
// It's unsafe to delete from inside the event handler so we do it here // It's unsafe to delete from inside the event handler so we do it here
if (m_self_destroy) if (m_self_destroy)
ModalDialog::dismiss(); ModalDialog::dismiss();

View File

@ -78,6 +78,7 @@ EventPropagation RegistrationDialog::processEvent(const std::string& event_sourc
assert(r); assert(r);
r->acceptTerms(); r->acceptTerms();
} }
// If it's not accept, it's cancel - anyway, close dialog // If it's not accept, it's cancel - anyway, close dialog
ModalDialog::dismiss(); ModalDialog::dismiss();
return EVENT_BLOCK; return EVENT_BLOCK;

View File

@ -144,9 +144,10 @@ void UserInfoDialog::sendFriendRequest()
*/ */
virtual void callback() virtual void callback()
{ {
core::stringw info_text("");
uint32_t id(0); uint32_t id(0);
getXMLData()->get("friendid", &id); getXMLData()->get("friendid", &id);
core::stringw info_text("");
if (isSuccess()) if (isSuccess())
{ {
PlayerManager::getCurrentOnlineProfile()->addFriend(id); PlayerManager::getCurrentOnlineProfile()->addFriend(id);
@ -158,7 +159,10 @@ void UserInfoDialog::sendFriendRequest()
info_text = _("Friend request send!"); info_text = _("Friend request send!");
} }
else else
{
info_text = getInfo(); info_text = getInfo();
}
UserInfoDialog *dialog = new UserInfoDialog(id, info_text, UserInfoDialog *dialog = new UserInfoDialog(id, info_text,
!isSuccess(), true); !isSuccess(), true);
GUIEngine::DialogQueue::get()->pushDialog(dialog, true); GUIEngine::DialogQueue::get()->pushDialog(dialog, true);
@ -196,8 +200,9 @@ void UserInfoDialog::acceptFriendRequest()
virtual void callback() virtual void callback()
{ {
uint32_t id(0); uint32_t id(0);
getXMLData()->get("friendid", &id);
core::stringw info_text(""); core::stringw info_text("");
getXMLData()->get("friendid", &id);
if (isSuccess()) if (isSuccess())
{ {
OnlineProfile * profile = OnlineProfile * profile =
@ -211,7 +216,10 @@ void UserInfoDialog::acceptFriendRequest()
info_text = _("Friend request accepted!"); info_text = _("Friend request accepted!");
} }
else else
{
info_text = getInfo(); info_text = getInfo();
}
GUIEngine::DialogQueue::get()->pushDialog( GUIEngine::DialogQueue::get()->pushDialog(
new UserInfoDialog(id, info_text, !isSuccess(), true), true); new UserInfoDialog(id, info_text, !isSuccess(), true), true);
@ -225,6 +233,7 @@ void UserInfoDialog::acceptFriendRequest()
PlayerManager::setUserDetails(request, "accept-friend-request"); PlayerManager::setUserDetails(request, "accept-friend-request");
request->addParameter("friendid", m_online_profile->getID()); request->addParameter("friendid", m_online_profile->getID());
request->queue(); request->queue();
m_processing = true; m_processing = true;
m_options_widget->setDeactivated(); m_options_widget->setDeactivated();
} // acceptFriendRequest } // acceptFriendRequest
@ -246,8 +255,9 @@ void UserInfoDialog::declineFriendRequest()
virtual void callback() virtual void callback()
{ {
uint32_t id(0); uint32_t id(0);
getXMLData()->get("friendid", &id);
core::stringw info_text(""); core::stringw info_text("");
getXMLData()->get("friendid", &id);
if (isSuccess()) if (isSuccess())
{ {
PlayerManager::getCurrentOnlineProfile()->removeFriend(id); PlayerManager::getCurrentOnlineProfile()->removeFriend(id);
@ -258,7 +268,10 @@ void UserInfoDialog::declineFriendRequest()
info_text = _("Friend request declined!"); info_text = _("Friend request declined!");
} }
else else
{
info_text = getInfo(); info_text = getInfo();
}
GUIEngine::DialogQueue::get()->pushDialog( GUIEngine::DialogQueue::get()->pushDialog(
new UserInfoDialog(id, info_text, !isSuccess(), new UserInfoDialog(id, info_text, !isSuccess(),
true), true); true), true);
@ -286,9 +299,11 @@ void UserInfoDialog::removeExistingFriend()
class RemoveFriendRequest : public XMLRequest class RemoveFriendRequest : public XMLRequest
{ {
unsigned int m_id; unsigned int m_id;
virtual void callback() virtual void callback()
{ {
core::stringw info_text(""); core::stringw info_text("");
if (isSuccess()) if (isSuccess())
{ {
PlayerManager::getCurrentOnlineProfile()->removeFriend(m_id); PlayerManager::getCurrentOnlineProfile()->removeFriend(m_id);
@ -299,7 +314,9 @@ void UserInfoDialog::removeExistingFriend()
info_text = _("Friend removed!"); info_text = _("Friend removed!");
} }
else else
{
info_text = getInfo(); info_text = getInfo();
}
UserInfoDialog *info = new UserInfoDialog(m_id, info_text, UserInfoDialog *info = new UserInfoDialog(m_id, info_text,
!isSuccess(), true); !isSuccess(), true);
@ -335,8 +352,9 @@ void UserInfoDialog::removePendingFriend()
virtual void callback() virtual void callback()
{ {
uint32_t id(0); uint32_t id(0);
getXMLData()->get("friendid", &id);
core::stringw info_text(""); core::stringw info_text("");
getXMLData()->get("friendid", &id);
if (isSuccess()) if (isSuccess())
{ {
PlayerManager::getCurrentOnlineProfile()->removeFriend(id); PlayerManager::getCurrentOnlineProfile()->removeFriend(id);
@ -347,8 +365,9 @@ void UserInfoDialog::removePendingFriend()
info_text = _("Friend request cancelled!"); info_text = _("Friend request cancelled!");
} }
else else
{
info_text = getInfo(); info_text = getInfo();
}
UserInfoDialog *dia = new UserInfoDialog(id, info_text, UserInfoDialog *dia = new UserInfoDialog(id, info_text,
!isSuccess(), true); !isSuccess(), true);
GUIEngine::DialogQueue::get()->pushDialog(dia, true); GUIEngine::DialogQueue::get()->pushDialog(dia, true);

View File

@ -48,14 +48,16 @@ VoteDialog::VoteDialog(const std::string & addon_id)
m_rating_widget = getWidget<RatingBarWidget>("rating"); m_rating_widget = getWidget<RatingBarWidget>("rating");
assert(m_rating_widget != NULL); assert(m_rating_widget != NULL);
m_rating_widget->setRating(0); m_rating_widget->setRating(0);
m_rating_widget->allowVoting(); m_rating_widget->allowVoting();
m_options_widget = getWidget<RibbonWidget>("options"); m_options_widget = getWidget<RibbonWidget>("options");
assert(m_options_widget != NULL); assert(m_options_widget != NULL);
m_cancel_widget = getWidget<IconButtonWidget>("cancel"); m_cancel_widget = getWidget<IconButtonWidget>("cancel");
assert(m_cancel_widget != NULL); 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(); m_fetch_vote_request = new XMLRequest();
PlayerManager::setUserDetails(m_fetch_vote_request, "get-addon-vote"); PlayerManager::setUserDetails(m_fetch_vote_request, "get-addon-vote");
@ -102,8 +104,9 @@ void VoteDialog::sendVote()
if (isSuccess()) if (isSuccess())
{ {
std::string addon_id; std::string addon_id;
getXMLData()->get("addon-id", &addon_id);
float average; float average;
getXMLData()->get("addon-id", &addon_id);
getXMLData()->get("new-average", &average); getXMLData()->get("new-average", &average);
addons_manager->getAddon(Addon::createAddonId(addon_id)) addons_manager->getAddon(Addon::createAddonId(addon_id))
->setRating(average); ->setRating(average);
@ -112,10 +115,8 @@ void VoteDialog::sendVote()
public: public:
SetAddonVoteRequest() : XMLRequest() {} SetAddonVoteRequest() : XMLRequest() {}
}; // SetAddonVoteRequest }; // SetAddonVoteRequest
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
m_perform_vote_request = new SetAddonVoteRequest(); m_perform_vote_request = new SetAddonVoteRequest();
PlayerManager::setUserDetails(m_perform_vote_request, "set-addon-vote"); PlayerManager::setUserDetails(m_perform_vote_request, "set-addon-vote");
m_perform_vote_request->addParameter("addonid", m_addon_id.substr(6)); 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 = const std::string& selection =
m_options_widget->getSelectionIDString(PLAYER_ID_GAME_MASTER); m_options_widget->getSelectionIDString(PLAYER_ID_GAME_MASTER);
if (selection == m_cancel_widget->m_properties[PROP_ID]) if (selection == m_cancel_widget->m_properties[PROP_ID])
{ {
m_self_destroy = true; m_self_destroy = true;
return GUIEngine::EVENT_BLOCK; return GUIEngine::EVENT_BLOCK;
} }
} }
return GUIEngine::EVENT_LET; return GUIEngine::EVENT_LET;
} // processEvent } // processEvent
@ -163,16 +167,21 @@ void VoteDialog::updateFetchVote()
if (!m_fetch_vote_request->isDone()) if (!m_fetch_vote_request->isDone())
{ {
// request still pending // request still pending
m_info_widget->setText(StringUtils::loadingDots(_("Fetching last vote")), m_info_widget->setText(
false ); StringUtils::loadingDots(_("Fetching last vote")),
false
);
return; return;
} // !isDone } // !isDone
if (m_fetch_vote_request->isSuccess()) if (m_fetch_vote_request->isSuccess())
{ {
m_info_widget->setDefaultColor();
std::string voted(""); std::string voted("");
m_info_widget->setDefaultColor();
m_fetch_vote_request->getXMLData()->get("voted", &voted); m_fetch_vote_request->getXMLData()->get("voted", &voted);
if (voted == "yes") if (voted == "yes")
{ {
float rating; float rating;

View File

@ -168,36 +168,36 @@ void OnlineScreen::onUpdate(float delta)
void OnlineScreen::doQuickPlay() void OnlineScreen::doQuickPlay()
{ {
// Refresh server list. // Refresh server list.
HTTPRequest* request = ServersManager::get()->refreshRequest(false); HTTPRequest* refresh_request = ServersManager::get()->refreshRequest(false);
if (request != NULL) // consider request done if (refresh_request != NULL) // consider request done
{ {
request->executeNow(); refresh_request->executeNow();
delete request; delete refresh_request;
} }
else else
{ {
Log::error("OnlineScreen", "Could not get the server list."); Log::error("OnlineScreen", "Could not get the server list.");
return; return;
} }
// select first one // select first one
const Server * server = ServersManager::get()->getQuickPlay(); const Server *server = ServersManager::get()->getQuickPlay();
// do a join request
XMLRequest *request2 = new RequestConnection::ServerJoinRequest(); XMLRequest *join_request = new RequestConnection::ServerJoinRequest();
if (!request2) if (!join_request)
{ {
sfx_manager->quickSound("anvil"); sfx_manager->quickSound("anvil");
return; return;
} }
PlayerManager::setUserDetails(request2, "request-connection"); PlayerManager::setUserDetails(join_request, "request-connection", Online::API::SERVER_PATH);
request2->setServerURL("address-management.php"); join_request->addParameter("server_id", server->getServerId());
request2->addParameter("server_id", server->getServerId());
request2->executeNow(); join_request->executeNow();
if (request2->isSuccess()) if (join_request->isSuccess())
{ {
delete request2; delete join_request;
StateManager::get()->pushScreen(NetworkingLobby::getInstance()); StateManager::get()->pushScreen(NetworkingLobby::getInstance());
ConnectToServer *cts = new ConnectToServer(server->getServerId(), ConnectToServer *cts = new ConnectToServer(server->getServerId(),
server->getHostId()); server->getHostId());

View File

@ -139,25 +139,30 @@ void OnlineUserSearch::parseResult(const XMLNode * input)
{ {
m_users.clear(); m_users.clear();
const XMLNode * users_xml = input->getNode("users"); const XMLNode * users_xml = input->getNode("users");
// Try to reserve enough cache space for all found entries. // Try to reserve enough cache space for all found entries.
unsigned int n = ProfileManager::get() unsigned int n = ProfileManager::get()
->guaranteeCacheSize(users_xml->getNumNodes()); ->guaranteeCacheSize(users_xml->getNumNodes());
if (n >= users_xml->getNumNodes()) if (n >= users_xml->getNumNodes())
{
n = users_xml->getNumNodes(); n = users_xml->getNumNodes();
}
else else
{ {
Log::warn("OnlineSearch", Log::warn("OnlineSearch",
"Too many results found, only %d will be displayed.", n); "Too many results found, only %d will be displayed.", n);
} }
for (unsigned int i = 0; i < n; i++) for (unsigned int i = 0; i < n; i++)
{ {
OnlineProfile * profile = new OnlineProfile(users_xml->getNode(i)); OnlineProfile * profile = new OnlineProfile(users_xml->getNode(i));
// The id must be pushed before adding it to the cache, since // The id must be pushed before adding it to the cache, since
// the cache might merge the new data with an existing entry // the cache might merge the new data with an existing entry
m_users.push_back(profile->getID()); m_users.push_back(profile->getID());
ProfileManager::get()->addToCache(profile); ProfileManager::get()->addToCache(profile);
} } // for i = 0 ... number of display users
} // parseResult } // parseResult
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@ -166,17 +171,19 @@ void OnlineUserSearch::parseResult(const XMLNode * input)
void OnlineUserSearch::showList() void OnlineUserSearch::showList()
{ {
m_user_list_widget->clear(); 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; std::vector<GUIEngine::ListWidget::ListCell> row;
OnlineProfile * profile = ProfileManager::get()->getProfileByID(m_users[i]); OnlineProfile * profile = ProfileManager::get()->getProfileByID(m_users[i]);
// This could still happen if something pushed results out of the cache. // This could still happen if something pushed results out of the cache.
if (!profile) if (!profile)
{ {
Log::warn("OnlineSearch", "User %d not in cache anymore, ignored.", Log::warn("OnlineSearch", "User %d not in cache anymore, ignored.", m_users[i]);
m_users[i]);
continue; continue;
} }
row.push_back(GUIEngine::ListWidget::ListCell(profile->getUserName(),-1,3)); row.push_back(GUIEngine::ListWidget::ListCell(profile->getUserName(),-1,3));
m_user_list_widget->addItem("user", row); m_user_list_widget->addItem("user", row);
} }
@ -267,6 +274,7 @@ void OnlineUserSearch::onUpdate(float dt)
sfx_manager->quickSound( "anvil" ); sfx_manager->quickSound( "anvil" );
new MessageDialog(m_search_request->getInfo()); new MessageDialog(m_search_request->getInfo());
} }
delete m_search_request; delete m_search_request;
m_search_request = NULL; m_search_request = NULL;
m_back_widget->setActivated(); m_back_widget->setActivated();

View File

@ -72,9 +72,9 @@ void RegisterScreen::init()
getWidget<TextBoxWidget>("local_username")->setText(username); getWidget<TextBoxWidget>("local_username")->setText(username);
TextBoxWidget *password_widget = getWidget<TextBoxWidget>("password"); TextBoxWidget *password_widget = getWidget<TextBoxWidget>("password");
password_widget->setPasswordBox(true,L'*'); password_widget->setPasswordBox(true, L'*');
password_widget = getWidget<TextBoxWidget>("password_confirm"); password_widget = getWidget<TextBoxWidget>("password_confirm");
password_widget->setPasswordBox(true,L'*'); password_widget->setPasswordBox(true, L'*');
m_info_widget = getWidget<LabelWidget>("info"); m_info_widget = getWidget<LabelWidget>("info");
assert(m_info_widget); assert(m_info_widget);
@ -129,6 +129,7 @@ void RegisterScreen::makeEntryFieldsVisible(bool online)
getWidget<LabelWidget>("label_online")->setVisible(false); getWidget<LabelWidget>("label_online")->setVisible(false);
online = false; online = false;
} }
getWidget<TextBoxWidget>("username")->setVisible(online); getWidget<TextBoxWidget>("username")->setVisible(online);
getWidget<LabelWidget >("label_username")->setVisible(online); getWidget<LabelWidget >("label_username")->setVisible(online);
getWidget<TextBoxWidget>("password")->setVisible(online); getWidget<TextBoxWidget>("password")->setVisible(online);
@ -147,7 +148,7 @@ void RegisterScreen::makeEntryFieldsVisible(bool online)
*/ */
void RegisterScreen::handleLocalName(const stringw &local_name) void RegisterScreen::handleLocalName(const stringw &local_name)
{ {
if (local_name.size()==0) if (local_name.size() == 0)
return; return;
// If a local player with that name does not exist, create one // 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 password_confirm= getWidget<TextBoxWidget>("password_confirm")->getText().trim();
core::stringw email = getWidget<TextBoxWidget>("email")->getText().trim(); core::stringw email = getWidget<TextBoxWidget>("email")->getText().trim();
m_signup_request = new XMLRequest(); m_signup_request = new XMLRequest();
m_signup_request->setServerURL("client-user.php"); m_signup_request->setApiURL(API::USER_PATH, "register");
m_signup_request->addParameter("action", "register" );
m_signup_request->addParameter("username", username ); m_signup_request->addParameter("username", username );
m_signup_request->addParameter("password", password ); m_signup_request->addParameter("password", password );
m_signup_request->addParameter("password_confirm", password_confirm); m_signup_request->addParameter("password_confirm", password_confirm);