Started to add support for downloading news from the addon server

at a specified interval only (e.g. only download every 2nd day).
Not fully working yet, might not work on linux/mac atm.


git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@8030 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
hikerstk 2011-03-23 03:57:49 +00:00
parent f8ff755340
commit 954b420446
8 changed files with 228 additions and 7 deletions

View File

@ -431,6 +431,7 @@ supertuxkart_SOURCES = \
utils/random_generator.hpp \
utils/string_utils.cpp \
utils/string_utils.hpp \
utils/time.hpp \
utils/translation.cpp \
utils/translation.hpp \
utils/vec3.cpp \

View File

@ -23,8 +23,10 @@
#include <string>
#if defined(WIN32) && !defined(__CYGWIN__)
# include <windows.h>
# define isnan _isnan
#else
# include <sys/time.h>
# include <math.h>
#endif
@ -34,6 +36,7 @@
#include "states_screens/addons_screen.hpp"
#include "states_screens/main_menu_screen.hpp"
#include "utils/string_utils.hpp"
#include "utils/time.hpp"
#if defined(WIN32) && !defined(__CYGWIN__)
// Use Sleep, which takes time in msecs. It must be defined after the
@ -79,13 +82,29 @@ void *NetworkHttp::mainLoop(void *obj)
{
NetworkHttp *me=(NetworkHttp*)obj;
// Initialise the online portion of the addons manager.
if(UserConfigParams::m_verbosity>=3)
// The news message must be updated if either it has never been updated,
// or if the time of the last update was more than news_frequency ago.
bool download = UserConfigParams::m_news_last_updated==0 ||
UserConfigParams::m_news_last_updated
+UserConfigParams::m_news_frequency
> Time::getTimeSinceEpoch();
if(!download)
{
// If there is no old news message file, force a new download
std::string xml_file = file_manager->getAddonsFile("news.xml");
if(xml_file=="")
download=true;
}
// Initialise the online portion of the addons manager.
if(download && UserConfigParams::m_verbosity>=3)
printf("[addons] Downloading list.\n");
if(me->downloadFileSynchron("news.xml"))
if(!download || me->downloadFileSynchron("news.xml"))
{
std::string xml_file = file_manager->getAddonsFile("news.xml");
if(download)
UserConfigParams::m_news_last_updated = Time::getTimeSinceEpoch();
const XMLNode *xml = new XMLNode(xml_file);
me->checkNewServer(xml);
me->updateNews(xml);

View File

@ -170,6 +170,71 @@ void IntUserConfigParam::findYourDataInAnAttributeOf(const XMLNode* node)
// ---------------------------------------------------------------------------------------
TimeUserConfigParam::TimeUserConfigParam(Time::TimeType default_value,
const char* param_name,
const char* comment)
{
m_value = default_value;
m_default_value = default_value;
this->paramName = param_name;
all_params.push_back(this);
if(comment != NULL) this->comment = comment;
}
TimeUserConfigParam::TimeUserConfigParam(Time::TimeType defaultValue,
const char* paramName,
GroupUserConfigParam* group,
const char* comment)
{
m_value = defaultValue;
m_default_value = defaultValue;
this->paramName = paramName;
group->addChild(this);
if(comment != NULL) this->comment = comment;
}
void TimeUserConfigParam::write(XMLWriter& stream) const
{
if(comment.size() > 0) stream << L" <!-- " << comment.c_str() << L" -->\n";
std::ostringstream o;
o<<m_value;
stream << L" <" << paramName.c_str() << L" value=\""
<< core::stringw(o.str().c_str()) << L"\" />\n\n";
}
irr::core::stringw TimeUserConfigParam::toString() const
{
// irrString does not have a += with a 64-bit int type, so
// we can't use an irrlicht's stringw directly. Since it's only a
// number, we can use std::string, and convert to stringw
std::string tmp;
std::ostringstream o;
o<<m_value;
return core::stringw(o.str().c_str());
}
void TimeUserConfigParam::findYourDataInAChildOf(const XMLNode* node)
{
const XMLNode* child = node->getNode( paramName );
if(child == NULL)
{
//std::cout << "Couldn't find int parameter " << paramName << std::endl;
return;
}
child->get( "value", &m_value );
//std::cout << "read int " << paramName << ", value=" << value << std::endl;
}
void TimeUserConfigParam::findYourDataInAnAttributeOf(const XMLNode* node)
{
node->get( paramName, &m_value );
}
// ---------------------------------------------------------------------------------------
StringUserConfigParam::StringUserConfigParam(const char* defaultValue, const char* paramName, const char* comment)
{

View File

@ -53,6 +53,7 @@ using irr::core::stringw;
#include "utils/constants.hpp"
#include "utils/no_copy.hpp"
#include "utils/ptr_vector.hpp"
#include "utils/time.hpp"
class XMLNode;
class XMLWriter;
@ -110,6 +111,32 @@ public:
int& operator=(const IntUserConfigParam& v) { m_value = (int)v; return m_value; }
};
class TimeUserConfigParam : public UserConfigParam
{
Time::TimeType m_value;
Time::TimeType m_default_value;
public:
TimeUserConfigParam(Time::TimeType defaultValue, const char* paramName,
const char* comment = NULL);
TimeUserConfigParam(Time::TimeType defaultValue, const char* paramName,
GroupUserConfigParam* group, const char* comment=NULL);
void write(XMLWriter& stream) const;
void findYourDataInAChildOf(const XMLNode* node);
void findYourDataInAnAttributeOf(const XMLNode* node);
irr::core::stringw toString() const;
void revertToDefaults() { m_value = m_default_value; }
operator Time::TimeType() const { return m_value; }
Time::TimeType& operator=(const Time::TimeType& v)
{ m_value = v; return m_value; }
Time::TimeType& operator=(const TimeUserConfigParam& v)
{ m_value = (int)v; return m_value; }
};
class StringUserConfigParam : public UserConfigParam
{
std::string m_value;
@ -384,8 +411,26 @@ namespace UserConfigParams
PARAM_PREFIX StringUserConfigParam m_skin_file
PARAM_DEFAULT( StringUserConfigParam("Peach.stkskin", "skin_file", "Name of the skin to use") );
// ---- Addon server related entries
PARAM_PREFIX GroupUserConfigParam m_addon_group
PARAM_DEFAULT( GroupUserConfigParam("AddonAndNews",
"Addon and news related settings") );
PARAM_PREFIX StringUserConfigParam m_server_addons
PARAM_DEFAULT( StringUserConfigParam("http://download.tuxfamily.org/stkaddons/0.7/", "server_addons", "The server used for addon.") );
PARAM_DEFAULT( StringUserConfigParam("http://stkaddons.tuxfamily.org/dl/xml",
"server_addons",
&m_addon_group,
"The server used for addon.") );
PARAM_PREFIX TimeUserConfigParam m_news_last_updated
PARAM_DEFAULT( TimeUserConfigParam(0, "last_updated",
&m_addon_group,
"Time news was updated last.") );
PARAM_PREFIX IntUserConfigParam m_news_frequency
PARAM_DEFAULT( IntUserConfigParam(0, "news_frequency",
&m_addon_group,
"How often news should be updated.") );
PARAM_PREFIX StringUserConfigParam m_language
PARAM_DEFAULT( StringUserConfigParam("system", "language", "Which language to use (language code or 'system')") );

View File

@ -1436,6 +1436,10 @@
RelativePath="..\..\utils\synchronised.hpp"
>
</File>
<File
RelativePath="..\..\utils\time.hpp"
>
</File>
<File
RelativePath="..\..\utils\translation.hpp"
>

View File

@ -302,6 +302,22 @@ int XMLNode::get(const std::string &attribute, int *value) const
return 1;
} // get(int)
// ----------------------------------------------------------------------------
int XMLNode::get(const std::string &attribute, Time::TimeType *value) const
{
std::string s;
if(!get(attribute, &s)) return 0;
if (!StringUtils::parseString<Time::TimeType>(s, value))
{
fprintf(stderr, "[XMLNode] WARNING: Expected int but found '%s' for attribute '%s' of node '%s' in file %s\n",
s.c_str(), attribute.c_str(), m_name.c_str(), m_file_name.c_str());
return 0;
}
return 1;
} // get(TimeType)
// ----------------------------------------------------------------------------
int XMLNode::get(const std::string &attribute, unsigned int *value) const
{

View File

@ -20,14 +20,15 @@
#ifndef HEADER_XML_NODE_HPP
#define HEADER_XML_NODE_HPP
#include "utils/no_copy.hpp"
#include <string>
#include <map>
#include <vector>
#include "irrlicht.h"
using namespace irr;
#include "utils/no_copy.hpp"
#include "utils/time.hpp"
class Vec3;
/**
@ -64,6 +65,7 @@ public:
int get(const std::string &attribute, core::stringw *value) const;
int get(const std::string &attribute, int *value) const;
int get(const std::string &attribute, unsigned int *value) const;
int get(const std::string &attribute, Time::TimeType *value) const;
int get(const std::string &attribute, float *value) const;
int get(const std::string &attribute, bool *value) const;
int get(const std::string &attribute, Vec3 *value) const;

69
src/utils/time.hpp Normal file
View File

@ -0,0 +1,69 @@
// $Id$
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2004 Steve Baker <sjbaker1@airmail.net>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef HEADER_TIME_HPP
#define HEADER_TIME_HPP
#ifdef WIN32
# define _WINSOCKAPI_
# include <windows.h>
#else
# include <stdint.h>
#endif
class Time
{
public:
#ifdef WIN32
typedef unsigned __int64 TimeType;
#else
typedef uint_least64_t TimeType;
#endif
static TimeType getTimeSinceEpoch()
{
#ifdef WIN32
FILETIME ft;
GetSystemTimeAsFileTime(&ft);
TimeType t = ft.dwHighDateTime;
t <<= 32;
t /= 10;
// The Unix epoch starts on Jan 1 1970. Need to subtract
// the difference in seconds from Jan 1 1601.
# if defined(_MSC_VER) || defined(_MSC_EXTENSIONS)
# define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64
# else
# define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL
# endif
t -= DELTA_EPOCH_IN_MICROSECS;
t |= ft.dwLowDateTime;
// Convert to seconds since epoch
t /= 1000000UL;
return t;
#else
struct timeval tv;
gettimeofday(&tv, NULL);
return tv.tv_sec;
#endif
}; // getTimeSinceEpoch
}; // class time
#endif