Adding the addons menu, I am going to write a mail to the ML

git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@5597 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
xapantu 2010-06-30 18:40:55 +00:00
parent f0094304da
commit 5a653e26e9
27 changed files with 1755 additions and 9 deletions

BIN
data/gui/addons.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

28
data/gui/addons.stkgui Normal file
View File

@ -0,0 +1,28 @@
<stkgui>
<div x="2%" y="2%" width="96%" height="96%" layout="vertical-row" >
<header text_align="center" width="100%" text="SuperTuxKart Options"/>
<spacer height="15" width="10"/>
<tabs id="options_choice" height="10%" max_height="110" width="100%" align="center">
<icon-button id="tab_addons" width="128" height="128" icon="gui/package.png"
I18N="Section in the addons menu" text="Addons"/>
<icon-button id="tab_audio" width="128" height="128" icon="gui/no-package.png"
I18N="Section in the addons menu" text="Update"/>
</tabs>
<box proportion="1" width="100%" layout="vertical-row">
<label id="update_status" width="100%" height="10%" text_align="left" text="Updating the list..." />
<spacer height="5%" width="100%"/>
<list id="list_addons" height="50%" proportion="5" width="100%" align="center"/>
<spacer height="15%" width="100%"/>
</box>
<spacer width="50" height="45" />
</div>
<button id="back" x="20" y="-40" width="250" height="35" align="left"
I18N="In the options menu, to go back to the main menu or game" text="Back"/>
</stkgui>

View File

@ -0,0 +1,41 @@
<stkgui>
<div x="2%" y="2%" width="96%" height="96%" layout="vertical-row" >
<header text_align="center" width="100%" text="SuperTuxKart Options"/>
<spacer height="15" width="10"/>
<tabs id="options_choice" height="10%" max_height="110" width="100%" align="center">
<icon-button id="tab_video" width="128" height="128" icon="gui/options_video.png"
I18N="Section in the settings menu" text="Karts"/>
<icon-button id="tab_audio" width="128" height="128" icon="gui/options_audio.png"
I18N="Section in the settings menu" text="Tracks"/>
</tabs>
<!--<label id="info_addons" width="10%" height="10%" text_align="left" text="[none]" />-->
<box proportion="1" width="100%" layout="horizontal-row">
<div height="75%" width="40%" layout="vertical-row">
<spacer height="50" width="10"/>
<list id="list_karts" proportion="5" width="100%" align="center"/>
</div>
<spacer height="40" width="10"/>
<div height="40%" width="50%" layout="vertical-row">
<spacer height="40" width="10"/>
<icon id="logo" align="center" height="50%" width="100%" icon="gui/logo.png"/>
<label align="center" height="15%" width="100%" id="name_addons" />
<label align="center" height="15%" width="100%" id="version_addons" />
<label align="center" height="15%" width="100%" id="description_addons" />
<label align="center" height="15%" width="100%" id="install_addons" />
<button id="install" x="20" y="-40" width="250" height="35" align="left"
I18N="In the addons menu" text="Install"/>
</div>
<spacer width="50" height="40" />
</box>
</div>
<button id="back" x="20" y="-40" width="250" height="35" align="left"
I18N="In the options menu, to go back to the main menu or game" text="Back"/>
</stkgui>

BIN
data/gui/back_addons.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -0,0 +1,40 @@
<stkgui>
<div x="5%" y="0" width="90%" height="98%" layout="vertical-row" >
<icon id="logo" align="center" proportion="8" width="100%" icon="gui/logo.png"/>
<label width="100%" height="10%" id="info_addons"
I18N="In the main screen"
text="Loading news from stkaddons..."
align="center" text_align="center" />
<buttonbar id="menu_toprow" proportion="3" width="75%" align="center">
<icon-button id="new" width="128" height="128" icon="gui/main_race.png"
I18N="Main menu button" text="Race"/>
<icon-button id="network" width="128" height="128" icon="gui/main_network.png"
I18N="Main menu button" text="Networking"/>
<icon-button id="challenges" width="128" height="128"
icon="gui/challenge.png"
I18N="Main menu button" text="Challenges"/>
<icon-button id="addons" width="128" height="128"
icon="gui/addons.png"
I18N="Main menu button" text="Addons"/>
</buttonbar>
<spacer width="10" proportion="1"/>
<buttonbar id="menu_bottomrow" proportion="3" width="85%" align="center">
<icon-button id="options" width="128" height="128" icon="gui/main_options.png"
I18N="Main menu button" text="Options"/>
<icon-button id="help" width="128" height="128" icon="gui/main_help.png"
I18N="Main menu button" text="Help"/>
<icon-button id="about" width="128" height="128" icon="gui/main_about.png"
I18N="Main menu button" text="About"/>
<icon-button id="quit" width="128" height="128" icon="gui/main_quit.png"
I18N="Main menu button" text="Quit"/>
</buttonbar>
<spacer width="10" proportion="1"/>
</div>
</stkgui>

BIN
data/gui/next_addons.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

BIN
data/gui/no-package.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
data/gui/package.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -278,6 +278,8 @@ supertuxkart_SOURCES = \
states_screens/dialogs/race_paused_dialog.cpp \
states_screens/dialogs/track_info_dialog.cpp \
states_screens/dialogs/track_info_dialog.hpp \
states_screens/dialogs/addons_loading.cpp \
states_screens/dialogs/addons_loading.hpp \
states_screens/arenas_screen.cpp \
states_screens/arenas_screen.hpp \
states_screens/feature_unlocked.cpp \
@ -306,6 +308,8 @@ supertuxkart_SOURCES = \
states_screens/options_screen_players.hpp \
states_screens/options_screen_video.cpp \
states_screens/options_screen_video.hpp \
states_screens/addons_screen.cpp \
states_screens/addons_screen.hpp \
states_screens/race_gui.cpp \
states_screens/race_gui.hpp \
states_screens/race_setup_screen.cpp \
@ -355,7 +359,13 @@ supertuxkart_SOURCES = \
utils/translation.cpp \
utils/translation.hpp \
utils/vec3.cpp \
utils/vec3.hpp
utils/vec3.hpp \
addons/network.cpp \
addons/network.hpp \
addons/addons.cpp \
addons/addons.hpp \
addons/zip.cpp \
addons/zip.hpp
# Link in the specific gcc 4.1 bug work around
supertuxkart_LDADD = \

450
src/addons/addons.cpp Normal file
View File

@ -0,0 +1,450 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2010 Lucas Baudin
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
/**
\page addons Addons
*/
#ifdef ADDONS_MANAGER
#include <string.h>
#include <map>
#include <vector>
#include <iostream>
#include "addons/addons.hpp"
#include "irrXML.h"
#include "addons/network.hpp"
#include "addons/zip.hpp"
#include <fstream>
#include <sys/types.h>
#include <unistd.h>
#include <dirent.h>
#include <sys/stat.h>
#include <sstream>
#include "io/file_manager.hpp"
using namespace irr; /* irrXML which is used to read (not write) xml file,
is located in the namespace irr::io.*/
using namespace io;
// ----------------------------------------------------------------------------
Addons::Addons()
{
this->index = -1;
std::cout << "Loading an xml file for addons: ";
download("list");
std::string xml_file = file_manager->getConfigDir() + "/" + "list";
std::cout << xml_file << std::endl;
IrrXMLReader* xml = createIrrXMLReader(xml_file.c_str());
// strings for storing the data we want to get out of the file
std::string attribute_name;
// parse the file until end reached
while(xml && xml->read())
{
/*only if it is a node*/
if(xml->getNodeType() == EXN_ELEMENT)
{
if (!strcmp("kart", xml->getNodeName()) || !strcmp("track", xml->getNodeName()))
{
addons_prop addons;
//the unsigned is to remove the compiler warnings, maybe it is a bad idea ?
for(unsigned int i = 0; i < xml->getAttributeCount(); i++)
{
attribute_name = xml->getAttributeName(i);
if(attribute_name == "name")
{
addons.name = xml->getAttributeValue("name");
}
if(attribute_name == "version")
{
addons.version = atoi(xml->getAttributeValue("version"));
}
if(attribute_name == "file")
{
addons.file = xml->getAttributeValue("file");
}
if(attribute_name == "description")
{
addons.description = xml->getAttributeValue("description");
}
if(attribute_name == "icon")
{
addons.icon = xml->getAttributeValue("icon");
}
if(attribute_name == "id")
{
addons.id = xml->getAttributeValue("id");
}
}
addons.type = xml->getNodeName();
addons.installed = false;
this->addons_list.push_back(addons);
}
}
}
delete xml;
this->file_installed = file_manager->getConfigDir() + "/" + "addons_installed.xml";
this->GetInstalledAddons();
}
void Addons::resetIndex()
{
this->index = -1;
}
// ----------------------------------------------------------------------------
void Addons::GetInstalledAddons()
{
std::string attribute_name;
int old_index = this->index;
/* checking for installed addons */
std::cout << "Loading an xml file for installed addons: ";
std::cout << this->file_installed << std::endl;
IrrXMLReader* xml = createIrrXMLReader(this->file_installed.c_str());
// parse the file until end reached
while(xml && xml->read())
{
std::string name;
std::string id;
int version = 0;
switch(xml->getNodeType())
{
case EXN_ELEMENT:
{
if (!strcmp("kart", xml->getNodeName()) || !strcmp("track", xml->getNodeName()))
{
std::cout << xml->getAttributeCount() << std::endl;
//the unsigned is to remove the compiler warnings, maybe it is a bad idea ?
for(unsigned int i = 0; i < xml->getAttributeCount(); i++)
{
attribute_name = xml->getAttributeName(i);
if(attribute_name == "id")
{
id = xml->getAttributeValue("id");
}
if(attribute_name == "name")
{
name = xml->getAttributeValue("name");
}
if(attribute_name == "version")
{
version = xml->getAttributeValueAsInt("version");
}
}
if(this->SelectId(id))
{
this->addons_list[this->index].installed = true;
this->addons_list[this->index].installed_version = version;
std::cout << "An addons is already installed: " + id << std::endl;
}
else
{
addons_prop addons;
addons.type = xml->getNodeName();
addons.name = name;
addons.installed_version = version;
addons.installed = true;
this->addons_list.push_back(addons);
}
}
}
break;
default : break;
}
}
delete xml;
this->index = old_index;
}
// ----------------------------------------------------------------------------
bool Addons::Next()
{
if(this->index + 1 < this->addons_list.size())
{
this->index ++;
return true;
}
this->index = -1;
return false;
}
// ----------------------------------------------------------------------------
bool Addons::NextType(std::string type)
{
while(this->Next())
{
if(this->addons_list[this->index].type == type)
return true;
}
while(this->Next())
{
if(this->addons_list[this->index].type == type)
return false;
}
return false;
}
// ----------------------------------------------------------------------------
bool Addons::Previous()
{
if(this->index - 1 > 0)
{
this->index --;
return true;
}
this->index = this->addons_list.size() - 1;
return false;
}
// ----------------------------------------------------------------------------
bool Addons::PreviousType(std::string type)
{
while(this->Previous())
{
if(this->addons_list[this->index].type == type)
return true;
}
while(this->Previous())
{
if(this->addons_list[this->index].type == type)
return false;
}
return false;
}
// ----------------------------------------------------------------------------
bool Addons::Select(std::string name)
{
//the unsigned is to remove the compiler warnings, maybe it is a bad idea ?
for(unsigned int i = 0; i < this->addons_list.size(); i++)
{
if(this->addons_list[i].name == name)
{
this->index = i;
return true;
}
}
return false;
}
// ----------------------------------------------------------------------------
bool Addons::SelectId(std::string id)
{
//the unsigned is to remove the compiler warnings, maybe it is a bad idea ?
for(unsigned int i = 0; i < this->addons_list.size(); i++)
{
if(this->addons_list[i].id == id)
{
this->index = i;
return true;
}
}
return false;
}
// ----------------------------------------------------------------------------
/* FIXME : remove this function */
addons_prop Addons::GetAddons()
{
return this->addons_list[this->index];
}
std::string Addons::GetType()
{
return this->addons_list[this->index].type;
}
// ----------------------------------------------------------------------------
std::string Addons::IsInstalled()
{
if(this->addons_list[this->index].installed)
{
return "yes";
}
return "no";
}
// ----------------------------------------------------------------------------
bool Addons::IsInstalledAsBool()
{
return this->addons_list[this->index].installed;
}
// ----------------------------------------------------------------------------
std::string Addons::GetName()
{
return this->addons_list[this->index].name;
}
// ----------------------------------------------------------------------------
int Addons::GetVersion()
{
return this->addons_list[this->index].version;
}
// ----------------------------------------------------------------------------
std::string Addons::GetIcon()
{
return this->addons_list[this->index].icon;
}
// ----------------------------------------------------------------------------
std::string Addons::GetVersionAsStr()
{
//maybe it is dirty, FIXME ?
std::ostringstream os;
os << this->addons_list[this->index].version;
return os.str();
}
// ----------------------------------------------------------------------------
int Addons::GetInstalledVersion()
{
if(this->addons_list[this->index].installed)
return this->addons_list[this->index].installed_version;
return 0;
}
// ----------------------------------------------------------------------------
std::string Addons::GetInstalledVersionAsStr()
{
if(this->addons_list[this->index].installed)
{
std::ostringstream os;
os << this->addons_list[this->index].installed_version;
return os.str();
}
return "";
}
// ----------------------------------------------------------------------------
std::string Addons::GetDescription()
{
return this->addons_list[this->index].description;
}
// ----------------------------------------------------------------------------
void Addons::Install()
{
std::string dest_file =file_manager->getAddonsDir() + "/" + "data" + "/" +
this->addons_list[this->index].type + "/";
//download of the addons file
download(std::string("file/" + this->addons_list[this->index].file),
this->addons_list[this->index].name);
//creating of the data folders
mkdir(std::string(file_manager->getAddonsDir() + "/" + "data").c_str(), 0777);
mkdir(dest_file.c_str(), 0777);
mkdir(std::string(dest_file + this->addons_list[this->index].name).c_str(), 0777);
//extract the zip in the addons folder called like the addons name
extract_zip(file_manager->getConfigDir() + "/" + this->addons_list[this->index].name,
dest_file + this->addons_list[this->index].name + "/");
this->addons_list[this->index].installed = true;
this->addons_list[this->index].installed_version = this->addons_list[this->index].version;
this->SaveInstalled();
}
// ----------------------------------------------------------------------------
void Addons::SaveInstalled()
{
//Put the addons in the xml file
//Manually because the irrlicht xml writer doesn't seem finished, FIXME ?
std::ofstream xml_installed(this->file_installed.c_str());
//write the header of the xml file
xml_installed << "<?xml version=\"1.0\"?>" << std::endl;
xml_installed << "<addons xmlns='http://stkaddons.tuxfamily.org/'>"
<< std::endl;
//the unsigned is to remove the compiler warnings, maybe it is a bad idea ?
for(unsigned int i = 0; i < this->addons_list.size(); i++)
{
if(this->addons_list[i].installed)
{
std::ostringstream os;
os << this->addons_list[i].installed_version;
//transform the version (int) in string
xml_installed << "<"+ this->addons_list[i].type +" name=\"" +
this->addons_list[i].name + "\" id=\"" +
this->addons_list[i].id + "\"";
xml_installed << " version=\"" + os.str() + "\" />" << std::endl;
}
}
xml_installed << "</addons>" << std::endl;
xml_installed.close();
}
// ----------------------------------------------------------------------------
void Addons::UnInstall()
{
std::cout << "Uninstall: " << this->addons_list[this->index].name << std::endl;
this->addons_list[this->index].installed = false;
//write the xml file with the informations about installed karts
this->SaveInstalled();
std::string dest_file = file_manager->getAddonsDir() + "/" + "data" + "/" +
this->addons_list[this->index].type + "/" +
this->addons_list[this->index].name + "/";
//remove the addons directory
this->RemoveDirectory(dest_file.c_str());
}
// ----------------------------------------------------------------------------
int Addons::RemoveDirectory(char const *name)
{
DIR *directory;
struct dirent *entry;
struct stat file_stat;
char buffer[1024] = {0};
directory = opendir(name);
if ( directory == NULL ) {
fprintf(stderr, "cannot open directory %s\n", name);
return 0;
}
while ( (entry = readdir(directory)) != NULL ) {
if ( strcmp(entry->d_name, ".") == 0 ||
strcmp(entry->d_name, "..") == 0 ) {
continue;
}
snprintf(buffer, 1024, "%s/%s", name, entry->d_name);
stat(buffer, &file_stat);
if ( S_ISREG(file_stat.st_mode) ) {
remove(buffer);
}
else if ( S_ISDIR(file_stat.st_mode) ) {
this->RemoveDirectory(buffer);
}
}
closedir(directory);
remove(name);
return 1;
}
std::string Addons::GetIdAsStr()
{
std::ostringstream os;
os << this->addons_list[this->index].id;
return os.str();
}
#endif

110
src/addons/addons.hpp Normal file
View File

@ -0,0 +1,110 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2010 Lucas Baudin
//
// 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.
#ifdef ADDONS_MANAGER
#ifndef HEADER_ADDONS_HPP
#define HEADER_ADDONS_HPP
#include <string.h>
#include <map>
#include <vector>
struct addons_prop
{
std::string name;
int version;
int installed_version;
std::string description;
std::string icon;
std::string file;
std::string id;
bool installed;
std::string type;
};
class Addons
{
private:
std::vector<addons_prop> addons_list;
int index;
std::string file_installed;
void SaveInstalled();
int RemoveDirectory(char const *name);
void GetInstalledAddons();
std::string type;
public:
Addons();
/** Select the next addons in the addons list. */
bool Next();
/** Select the next addons in the addons list. */
bool Previous();
/** Get all the selected addon parameters. */
addons_prop GetAddons();
/** Select an addon with it name. */
bool Select(std::string);
/** Select an addon with it id. */
bool SelectId(std::string);
/** Get the name of the selected addon. */
std::string GetName();
/** Get the version of the selected addon. */
int GetVersion();
/** Get the path of the addon icon. */
std::string GetIcon();
/** Get the version of the selected addon as a string. */
std::string GetVersionAsStr();
/** Get the installed version of the selected addon. */
int GetInstalledVersion();
std::string GetInstalledVersionAsStr();
/** Get the installed version of the selected addon. */
std::string GetIdAsStr();
/** Get the description of the selected addons. */
std::string GetDescription();
/** Install or upgrade the selected addon. */
void Install();
/** Uninstall the selected addon. This method will remove all the directory of the addon.*/
void UnInstall();
void resetIndex();
/** Get the state of the addon: if it is installed or not.*/
/* FIXME : the return value should be a boolean, not a string. */
std::string IsInstalled();
/** Get the state of the addon: if it is installed or not.*/
/* FIXME : the return value should be a boolean, not a string. */
bool IsInstalledAsBool();
bool NextType(std::string type);
bool PreviousType(std::string type);
std::string GetType();
};
#endif
#endif

61
src/addons/network.cpp Normal file
View File

@ -0,0 +1,61 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2010 Lucas Baudin
//
// 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.
#ifdef ADDONS_MANAGER
#include <curl/curl.h>
#include <stdio.h>
#include <string>
#include "addons/network.hpp"
#include "config/user_config.hpp"
#include "states_screens/main_menu_screen.hpp"
#include "states_screens/addons_screen.hpp"
#include "io/file_manager.hpp"
// ------------------------------------------------------------------------------------------------------
void download(std::string file)
{
CURL *session = curl_easy_init();
std::cout << "Downloading: " << std::string(UserConfigParams::m_server_addons.toString() + "/" + file) << std::endl;
curl_easy_setopt(session, CURLOPT_URL, std::string(UserConfigParams::m_server_addons.toString() + "/" + file).c_str());
FILE * fp = fopen(std::string(file_manager->getConfigDir() + std::string("/") + file).c_str(), "w");
curl_easy_setopt(session, CURLOPT_WRITEDATA, fp);
curl_easy_setopt(session, CURLOPT_WRITEFUNCTION, fwrite);
curl_easy_perform(session);
fclose(fp);
curl_easy_cleanup(session);
std::cout << UserConfigParams::m_server_addons.toString() << std::endl;
}
// ------------------------------------------------------------------------------------------------------
void download(std::string file, std::string save)
{
CURL *session = curl_easy_init();
std::cout << "Downloading: " << std::string(UserConfigParams::m_server_addons.toString() + "/" + file) << std::endl;
curl_easy_setopt(session, CURLOPT_URL, std::string(UserConfigParams::m_server_addons.toString() + "/" + file).c_str());
FILE * fp = fopen(std::string(file_manager->getConfigDir() + std::string("/") + save).c_str(), "w");
curl_easy_setopt(session, CURLOPT_WRITEDATA, fp);
curl_easy_setopt(session, CURLOPT_WRITEFUNCTION, fwrite);
curl_easy_perform(session);
fclose(fp);
curl_easy_cleanup(session);
std::cout << UserConfigParams::m_server_addons.toString() << std::endl;
}
#endif

31
src/addons/network.hpp Normal file
View File

@ -0,0 +1,31 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2010 Lucas Baudin
//
// 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.
#ifdef ADDONS_MANAGER
#ifndef HEADER_NETWORK_HPP
#define HEADER_NETWORK_HPP
/** Download a file. The file name isn't absolute, the server in the config will be added to file. */
void download(std::string file);
/** Download a file with a specific destination. */
void download(std::string file, std::string out);
#endif
#endif

97
src/addons/zip.cpp Normal file
View File

@ -0,0 +1,97 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2010 Lucas Baudin
//
// 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.
#ifdef ADDONS_MANAGER
#include "irrlicht.h"
#include "graphics/irr_driver.hpp"
#include <string.h>
#include <iostream>
#include <fstream>
using namespace irr;
using namespace io;
s32 IFileSystem_copyFileToFile(IWriteFile* dst, IReadFile* src)
{
char buf[1024];
const s32 sz = sizeof(buf) / sizeof(*buf);
s32 r, rx = src->getSize();
for (r = 0; r < rx; /**/)
{
s32 w, wx = src->read(buf, sz);
for (w = 0; w < wx; /**/)
{
s32 n = dst->write(buf + w, wx - w);
if (n < 0)
return -1;
else
w += n;
}
r += w;
}
return r;
}
void extract_zip(std::string from, std::string to)
{
//get the stk irrlicht device
IrrlichtDevice * device = irr_driver->getDevice();
//get the filesystem from the device
IFileSystem* pfs = device->getFileSystem();
//Add the zip to the file system
pfs->addZipFileArchive(from.c_str());
IFileArchive * zipfile = pfs->getFileArchive(0);
//extract the file where there is the others file name
IReadFile* srcFile = pfs->createAndOpenFile("file_list");
IWriteFile* dstFile = pfs->createAndWriteFile(std::string(to + "file_list").c_str());
std::cout << from.c_str() << std::endl;
//....
if (IFileSystem_copyFileToFile(dstFile, srcFile) < 0)
; // error
srcFile->drop();
dstFile->drop();
std::string file_list;
std::string buff;
std::ifstream entree(std::string(to + "file_list").c_str(), std::ios::in);
while (entree >> buff)
file_list += buff;
std::cout << file_list << std::endl;
std::string current_file;
for(unsigned int i=0; i < file_list.size(); i++)
{
if(file_list.c_str()[i] != '\\')
{
current_file += file_list[i];
}
else
{
std::cout << current_file << std::endl;
IReadFile* srcFile = pfs->createAndOpenFile(current_file.c_str());
IWriteFile* dstFile = pfs->createAndWriteFile(std::string(to + current_file).c_str());
if (IFileSystem_copyFileToFile(dstFile, srcFile) < 0)
; // error
srcFile->drop();
dstFile->drop();
current_file = "";
}
}
//remove the zip from the filesystem to save memory and avoid problem with a name conflict
pfs->removeFileArchive(from.c_str());
}
#endif

25
src/addons/zip.hpp Normal file
View File

@ -0,0 +1,25 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2010 Lucas Baudin
//
// 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.
#ifdef ADDONS_MANAGER
#ifndef HEADER_ZIP_HPP
#define HEADER_ZIP_HPP
/** Extract a zip. */
void extract_zip(std::string, std::string);
#endif
#endif

View File

@ -314,6 +314,9 @@ namespace UserConfigParams
PARAM_PREFIX StringUserConfigParam m_skin_file
PARAM_DEFAULT( StringUserConfigParam("Glass.stkskin", "skin_file", "Name of the skin to use") );
PARAM_PREFIX StringUserConfigParam m_server_addons
PARAM_DEFAULT( StringUserConfigParam("http://download.tuxfamily.org/stkaddons/0.7/", "server_addons", "The server used for addon.") );
PARAM_PREFIX bool m_no_start_screen PARAM_DEFAULT( false ); // not saved to file

View File

@ -154,6 +154,9 @@ FileManager::FileManager(char *argv[])
fprintf(stderr, "Data files will be fetched from: '%s'\n",
m_root_dir.c_str() );
checkAndCreateConfigDir();
#ifdef ADDONS_MANAGER
checkAndCreateAddonsDir();
#endif
} // FileManager
//-----------------------------------------------------------------------------
@ -444,6 +447,61 @@ void FileManager::checkAndCreateConfigDir()
return;
} // checkAndCreateConfigDir
#ifdef ADDONS_MANAGER
void FileManager::checkAndCreateAddonsDir()
{
#ifdef WIN32
//TODO
#else
# ifdef __APPLE__
//TODO
# else
// Remaining unix variants. Use the new standards for config directory
// i.e. either XDG_CONFIG_HOME or $HOME/.config
if (getenv("XDG_DATA_HOME")!=NULL){
m_addons_dir = getenv("XDG_DATA_HOME");
}
else if (!getenv("HOME"))
{
std::cerr << "No home directory, this should NOT happen - trying '.addons' for addons files!\n";
m_addons_dir = "stkaddons";
}
else
{
m_addons_dir = getenv("HOME");
m_addons_dir += "/.local/share";
if(!checkAndCreateDirectory(m_config_dir))
{
// If $HOME/.config can not be created:
fprintf(stderr, "Can't create dir '%s', falling back to use '%s'.\n",
m_config_dir.c_str(), getenv("HOME"));
m_addons_dir = getenv("HOME");
m_addons_dir += ".";
}
}
# endif
#endif
const std::string CONFIGDIR("supertuxkart");
m_addons_dir += "/";
m_addons_dir += CONFIGDIR;
if(!checkAndCreateDirectory(m_addons_dir))
{
fprintf(stderr, "Can not create config dir '%s', falling back to '.'.\n",
m_addons_dir.c_str());
m_config_dir = ".";
}
return;
} // checkAndCreateAddonsDir
//-----------------------------------------------------------------------------
std::string FileManager::getAddonsDir() const
{
return m_addons_dir;
} // getConfigDir
/* see l450: to avoid the compilation of unused methods. */
#endif
//-----------------------------------------------------------------------------
std::string FileManager::getConfigDir() const
{

View File

@ -50,6 +50,8 @@ private:
bool m_is_full_path;
/** Directory where user config files are stored. */
std::string m_config_dir;
/** Directory where addons are stored. */
std::string m_addons_dir;
/** Root data directory. */
std::string m_root_dir;
std::vector<std::string> m_texture_search_path,
@ -64,6 +66,9 @@ private:
bool checkAndCreateDirectory(const std::string &path);
io::path createAbsoluteFilename(const std::string &f);
void checkAndCreateConfigDir();
#ifdef ADDONS_MANAGER
void checkAndCreateAddonsDir();
#endif
public:
FileManager(char *argv[]);
~FileManager();
@ -73,6 +78,9 @@ public:
XMLNode *createXMLTree(const std::string &filename);
std::string getConfigDir () const;
#ifdef ADDONS_MANAGER
std::string getAddonsDir () const;
#endif
std::string getKartDir () const;
std::string getDataDir () const;
std::string getTranslationDir() const;

View File

@ -69,6 +69,7 @@
#include "tracks/track_manager.hpp"
#include "utils/translation.hpp"
void cmdLineHelp (char* invocation)
{
fprintf ( stdout,
@ -581,10 +582,6 @@ void cleanTuxKart()
int main(int argc, char *argv[] )
{
#ifdef ADDONS_MANAGER
std::cout << "Addons manager enabled." << std::endl;
#endif
try {
// Init the minimum managers so that user config exists, then
// handle all command line options that do not need (or must

View File

@ -0,0 +1,162 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2010 Lucas Baudin
//
// 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.
#ifdef ADDONS_MANAGER
#include "states_screens/addons_screen.hpp"
#include "states_screens/dialogs/addons_loading.hpp"
#include "guiengine/widget.hpp"
#include "guiengine/widgets/ribbon_widget.hpp"
#include "guiengine/widgets.hpp"
#include "states_screens/state_manager.hpp"
#include "addons/network.hpp"
#include "guiengine/CGUISpriteBank.h"
#include "addons/addons.hpp"
#include "io/file_manager.hpp"
#include "irrlicht.h"
/*pthread aren't supported natively by windows. Here a port: http://sourceware.org/pthreads-win32/ */
#include <pthread.h>
#include <sstream>
DEFINE_SCREEN_SINGLETON( AddonsScreen );
// ------------------------------------------------------------------------------------------------------
AddonsScreen::AddonsScreen() : Screen("addons.stkgui")
{
}
// ------------------------------------------------------------------------------------------------------
void AddonsScreen::loadedFromFile()
{
video::ITexture* icon1 = irr_driver->getTexture( file_manager->getGUIDir()
+ "/package.png" );
video::ITexture* icon2 = irr_driver->getTexture( file_manager->getGUIDir()
+ "/no-package.png" );
m_icon_bank = new irr::gui::STKModifiedSpriteBank( GUIEngine::getGUIEnv() );
m_icon_bank->addTextureAsSprite(icon1);
m_icon_bank->addTextureAsSprite(icon2);
}
// ------------------------------------------------------------------------------------------------------
void AddonsScreen::loadList()
{
std::cout << "load list" << std::endl;
GUIEngine::ListWidget* w_list = this->getWidget<GUIEngine::ListWidget>("list_addons");
w_list->clear();
this->addons->resetIndex();
w_list->addItem("kart", _("Karts:"), -1 /* no icon */);
while(this->addons->NextType("kart"))
{
std::cout << this->addons->GetName() << std::endl;
if(this->addons->IsInstalledAsBool())
w_list->addItem(this->addons->GetIdAsStr().c_str(),
this->addons->GetName().c_str(), 0 /* icon installed */);
else
w_list->addItem(this->addons->GetIdAsStr().c_str(),
this->addons->GetName().c_str(), 1 /* icon unsinstalled*/);
}
//load all tracks...
w_list->addItem("track", _("Tracks:"), -1 /* no icon */);
this->addons->resetIndex();
while(this->addons->NextType("track"))
{
std::cout << this->addons->GetName() << std::endl;
if(this->addons->IsInstalledAsBool())
w_list->addItem(this->addons->GetIdAsStr().c_str(),
this->addons->GetName().c_str(), 0 /* icon */);
else
w_list->addItem(this->addons->GetIdAsStr().c_str(),
this->addons->GetName().c_str(), 1 /* icon */);
}
//remove the text from the widget : "Updating list..." (see l164)
this->update_status->setText("");
this->can_load_list = false;
}
// ------------------------------------------------------------------------------------------------------
void AddonsScreen::eventCallback(GUIEngine::Widget* widget, const std::string& name, const int playerID)
{
if (name == "back")
{
StateManager::get()->escapePressed();
}
else if (name == "list_addons")
{
GUIEngine::ListWidget* list = this->getWidget<GUIEngine::ListWidget>("list_addons");
std::string addons = list->getSelectionInternalName();
if(addons != "track" && addons != "kart")
{
this->addons->SelectId(addons);
this->load = new AddonsLoading(this->addons, 0.8f, 0.8f);
}
}
}
// ------------------------------------------------------------------------------------------------------
void AddonsScreen::onUpdate(float delta, irr::video::IVideoDriver* driver)
{
pthread_mutex_lock(&(this->mutex));
if(this->can_load_list)
{
this->loadList();
}
pthread_mutex_unlock(&(this->mutex));
}
void AddonsScreen::init()
{
this->update_status = this->getWidget<GUIEngine::LabelWidget>("update_status");
std::cout << "Addons dir:" + file_manager->getAddonsDir() << std::endl;
this->type = "track";
GUIEngine::ListWidget* w_list = this->getWidget<GUIEngine::ListWidget>("list_addons");
w_list->setIcons(m_icon_bank);
//w_list->clear();
std::cout << "icon bank" << std::endl;
this->can_load_list = false;
pthread_t thread;
pthread_create(&thread, NULL, &AddonsScreen::downloadList, this);
}
// ------------------------------------------------------------------------------------------------------
void AddonsScreen::tearDown()
{
}
// ------------------------------------------------------------------------------------------------------
void * AddonsScreen::downloadList( void * pthis)
{
AddonsScreen * pt = (AddonsScreen*)pthis;
pt->update_status->setText(_("Updating the list..."));
//load all karts...
pt->addons = new Addons();
pthread_mutex_lock(&(pt->mutex));
pt->can_load_list = true;
pthread_mutex_unlock(&(pt->mutex));
//pt->loadList();
return NULL;
}
#endif

View File

@ -0,0 +1,74 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2010 Lucas Baudin
//
// 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.
#ifdef ADDONS_MANAGER
#ifndef HEADER_ADDONS_SCREEN_HPP
#define HEADER_ADDONS_SCREEN_HPP
#include "guiengine/screen.hpp"
#include "states_screens/dialogs/addons_loading.hpp"
#include "addons/addons.hpp"
#include "guiengine/widgets/label_widget.hpp"
#include <pthread.h>
#include "irrlicht.h"
/* used for the installed/unsinstalled icons*/
namespace irr { namespace gui { class STKModifiedSpriteBank; } }
namespace GUIEngine { class Widget; }
/**
* \brief Addons screen
* \ingroup states_screens
*/
class AddonsScreen : public GUIEngine::Screen, public GUIEngine::ScreenSingleton<AddonsScreen>
{
friend class GUIEngine::ScreenSingleton<AddonsScreen>;
AddonsScreen();
Addons * addons;
AddonsLoading * load;
void loadInformations();
/** For the addons list, a package when it is installed. */
irr::gui::STKModifiedSpriteBank* m_icon_bank;
GUIEngine::LabelWidget* update_status;
public:
bool can_load_list;
pthread_mutex_t mutex;
std::string type;
void loadList();
/** \brief implement callback from parent class GUIEngine::Screen */
virtual void loadedFromFile();
/** \brief implement callback from parent class GUIEngine::Screen */
virtual void eventCallback(GUIEngine::Widget* widget, const std::string& name, const int playerID);
/** \brief implement callback from parent class GUIEngine::Screen */
virtual void init();
/** \brief implement callback from parent class GUIEngine::Screen */
virtual void tearDown();
friend void * startInstall(void *);
/** This function is used to download a text from the server to show the news. */
static void * downloadList(void *);
virtual void onUpdate(float delta, irr::video::IVideoDriver*);
};
#endif
#endif

View File

@ -0,0 +1,144 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2010 Lucas Baudin
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "states_screens/addons_screen.hpp"
#include "states_screens/dialogs/addons_loading.hpp"
#include "guiengine/widget.hpp"
#include "guiengine/widgets/ribbon_widget.hpp"
#include "guiengine/widgets.hpp"
#include "states_screens/state_manager.hpp"
#include "addons/network.hpp"
#include "addons/addons.hpp"
#include "io/file_manager.hpp"
/*pthread aren't supported natively by windows. Here a port: http://sourceware.org/pthreads-win32/ */
#include <pthread.h>
#include <sstream>
DEFINE_SCREEN_SINGLETON( AddonsUpdateScreen );
// ------------------------------------------------------------------------------------------------------
AddonsUpdateScreen::AddonsUpdateScreen() : Screen("addons_update.stkgui")
{
}
// ------------------------------------------------------------------------------------------------------
void AddonsUpdateScreen::loadedFromFile()
{
}
// ------------------------------------------------------------------------------------------------------
void AddonsUpdateScreen::download_list()
{
/*
GUIEngine::ListWidget* w_list = this->getWidget<GUIEngine::ListWidget>("list_karts");
this->addons = new Addons(std::string(file_manager->getConfigDir() + "/list_text"), std::string(file_manager->getConfigDir() + "/installed.xml"));
//to have the name of the first karts and load it informatins later
this->addons->Next();
std::string first_kart = this->addons->GetName();
std::cout << this->addons->GetName() << std::endl;
w_list->addItem(std::string("list_karts" + this->addons->GetName()).c_str(), this->addons->GetName().c_str(), 0 /* icon */);
/*while(this->addons->Next())
{
std::cout << this->addons->GetName() << std::endl;
w_list->addItem(std::string("list_karts" + this->addons->GetName()).c_str(), this->addons->GetName().c_str(), 0 /* icon *//*);
}
this->addons->Select(first_kart);
this->loadInformations();*/
}
// ------------------------------------------------------------------------------------------------------
void AddonsUpdateScreen::eventCallback(GUIEngine::Widget* widget, const std::string& name, const int playerID)
{
if (name == "back")
{
StateManager::get()->escapePressed();
}
else if (name == "install")
{
this->load = new AddonsLoading(0.4f, 0.4f);
pthread_t thread;
pthread_create(&thread, NULL, *startInstall, this);
//this->addons->Install();
}
else if (name.find("list_karts") == 0)
{
GUIEngine::ListWidget* list = this->getWidget<GUIEngine::ListWidget>("list_karts");
std::string kart = list->getSelectionInternalName().replace(0, 10, "");
this->addons->Select(kart);
this->loadInformations();
}
}
// ------------------------------------------------------------------------------------------------------
void AddonsUpdateScreen::init()
{
pthread_t nThreadID2;
pthread_create(&nThreadID2, NULL, *download_l, this);
}
// ------------------------------------------------------------------------------------------------------
void AddonsUpdateScreen::tearDown()
{
}
void AddonsUpdateScreen::loadInformations()
{
std::cout << this->addons->GetName() << std::endl;
GUIEngine::LabelWidget* w = this->getWidget<GUIEngine::LabelWidget>("name_addons");
w->setText(std::string("Name: "+ this->addons->GetName()).c_str());
w = this->getWidget<GUIEngine::LabelWidget>("description_addons");
w->setText(std::string("Description: " + this->addons->GetDescription()).c_str());
w = this->getWidget<GUIEngine::LabelWidget>("version_addons");
std::ostringstream os;
os << this->addons->GetVersion();
w->setText(std::string("Version: " + os.str()).c_str());
w = this->getWidget<GUIEngine::LabelWidget>("install_addons");
w->setText(std::string("Installed: " + this->addons->IsInstalled()).c_str());
GUIEngine::ButtonWidget* button = this->getWidget<GUIEngine::ButtonWidget>("install");
if(this->addons->IsInstalled() == "yes")
{
button->setLabel(std::string("Uninstall").c_str());
}
else
{
button->setLabel(std::string("Install").c_str());
}
}
// ------------------------------------------------------------------------------------------------------
//I dislike this way, it is too dirty but I didn't find another way
void * startInstall(void* pthis)
{
AddonsUpdateScreen * obj = (AddonsUpdateScreen*)pthis;
if(obj->addons->IsInstalled() == "yes")
{
std::cout << obj->addons->IsInstalled() << std::endl;
obj->addons->UnInstall();
}
else
{
obj->addons->Install();
}
obj->load->close();
obj->loadInformations();
return NULL;
}

View File

@ -0,0 +1,58 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2010 Lucas Baudin
//
// 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_ADDONS_SCREEN_HPP
#define HEADER_ADDONS_SCREEN_HPP
#include "guiengine/screen.hpp"
#include "states_screens/dialogs/addons_loading.hpp"
#include "addons/addons.hpp"
#include "guiengine/widgets/label_widget.hpp"
namespace GUIEngine { class Widget; }
/**
* \brief Help screen, part 1
* \ingroup states_screens
*/
class AddonsUpdateScreen : public GUIEngine::Screen, public GUIEngine::ScreenSingleton<AddonsUpdateScreen>
{
friend class GUIEngine::ScreenSingleton<AddonsUpdateScreen>;
AddonsUpdateScreen();
Addons * addons;
AddonsLoading * load;
void loadInformations();
public:
void download_list();
/** \brief implement callback from parent class GUIEngine::Screen */
virtual void loadedFromFile();
/** \brief implement callback from parent class GUIEngine::Screen */
virtual void eventCallback(GUIEngine::Widget* widget, const std::string& name, const int playerID);
/** \brief implement callback from parent class GUIEngine::Screen */
virtual void init();
/** \brief implement callback from parent class GUIEngine::Screen */
virtual void tearDown();
friend void * startInstall(void *);
};
void * startInstall(void *);
#endif

View File

@ -0,0 +1,236 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2009 Marianne Gagnon
//
// 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.
#ifdef ADDONS_MANAGER
#include "guiengine/engine.hpp"
#include "guiengine/widgets.hpp"
#include "input/input_manager.hpp"
#include "states_screens/dialogs/addons_loading.hpp"
#include "utils/translation.hpp"
#include "addons/addons.hpp"
#include "addons/network.hpp"
#include "states_screens/addons_screen.hpp"
#include <pthread.h>
#include "utils/string_utils.hpp"
#include "io/file_manager.hpp"
using namespace GUIEngine;
using namespace irr::gui;
// ------------------------------------------------------------------------------------------------------
AddonsLoading::AddonsLoading(Addons * id, const float w, const float h) :
ModalDialog(w, h)
{
this->addons = id;
core::rect< s32 > area_right(10, 0, m_area.getWidth()/2, m_area.getHeight());
core::rect< s32 > area_left(m_area.getWidth()/2 + 20, 0, m_area.getWidth(), m_area.getHeight());
/*Init the icon here to be able to load a single image*/
icon = new IconButtonWidget();
/* Next and previous button*/
IconButtonWidget * next_previous = new IconButtonWidget();
next_previous->setImage("gui/next_addons.png");
next_previous->x = area_right.UpperLeftCorner.X + 100;
next_previous->y = area_right.UpperLeftCorner.Y +20 ;
next_previous->w = 75;
next_previous->m_properties[PROP_ID] = "next";
next_previous->h = 40;
next_previous->setParent(m_irrlicht_window);
m_children.push_back(next_previous);
next_previous->add();
next_previous = new IconButtonWidget();
next_previous->setImage("gui/back_addons.png");
next_previous->x = area_right.UpperLeftCorner.X + 20;
next_previous->y = area_right.UpperLeftCorner.Y +20 ;
next_previous->w = 75;
next_previous->m_properties[PROP_ID] = "previous";
next_previous->h = 40;
next_previous->setParent(m_irrlicht_window);
m_children.push_back(next_previous);
next_previous->add();
name = new LabelWidget();
name->m_text = StringUtils::insertValues(_("Name: %i"), this->addons->GetName().c_str());
name->x = area_left.UpperLeftCorner.X;
name->y = area_left.UpperLeftCorner.Y;
name->w = area_left.getWidth();
name->h = area_left.getHeight()/6;
name->setParent(m_irrlicht_window);
m_children.push_back(name);
name->add();
description = new LabelWidget();
description->m_properties[PROP_WORD_WRAP] = "true";
description->x = area_left.UpperLeftCorner.X;
description->y = area_left.UpperLeftCorner.Y + area_left.getHeight()/6;
description->w = area_left.getWidth();
description->h = area_left.getHeight()/3;
description->setParent(m_irrlicht_window);
description->m_text = StringUtils::insertValues(_("Description: %i"), this->addons->GetDescription().c_str());
description->add();
version = new LabelWidget();
version->x = area_left.UpperLeftCorner.X;
version->y = area_left.UpperLeftCorner.Y + area_left.getHeight()/6 + area_left.getHeight()/3;
version->m_text = StringUtils::insertValues(_("Version: %i"), this->addons->GetVersionAsStr().c_str());
version->w = area_left.getWidth();
version->h = area_left.getHeight()/3;
version->setParent(m_irrlicht_window);
m_children.push_back(version);
version->add();
m_children.push_back(description);
this->loadInfo();
}
void AddonsLoading::loadInfo()
{
core::rect< s32 > area_right(10, 0, m_area.getWidth()/2, m_area.getHeight());
core::rect< s32 > area_left(m_area.getWidth()/2 + 20, 0, m_area.getWidth(), m_area.getHeight());
/*I think we can wait a little to have the icon ?*/
download("icon/" + this->addons->GetIcon(), this->addons->GetName() + ".png");
icon->setImage(std::string(file_manager->getConfigDir() + "/" + this->addons->GetName() + ".png").c_str(), IconButtonWidget::ICON_PATH_TYPE_ABSOLUTE);
icon->x = area_right.UpperLeftCorner.X;
icon->y = area_right.UpperLeftCorner.Y;
icon->w = m_area.getWidth()/2;
icon->h = m_area.getHeight();
icon->setParent(m_irrlicht_window);
m_children.push_back(icon);
icon->add();
name->setText(StringUtils::insertValues(_("Name: %i"), this->addons->GetName().c_str()));
description->setText(StringUtils::insertValues(_("Description: %i"), this->addons->GetDescription().c_str()));
version->setText(StringUtils::insertValues(_("Version: %i"), this->addons->GetVersionAsStr().c_str()));
this->back_button = new ButtonWidget();
/*this->back_button->setLabel(std::string("Back").c_str());*/
this->back_button->m_text = _("Back");
this->back_button->m_properties[PROP_ID] = "cancel";
this->back_button->x = 20;
this->back_button->y = m_area.getHeight()-45;
this->back_button->setParent(m_irrlicht_window);
m_children.push_back(this->back_button);
this->back_button->w = 150;
this->back_button->h = 35;
this->back_button->add();
this->install_button = new ButtonWidget();
/*this->back_button->setLabel(std::string("Back").c_str());*/
if(this->addons->IsInstalled() == "yes")
this->install_button->m_text = _("Uninstall");
else
this->install_button->m_text = _("Install");
this->install_button->m_properties[PROP_ID] = "install";
this->install_button->x = m_area.getWidth()-170;
this->install_button->y = m_area.getHeight()-45;
this->install_button->setParent(m_irrlicht_window);
m_children.push_back(this->install_button);
this->install_button->w = 150;
this->install_button->h = 35;
this->install_button->add();
}
// ------------------------------------------------------------------------------------------------------
GUIEngine::EventPropagation AddonsLoading::processEvent(const std::string& eventSource)
{
if(eventSource == "cancel")
{
//input_manager->setMode(InputManager::MENU);
dismiss();
//return GUIEngine::EVENT_BLOCK;
}
else if(eventSource == "next")
{
this->addons->NextType(this->addons->GetType());
this->loadInfo();
}
else if(eventSource == "previous")
{
this->addons->PreviousType(this->addons->GetType());
this->loadInfo();
}
if(eventSource == "install")
{
this->back_button->setDeactivated();
this->install_button->setDeactivated();
pthread_t thread;
pthread_create(&thread, NULL, &AddonsLoading::startInstall, this);
}
return GUIEngine::EVENT_LET;
}
// ------------------------------------------------------------------------------------------------------
void AddonsLoading::close()
{
GUIEngine::Screen* curr_screen = GUIEngine::getCurrentScreen();
pthread_mutex_lock(&(((AddonsScreen*)curr_screen)->mutex));
((AddonsScreen*)curr_screen)->can_load_list = true;
pthread_mutex_unlock(&(((AddonsScreen*)curr_screen)->mutex));
dismiss();
std::cout << "unlock the mutex" << std::endl;
}
// ------------------------------------------------------------------------------------------------------
void * AddonsLoading::startInstall(void* pthis)
{
AddonsLoading * obj = (AddonsLoading*)pthis;
if(obj->addons->IsInstalled() == "yes")
{
std::cout << obj->addons->IsInstalled() << std::endl;
obj->addons->UnInstall();
}
else
{
obj->addons->Install();
}
obj->close();
return NULL;
}
// ------------------------------------------------------------------------------------------------------
void * AddonsLoading::downloadIcon(void* pthis)
{
/*
AddonsLoading * obj = (AddonsLoading*)pthis;
download("icon/" + obj->addons->GetIcon(), obj->addons->GetName() + ".png");
obj->icon->setImage(std::string(file_manager->getConfigDir() + "/" + obj->addons->GetName() + ".png").c_str(), IconButtonWidget::ICON_PATH_TYPE_ABSOLUTE);
obj->icon->setImage(std::string(file_manager->getConfigDir() + "/" + obj->addons->GetName() + ".png").c_str(), IconButtonWidget::ICON_PATH_TYPE_ABSOLUTE);
obj->icon->x = 0;
obj->icon->y = 0;
obj->icon->w = obj->m_area.getWidth()/2;
obj->icon->h = obj->m_area.getHeight();
obj->icon->setParent(obj->m_irrlicht_window);
obj->m_children.push_back(obj->icon);
obj->icon->add();*/
return NULL;
}
#endif

View File

@ -0,0 +1,55 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2010 Lucas Baudin
//
// 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.
#ifdef ADDONS_MANAGER
#ifndef HEADER_ADDONS_LOADING_HPP
#define HEADER_ADDONS_LOADING_HPP
#include "guiengine/modaldialog.hpp"
#include "addons/addons.hpp"
#include "guiengine/widgets.hpp"
#include <pthread.h>
class AddonsLoading : public GUIEngine::ModalDialog
{
//virtual void escapePressed() {};
private:
GUIEngine::LabelWidget * name;
GUIEngine::LabelWidget * description;
GUIEngine::LabelWidget * version;
GUIEngine::LabelWidget * author;
GUIEngine::ButtonWidget * back_button;
GUIEngine::ButtonWidget * install_button;
GUIEngine::IconButtonWidget * icon;
static void * startInstall(void*);
static void * downloadIcon(void*);
pthread_mutex_t mutex;
void loadInfo();
public:
/**
* Creates a modal dialog with given percentage of screen width and height
*/
Addons * addons;
AddonsLoading(Addons * id, const float percentWidth, const float percentHeight);
GUIEngine::EventPropagation processEvent(const std::string& eventSource);
void close();
};
#endif
#endif

View File

@ -27,27 +27,59 @@
#include "states_screens/kart_selection.hpp"
#include "states_screens/help_screen_1.hpp"
#include "states_screens/options_screen_video.hpp"
#include "states_screens/addons_screen.hpp"
#include "states_screens/state_manager.hpp"
#include "io/file_manager.hpp"
// FIXME : remove, temporary test
#include "states_screens/feature_unlocked.hpp"
#include "states_screens/grand_prix_lose.hpp"
#include "states_screens/grand_prix_win.hpp"
#include "addons/network.hpp"
#include "tracks/track_manager.hpp"
#include "tracks/track.hpp"
#include <iostream>
#include <string>
#include <pthread.h>
using namespace GUIEngine;
DEFINE_SCREEN_SINGLETON( MainMenuScreen );
// ------------------------------------------------------------------------------------------------------
#ifdef ADDONS_MANAGER
MainMenuScreen::MainMenuScreen() : Screen("mainaddons.stkgui")
{
}
#else
MainMenuScreen::MainMenuScreen() : Screen("main.stkgui")
{
}
#endif
#ifdef ADDONS_MANAGER
void MainMenuScreen::downloadRss()
{
LabelWidget* w = this->getWidget<LabelWidget>("info_addons");
FILE* fichier = NULL;
char chaine[1000] = "";
fichier = fopen(std::string(file_manager->getConfigDir() + "/news").c_str(), "r+");
std::string info = std::string("");
while (fgets(chaine, 1000, fichier) != NULL) // On lit le fichier tant qu'on ne reçoit pas d'erreur (NULL)
{
info += std::string(chaine);
}
fclose(fichier);
// to remove the break line.
//info.replace(info.size()-1,1, "");
std::cout << info << std::endl;
w->setText(std::string(info).c_str());
}
#endif
// ------------------------------------------------------------------------------------------------------
void MainMenuScreen::loadedFromFile()
@ -55,13 +87,17 @@ void MainMenuScreen::loadedFromFile()
}
// ------------------------------------------------------------------------------------------------------
//
void MainMenuScreen::init()
{
// reset in case we're coming back from a race
StateManager::get()->resetActivePlayers();
input_manager->getDeviceList()->setAssignMode(NO_ASSIGN);
input_manager->setMasterPlayerOnly(false);
#ifdef ADDONS_MANAGER
pthread_t nThreadID2;
pthread_create(&nThreadID2, NULL, &MainMenuScreen::downloadNews, this);
#endif
}
// ------------------------------------------------------------------------------------------------------
@ -150,7 +186,24 @@ void MainMenuScreen::eventCallback(Widget* widget, const std::string& name, cons
{
StateManager::get()->pushScreen(ChallengesScreen::getInstance());
}
#ifdef ADDONS_MANAGER
else if (selection == "addons")
{
std::cout << "Addons" << std::endl;
StateManager::get()->pushScreen(AddonsScreen::getInstance());
}
#endif
}
#ifdef ADDONS_MANAGER
// ------------------------------------------------------------------------------------------------------
void * MainMenuScreen::downloadNews( void * pthis)
{
download("news");
MainMenuScreen * pt = (MainMenuScreen*)pthis;
pt->downloadRss();
return NULL;
}
#endif
// ------------------------------------------------------------------------------------------------------

View File

@ -32,6 +32,7 @@ class MainMenuScreen : public GUIEngine::Screen, public GUIEngine::ScreenSinglet
MainMenuScreen();
public:
void downloadRss();
/** \brief implement callback from parent class GUIEngine::Screen */
virtual void loadedFromFile();
@ -43,6 +44,10 @@ public:
/** \brief implement callback from parent class GUIEngine::Screen */
virtual void tearDown();
/** This function is used to download a text from the server to show the news. */
static void * downloadNews(void *);
};
#endif