[OregonCore]Encore cette commande !
Bon ben me revoilà avec ma commande Smile Sauf que cette fois c'est en production ! Sur mon serveur linux , le code est le suivant

[code=cpp]bool ChatHandler::HandleRecupAllCommand(const char* args)
{
if(!*args)
{
return false;
}
Player *pPlayer = m_session->GetPlayer();
uint32 pGUID = pPlayer->GetGUID();

uint32 ID_command = atoi(args);

QueryResult_AutoPtr sac = CharacterDatabase.PQuery("SELECT bag FROM new_recup WHERE PGUID = %u" , pGUID);
if(sac->Fetch()->GetUInt32() == 0)
{
PSendSysMessage("Vous n'avez pas récupérés vos sac !");
return false;
}

QueryResult_AutoPtr id_command = CharacterDatabase.PQuery("SELECT id_command FROM new_recup WHERE PGUID = %u" , pGUID);
if (id_command->Fetch()->GetUInt32() != atoi(args))
{
PSendSysMessage("L'id de votre commande n'est pas bon , veuillez entrer le bon : %u" , id_command->Fetch()->GetString());
return false;
}
else
{
/*===== OBJETS === */

//On récupère l'id du set
QueryResult_AutoPtr id_set = CharacterDatabase.PQuery("SELECT id_set FROM new_recup WHERE id_command = %u" , ID_command);
uint32 tmp = id_set->Fetch()->GetUInt32();
QueryResult_AutoPtr results2 = CharacterDatabase.PQuery("SELECT id_objet FROM recup_datas WHERE id_set = %u" , tmp);
do
{
Field* fields = results2->Fetch();
args = (char*)fields[0].GetString();
ChatHandler::HandleAddItemCommand(args);
}
while(results2->NextRow());

/* ==== LVL + MONEY === */
pPlayer->SetLevel(70);
pPlayer->SetMoney(30000000);//3000 po


/* === MONTURES ====*/
QueryResult_AutoPtr mountComp = CharacterDatabase.PQuery("SELECT MountComp FROM new_recup WHERE PGUID = %u" , pGUID);
switch(mountComp->Fetch()->GetUInt32())
{
case 75:
pPlayer->learnSpell(33388);
break;
case 150:
pPlayer->learnSpell(33391);
break;
case 225:
pPlayer->learnSpell(34090);
break;
case 300:
pPlayer->learnSpell(34091);
break;
}

/* ==== PREMIER METIER ==== */

QueryResult_AutoPtr QFirstWork = CharacterDatabase.PQuery("SELECT FirstWork FROM new_recup WHERE id_command = %u" , id_command);
QueryResult_AutoPtr QFirstWorkLvl = CharacterDatabase.PQuery("SELECT FirstWorkLvl FROM new_recup WHERE id_command = %u" , id_command);
QueryResult_AutoPtr QFirstWorkSpell;
uint32 FirstWorkId;
uint32 FirstWorkLevel;
uint32 FirstWorkSpell;

if(QFirstWork->Fetch() && QFirstWorkLvl->Fetch())
{
FirstWorkId = QFirstWork->Fetch()->GetUInt32();
FirstWorkLevel = QFirstWorkLvl->Fetch()->GetUInt32();
QFirstWorkSpell = CharacterDatabase.PQuery("SELECT Spell FROM recup_work_data WHERE Work = %u AND Lvl = %u" , FirstWorkId , FirstWorkLevel);
}
else {
sLog.outString("Tes fetch() marchent pas Clin");
return false;
}
if(QFirstWorkSpell->Fetch())
FirstWorkSpell = QFirstWorkSpell->Fetch()->GetUInt32();

pPlayer->learnSpell(FirstWorkSpell);
pPlayer->SetSkill(FirstWorkId , FirstWorkLevel , FirstWorkLevel);

/* ==== DEUXIEME METIER === */

QueryResult_AutoPtr QSecondWork = CharacterDatabase.PQuery("SELECT SecondWork FROM new_recup WHERE id_command = %u" , id_command);
QueryResult_AutoPtr QSecondWorkLvl = CharacterDatabase.PQuery("SELECT SecondWorkLvl FROM new_recup WHERE id_command = %u" , id_command);
QueryResult_AutoPtr QSecondWorkSpell;
uint32 SecondWorkId;
uint32 SecondWorkLevel;
uint32 SecondWorkSpell;

if(QSecondWork->Fetch() && QSecondWorkLvl->Fetch())
{
SecondWorkId = QSecondWork->Fetch()->GetUInt32();
SecondWorkLevel = QSecondWorkLvl->Fetch()->GetUInt32();
QSecondWorkSpell = CharacterDatabase.PQuery("SELECT Spell FROM recup_work_data WHERE Work = %u AND Lvl = %u" , SecondWorkId , SecondWorkLevel);
}
else {
sLog.outString("Tes fetch() marchent pas Clin");
return false;
}
if(QSecondWorkSpell->Fetch())
SecondWorkSpell = QSecondWorkSpell->Fetch()->GetUInt32();

pPlayer->learnSpell(SecondWorkSpell);
pPlayer->SetSkill(SecondWorkId , SecondWorkLevel , SecondWorkLevel);

/* ==== METIER SECONDAIRE = */

QueryResult_AutoPtr QSecondaryWork = CharacterDatabase.PQuery("SELECT SecondaryWork FROM new_recup WHERE id_command = %u" , id_command);
QueryResult_AutoPtr QSecondaryWorkLvl = CharacterDatabase.PQuery("SELECT SecondaryWorkLvl FROM new_recup WHERE id_command = %u" , id_command);
QueryResult_AutoPtr QSecondaryWorkSpell;
uint32 SecondaryWorkId;
uint32 SecondaryWorkLevel;
uint32 SecondaryWorkSpell;

if(QSecondaryWork->Fetch() && QSecondaryWorkLvl->Fetch())
{
SecondaryWorkId = QSecondaryWork->Fetch()->GetUInt32();
SecondaryWorkLevel = QSecondaryWorkLvl->Fetch()->GetUInt32();
QSecondaryWorkSpell = CharacterDatabase.PQuery("SELECT Spell FROM recup_work_data WHERE Work = %u AND Lvl = %u" , SecondaryWorkId , SecondaryWorkLevel);
}
else {
sLog.outString("Tes fetch() marchent pas Clin");
return false;
}
if(QSecondaryWorkSpell->Fetch())
SecondaryWorkSpell = QSecondaryWorkSpell->Fetch()->GetUInt32();

pPlayer->learnSpell(SecondaryWorkSpell);
pPlayer->SetSkill(SecondaryWorkId , SecondaryWorkLevel , SecondaryWorkLevel);

/* ==== REP VILLE BASSE === */
QueryResult_AutoPtr villeBasse = CharacterDatabase.PQuery("SELECT RepVilleBasse FROM new_recup WHERE id_command = %u" , id_command);
if(villeBasse->Fetch()->GetUInt32() > 0)
{
std::stringstream outvb;
outvb << "1011 " << villeBasse->Fetch()->GetUInt32();
ChatHandler::HandleModifyRepCommand(outvb.str().c_str());
}
/* ==== REP SHATAR ======== */
QueryResult_AutoPtr Shatar = CharacterDatabase.PQuery("SELECT RepShatar FROM new_recup WHERE id_command = %u" , id_command);
if(Shatar->Fetch()->GetUInt32() > 0)
{
std::stringstream outs;
outs << "935 " << villeBasse->Fetch()->GetUInt32();
ChatHandler::HandleModifyRepCommand(outs.str().c_str());
}
/* ==== REP THRALLMAR ===== */
QueryResult_AutoPtr Thrallmar = CharacterDatabase.PQuery("SELECT RepThrallmar FROM new_recup WHERE id_command = %u" , id_command);
if(Thrallmar->Fetch()->GetUInt32() > 0)
{
std::stringstream outt;
outt << "947 " << villeBasse->Fetch()->GetUInt32();
ChatHandler::HandleModifyRepCommand(outt.str().c_str());
}

/* ==== REP CENARIENNE ==== */
QueryResult_AutoPtr RepCenarienne = CharacterDatabase.PQuery("SELECT RepCenarienne FROM new_recup WHERE id_command = %u" , id_command);
if(RepCenarienne->Fetch()->GetUInt32() > 0)
{
std::stringstream outc;
outc << "942 " << villeBasse->Fetch()->GetUInt32();
ChatHandler::HandleModifyRepCommand(outc.str().c_str());
}
/* ==== REP GARDIENS ====== */
QueryResult_AutoPtr RepGardiens = CharacterDatabase.PQuery("SELECT RepGardiens FROM new_recup WHERE id_command = %u" , id_command);
if(RepGardiens->Fetch()->GetUInt32() > 0)
{
std::stringstream outg;
outg << "989 " << villeBasse->Fetch()->GetUInt32();
ChatHandler::HandleModifyRepCommand(outg.str().c_str());
}
args = NULL;
ChatHandler::HandleMaxSkillCommand(args);

CharacterDatabase.PQuery("DELETE FROM new_recup WHERE PGUID = %u" , pGUID);
return true;
}
}[/code]

Donc quand j'utilise gdb il me dit bien que le crash vient de cette fonction , sauf que je sais pas comment faire pour qu'il me donne la ligne . Si vous aviez une idée ? :/
lance un bt full sur gdb
Entre temps j'ai compris comment avoir la ligne du crash , donc ça m'a donné ça :

[code=cpp]0x08569a70 in ChatHandler::HandleRecupAllCommand (this=0xb0f9f148,
args=0xf6218ff "15")
at /home/asedic/old/src/ham-s-project/src/game/Level0.cpp:377
377 QueryResult_AutoPtr QFirstWork = CharacterDatabase.PQuery("SELECT FirstWork FROM new_recup WHERE id_command = %u" , id_command);
[/code]

Donc j'ai changé mon code par :

[code=cpp]/* ==== PREMIER METIER ==== */

QueryResult_AutoPtr QFirstWork = CharacterDatabase.PQuery("SELECT FirstWork FROM new_recup WHERE id_command = %u" , ID_command);
QueryResult_AutoPtr QFirstWorkLvl = CharacterDatabase.PQuery("SELECT FirstWorkLvl FROM new_recup WHERE id_command = %u" , ID_command);
QueryResult_AutoPtr QFirstWorkSpell;
uint32 FirstWorkId;
uint32 FirstWorkLevel;
uint32 FirstWorkSpell;

if(QFirstWork->Fetch() && QFirstWorkLvl->Fetch())
{
FirstWorkId = QFirstWork->Fetch()->GetUInt32();
FirstWorkLevel = QFirstWorkLvl->Fetch()->GetUInt32();
QFirstWorkSpell = CharacterDatabase.PQuery("SELECT Spell FROM recup_work_data WHERE Work = %u AND Lvl = %u" , FirstWorkId , FirstWorkLevel);
}
if(QFirstWorkSpell->Fetch())
FirstWorkSpell = QFirstWorkSpell->Fetch()->GetUInt32();

pPlayer->learnSpell(FirstWorkSpell);
pPlayer->SetSkill(FirstWorkId , FirstWorkLevel , FirstWorkLevel);[/code]

cette fois j'ai test sur mon pc , ça crash toujours mais j'arrive pas debugger ça me fais choisir une nouvelle instance et il utilise pas le code Erf Comment on peut changer ça ?
Édition :
Résolu , voici le code final Heureux

[code=cpp]bool ChatHandler::HandleRecupAllCommand(const char* args)
{

Player *pPlayer = m_session->GetPlayer();
uint32 pGUID = pPlayer->GetGUID();
uint32 ID_command;

QueryResult_AutoPtr sac = CharacterDatabase.PQuery("SELECT bag FROM new_recup WHERE PGUID = %u" , pGUID);
if(sac->Fetch()->GetUInt32() == 0)
{
PSendSysMessage("Vous n'avez pas récupérés vos sac !");
return false;
}


QueryResult_AutoPtr id_command = CharacterDatabase.PQuery("SELECT id_command FROM new_recup WHERE PGUID = %u" , pGUID);
if (id_command->Fetch())
ID_command = id_command->Fetch()->GetUInt32();

else return false;
/*===== OBJETS === */

//On récupère l'id du set
QueryResult_AutoPtr id_set = CharacterDatabase.PQuery("SELECT id_set FROM new_recup WHERE id_command = %u" , ID_command);
uint32 tmp = id_set->Fetch()->GetUInt32();
QueryResult_AutoPtr results2 = CharacterDatabase.PQuery("SELECT id_objet FROM recup_datas WHERE id_set = %u" , tmp);
do
{
Field* fields = results2->Fetch();
args = (char*)fields[0].GetString();
ChatHandler::HandleAddItemCommand(args);
}
while(results2->NextRow());

/* ==== LVL + MONEY === */
pPlayer->SetLevel(70);
pPlayer->SetMoney(30000000);//3000 po


/* === MONTURES ====*/
QueryResult_AutoPtr mountComp = CharacterDatabase.PQuery("SELECT MountComp FROM new_recup WHERE PGUID = %u" , pGUID);
if(mountComp->Fetch())
{
switch(mountComp->Fetch()->GetUInt32())
{
case 75:
pPlayer->learnSpell(33388);
break;
case 150:
pPlayer->learnSpell(33391);
break;
case 225:
pPlayer->learnSpell(34090);
break;
case 300:
pPlayer->learnSpell(34091);
break;
}
}

/* ==== PREMIER METIER ==== */

QueryResult_AutoPtr QFirstWork = CharacterDatabase.PQuery("SELECT FirstWork FROM new_recup WHERE id_command = %u" , ID_command);
QueryResult_AutoPtr QFirstWorkLvl = CharacterDatabase.PQuery("SELECT FirstWorkLvl FROM new_recup WHERE id_command = %u" , ID_command);
QueryResult_AutoPtr QFirstWorkSpell;
uint32 FirstWorkId;
uint32 FirstWorkLevel;
uint32 FirstWorkSpell;

if(QFirstWork->Fetch() && QFirstWorkLvl->Fetch())
{
if(QFirstWork->Fetch()->GetUInt32() != 0 && QFirstWorkLvl->Fetch()->GetUInt32() != 0)
{
FirstWorkId = QFirstWork->Fetch()->GetUInt32();
FirstWorkLevel = QFirstWorkLvl->Fetch()->GetUInt32();
QFirstWorkSpell = CharacterDatabase.PQuery("SELECT Spell FROM recup_work_data WHERE Work = %u AND Lvl = %u" , FirstWorkId , FirstWorkLevel);

if(QFirstWorkSpell->Fetch())
{
FirstWorkSpell = QFirstWorkSpell->Fetch()->GetUInt32();

pPlayer->learnSpell(FirstWorkSpell);
pPlayer->SetSkill(FirstWorkId , FirstWorkLevel , FirstWorkLevel);
}
}
}

/* ==== DEUXIEME METIER === */

QueryResult_AutoPtr QSecondWork = CharacterDatabase.PQuery("SELECT SecondWork FROM new_recup WHERE id_command = %u" , ID_command);
QueryResult_AutoPtr QSecondWorkLvl = CharacterDatabase.PQuery("SELECT SecondWorkLvl FROM new_recup WHERE id_command = %u" , ID_command);
QueryResult_AutoPtr QSecondWorkSpell;
uint32 SecondWorkId;
uint32 SecondWorkLevel;
uint32 SecondWorkSpell;

if(QSecondWork->Fetch() && QSecondWorkLvl->Fetch())
{
if(QSecondWork->Fetch()->GetUInt32() != 0 && QSecondWorkLvl->Fetch()->GetUInt32() != 0)
{
SecondWorkId = QSecondWork->Fetch()->GetUInt32();
SecondWorkLevel = QSecondWorkLvl->Fetch()->GetUInt32();
QSecondWorkSpell = CharacterDatabase.PQuery("SELECT Spell FROM recup_work_data WHERE Work = %u AND Lvl = %u" , SecondWorkId , SecondWorkLevel);

if(QSecondWorkSpell->Fetch())
{
SecondWorkSpell = QSecondWorkSpell->Fetch()->GetUInt32();

pPlayer->learnSpell(SecondWorkSpell);
pPlayer->SetSkill(SecondWorkId , SecondWorkLevel , SecondWorkLevel);
}
}
}

/* ==== METIER SECONDAIRE = */

QueryResult_AutoPtr QSecondaryWork = CharacterDatabase.PQuery("SELECT SecondaryWork FROM new_recup WHERE id_command = %u" , ID_command);
QueryResult_AutoPtr QSecondaryWorkLvl = CharacterDatabase.PQuery("SELECT SecondaryWorkLvl FROM new_recup WHERE id_command = %u" , ID_command);
QueryResult_AutoPtr QSecondaryWorkSpell;
uint32 SecondaryWorkId;
uint32 SecondaryWorkLevel;
uint32 SecondaryWorkSpell;

if(QSecondaryWork->Fetch() && QSecondaryWorkLvl->Fetch())
{
if(QSecondaryWork->Fetch()->GetUInt32() != 0 && QSecondaryWorkLvl->Fetch()->GetUInt32() != 0)
{
SecondaryWorkId = QSecondaryWork->Fetch()->GetUInt32();
SecondaryWorkLevel = QSecondaryWorkLvl->Fetch()->GetUInt32();
QSecondaryWorkSpell = CharacterDatabase.PQuery("SELECT Spell FROM recup_work_data WHERE Work = %u AND Lvl = %u" , SecondaryWorkId , SecondaryWorkLevel);

if(QSecondaryWorkSpell->Fetch())
{
SecondaryWorkSpell = QSecondaryWorkSpell->Fetch()->GetUInt32();

pPlayer->learnSpell(SecondaryWorkSpell);
pPlayer->SetSkill(SecondaryWorkId , SecondaryWorkLevel , SecondaryWorkLevel);
}
}
}

/* ==== REP VILLE BASSE === */
QueryResult_AutoPtr villeBasse = CharacterDatabase.PQuery("SELECT RepVilleBasse FROM new_recup WHERE id_command = %u" , ID_command);
if(villeBasse->Fetch()->GetUInt32() > 0)
{
std::stringstream outvb;
outvb << "1011 " << villeBasse->Fetch()->GetUInt32();
ChatHandler::HandleModifyRepCommand(outvb.str().c_str());
}
/* ==== REP SHATAR ======== */
QueryResult_AutoPtr Shatar = CharacterDatabase.PQuery("SELECT RepShatar FROM new_recup WHERE id_command = %u" , ID_command);
if(Shatar->Fetch()->GetUInt32() > 0)
{
std::stringstream outs;
outs << "935 " << villeBasse->Fetch()->GetUInt32();
ChatHandler::HandleModifyRepCommand(outs.str().c_str());
}
/* ==== REP THRALLMAR ===== */
QueryResult_AutoPtr Thrallmar = CharacterDatabase.PQuery("SELECT RepThrallmar FROM new_recup WHERE id_command = %u" , ID_command);
if(Thrallmar->Fetch()->GetUInt32() > 0)
{
std::stringstream outt;
outt << "947 " << villeBasse->Fetch()->GetUInt32();
ChatHandler::HandleModifyRepCommand(outt.str().c_str());
}

/* ==== REP CENARIENNE ==== */
QueryResult_AutoPtr RepCenarienne = CharacterDatabase.PQuery("SELECT RepCenarienne FROM new_recup WHERE id_command = %u" , ID_command);
if(RepCenarienne->Fetch()->GetUInt32() > 0)
{
std::stringstream outc;
outc << "942 " << villeBasse->Fetch()->GetUInt32();
ChatHandler::HandleModifyRepCommand(outc.str().c_str());
}
/* ==== REP GARDIENS ====== */
QueryResult_AutoPtr RepGardiens = CharacterDatabase.PQuery("SELECT RepGardiens FROM new_recup WHERE id_command = %u" , ID_command);
if(RepGardiens->Fetch()->GetUInt32() > 0)
{
std::stringstream outg;
outg << "989 " << villeBasse->Fetch()->GetUInt32();
ChatHandler::HandleModifyRepCommand(outg.str().c_str());
}
args = NULL;
ChatHandler::HandleMaxSkillCommand(args);

CharacterDatabase.PQuery("UPDATE new_recup SET done = 1 WHERE PGUID = %u" , pGUID);
return true;

}[/code]
A mon avis ça manque un peu de NULL check tous ça en passant, ça peut t'éviter des crash du genre.
(02-07-2011 18:27)Sadikum a écrit :  A mon avis ça manque un peu de NULL check tous ça en passant, ça peut t'éviter des crash du genre.

Oui j'ai remarqué ! Bon sinon je réouvre car là c'est le gros bordel . Vous vous souvenez de mes problèmes de crash a la déconnection ? Eh bien c'est revenu depuis que j'ai mis en place ma commande

Vous voulez le bt ?

Citation :#0 0xb79795ab in ?? () from /lib/i686/cmov/libc.so.6
#1 0xb797b7ed in ?? () from /lib/i686/cmov/libc.so.6
#2 0xb797dc8c in malloc () from /lib/i686/cmov/libc.so.6
#3 0xb7981150 in strdup () from /lib/i686/cmov/libc.so.6
#4 0x08578153 in bool Database::AsyncQuery<CharacterHandler, unsigned int>(CharacterHandler*, void (CharacterHandler::*)(ACE_Refcounted_Auto_Ptr<QueryResult, ACE_Null_Mutex>, unsigned int), unsigned int, char const*) ()
#5 0x085782e5 in bool Database::AsyncPQuery<CharacterHandler, unsigned int>(CharacterHandler*, void (CharacterHandler::*)(ACE_Refcounted_Auto_Ptr<QueryResult, ACE_Null_Mutex>, unsigned int), unsigned int, char const*, ...) ()
#6 0x085777ae in WorldSession::HandleCharEnumOpcode (this=0xd3ccdf8)
at /home/asedic/old/src/ham-s-project/src/game/CharacterHandler.cpp:189
#7 0x08228ce4 in WorldSession::ExecuteOpcode (this=0xd3ccdf8, diff=50)
at /home/asedic/old/src/ham-s-project/src/game/WorldSession.cpp:562
#8 WorldSession::Update (this=0xd3ccdf8, diff=50)
at /home/asedic/old/src/ham-s-project/src/game/WorldSession.cpp:231
#9 0x08379c36 in World::UpdateSessions (this=0x8a685f0, diff=50)
at /home/asedic/old/src/ham-s-project/src/game/World.cpp:2263
#10 0x0837ad05 in World::Update (this=0x8a685f0, diff=50)
at /home/asedic/old/src/ham-s-project/src/game/World.cpp:1706
#11 0x081bb797 in WorldRunnable::run (this=0xb35ee58)
at /home/asedic/old/src/ham-s-project/src/oregoncore/WorldRunnable.cpp:56
#12 0x085c3f22 in ACE_Based::Thread::ThreadTask (param=0xb35ee58)

Le bt full ?

Citation :#0 0xb79795ab in ?? () from /lib/i686/cmov/libc.so.6
No symbol table info available.
#1 0xb797b7ed in ?? () from /lib/i686/cmov/libc.so.6
No symbol table info available.
#2 0xb797dc8c in malloc () from /lib/i686/cmov/libc.so.6
No symbol table info available.
#3 0xb7981150 in strdup () from /lib/i686/cmov/libc.so.6
No symbol table info available.
#4 0x08578153 in bool Database::AsyncQuery<CharacterHandler, unsigned int>(CharacterHandler*, void (CharacterHandler::*)(ACE_Refcounted_Auto_Ptr<QueryResult, ACE_Null_Mutex>, unsigned int), unsigned int, char const*) ()
No symbol table info available.
#5 0x085782e5 in bool Database::AsyncPQuery<CharacterHandler, unsigned int>(CharacterHandler*, void (CharacterHandler::*)(ACE_Refcounted_Auto_Ptr<QueryResult, ACE_Null_Mutex>, unsigned int), unsigned int, char const*, ...) ()
No symbol table info available.
#6 0x085777ae in WorldSession::HandleCharEnumOpcode (this=0xd3ccdf8)
at /home/asedic/old/src/ham-s-project/src/game/CharacterHandler.cpp:189
No locals.
#7 0x08228ce4 in WorldSession::ExecuteOpcode (this=0xd3ccdf8, diff=50)
at /home/asedic/old/src/ham-s-project/src/game/WorldSession.cpp:562
No locals.
#8 WorldSession::Update (this=0xd3ccdf8, diff=50)

Donc ça crash toujours a la déconnection , d'après ce que j'ai pu lire dans le code , ça serait a la réception d'un packet pas bon qui empècherai le world de s'updater (ça reste que des suppositions) . EN TOUT CAS JEN AI MARRE
ABandonen oregon reste en 3.3.5
Je pense que je vais tout arreter quand je vois comment c'est la merde !
Édition :
Up ??
Asedic met des log dans tout ce qui est succéptible de faire crash, j’espère que tu trouveras la fonction qui bug =)
bah j'ai trouvé je sais que c'est dans l'update du world matte le bt Clin Après je sais pas vraiment pourquoi :/ Elmsroth m'a conseillé de recoder ma commande un peu mieux c'est assez sale là

Retourner en haut Accueil