JeuWeb - Crée ton jeu par navigateur
Fausse bonne idée ? - Version imprimable

+- JeuWeb - Crée ton jeu par navigateur (https://jeuweb.org)
+-- Forum : Discussions, Aide, Ressources... (https://jeuweb.org/forumdisplay.php?fid=38)
+--- Forum : Programmation, infrastructure (https://jeuweb.org/forumdisplay.php?fid=51)
+--- Sujet : Fausse bonne idée ? (/showthread.php?tid=7307)

Pages : 1 2 3


Fausse bonne idée ? - Max72 - 29-01-2015

Bonsoir.


J'ai à nouveau besoin que vous n'éclairiez ma lanterne.

Je pose le contexte :

Lorsqu'un joueur se connecte, il met tout en tas de données en session (id, pseudo, ressources, dernier calcul des ressources etc).
Je précise que les sessions sont sécurisées (hashées toussa). D'ailleurs, ce sont des fausses sessions car j'utilise des cookies pour les sessions.

Ensuite, de page en page, si le joueur ne fait aucune action spéciale (construire un bâtiment etc), les ressources sont recalculées de page en page, suivant ce que le joueur a en session. En gros, le joueur peut cliquer toutes les 2 secondes sur rafraichir pendant 3 heures, aucune requête à la BDD ne sera effectuée (c'est LE but désiré).

Mais je me pose la question sur la fiabilité de ce système. Imaginons que quelqu'un arrive à péter l'algo de cryptage, il a alors les pleins pouvoir sur sa cité (recherche, ressources etc).
Le cryptage est assez balèze (je ne mettrai pas le code ici XD ) mais, à votre avis, puis-je être serein sur ce système ?

Et vous, implémentez-vous un système de ce genre ou toute la confiance doit être déléguée au serveur ?

Merci.


RE: Fausse bonne idée ? - Akira777 - 29-01-2015

Bonsoir,

C'est marrant, je me pose à peu près les mêmes questions en ce moment.
T'as pas du mal à gérer la cohérence de ta BDD quand y'a de multiples interactions entre les joueurs et que t'as besoin de mettre à jour les données du joueur connectés ?
Enfin bref, c'est pas le sujet...

Pour ma part, j'ai déjà fait un truc à peu près similaire, j'ai jamais eu de problème. En implémentant un bon système de jeton dans tes données et d'un système de somme de contrôle par dessus, j'imagine que ça peut être satisfaisant.

Après, tout en étant pragmatique, si tu t'appelais InnoGames (Guerre Tribale, Forge of Empires, ...) je pense qu'on pourrait vraiment se mettre autour d'une table. Mais bon, casser un cryptage, c'est pas à la portée de José le connard du PMU au coin de la rue. Y'aurait un réel bénéfice financier ou des milliers de joueurs, pourquoi pas... (A moins que ce soit le cas ? ^.^)

En tout cas, je suis attentif si d'autres ont des commentaires à apporter.


RE: Fausse bonne idée ? - Xenos - 30-01-2015

Parenthèse: Si ce système implique que la BDD n'est pas à jour (c'est à dire que certaines données sont dans les sessions, d'autres dans la BDD, etc), alors cela risque de rendre le tout impossible à maintenir...


Tout dépend de la façon de le réaliser.

• Si c'est un cookie qui stocke des données du joueur (ressources, batiments, etc), qu'il stocke sa propre signature (type sha256 avec un sel), et que le serveur le lit, le désérialise, vérifie sa signature et si elle correspond, considère les données du cookie comme légitimes, alors
le risque est important: des joueurs s’octroieront des ressources en modifiant ce cookie
le réseau sera surchargé: le cookie étant envoyé à chaque requête HTTP, le réseau sera ralenti et le bénéfice sera peut-être moindre
la taille des cookies est limitée: il ne faudra pas trop stocker de données dans le cookie
le cookie peut être intercepté: si la connexion n'est pas sécurisée, un pirate connaitra toutes les ressources des comptes qu'il sniffera


• Si les données sont stockées dans la session coté serveur (type $_SESSION[]), et que le joueur est rattaché à sa session via un cookie de session classique, alors, pourquoi pas, le système semble fiable.
→ Est-ce bénéfique du point de vue des perfs (car les sessions PHP sont stockées sur le disque, il me semble, et peuvent donc être plus lentes d'accès que des données SQL qui cache en RAM les derniers résultats), cela reste à voir.


• Si c'est un mix des deux, et que les données sont stockées coté client, dans un cookie, et que le serveur ne stocke que la signature du cookie (pour vérifier qu'il n'a pas été modifié), alors on doit être correct niveau sécurité.
→ On aura toujours le problème de la surcharge réseau, de la limite de taille des cookies, et de la possibilité de se faire sniffer ses cookies.



• Tout ce qui est données critiques est géré par le serveur.
→ données personnelles (email)
→ données de sécurité (pass)
→ données critiques du jeu (ressources des joueurs, unités,...)

• Le serveur peut partiellement déléguer une tâche au client et se contenter de vérifier le résultat proposé par le client
→ un algorithme de pathfinding en javascript, coté client, cherche le plus court chemin du point A au point B
→ il envoie ce chemin au serveur
→ le serveur se contente de vérifier la validité du chemin
→ le serveur se moque de savoir si le chemin envoyé par le client est le plus rapide ou non
Cela permet de décharger le serveur (il ne fait pas l'algorithme de calcul de chemin) sans rogner sur la sécurité (le serveur s'assure que le chemin est valide). Les preuves de travail fonctionnent sur ce principe.

• Le serveur peut déléguer totalement une tâche au client
→ agencement de la page du site
→ présentation (CSS)
→ toute donnée qui n'impacte en rien les autres joueurs (statistiques personnelles du joueur, comme le temps total de jeu)


RE: Fausse bonne idée ? - Max72 - 30-01-2015

Salut Akira, merci de ta réponse.

Non pas de milliers de joueurs malheureusement, le projet est encore au développement.
En effet, je me dis la même chose, mais je suis partisan du 'on sait jamais' ^^'

Sinon pour la cohérence, j'avoue que je n'en suis pas encore là, mais j'y ai déjà songé avec 2 trucs tout bêtes :
- Si interaction avec une cité (combat, pilage, ....) alors j'actualise en BDD la cité en question (donc du défenseur), et ce qu'il soit connecté ou absent depuis 6 mois. A chaque action (construction, combat, pillage, ...), la cité est mise à jour dans la DB.
- Une classe 'Events' : Classe qui gère les évènements du joueur (s'il s'est fait attaquer, piller, qu'une construction est finie) etc. Lors d'une création d'instance, tu indiques en paramètre si la cité du joueur concerné doit être recalculé ou pas.

Genre :
Code PHP :
<?php 
class Events
{

private
$recalcul;

function
__construct($type_d_evenement, $joueurs_concernes, $recalcul = false)
{
// bla bla
$this->recalcul = $recalcul;
}

function
save() {
if (
$this->recalcul)
{
// Recalcul de la cité depuis les infos de la DB
}
// Bla bla
}
}

C'est pas très clair je sais, mais je suis dans mon lit et je n'ai pas encore codé cette partie.

Edit : Grilled, je te réponds demain Xenos.


RE: Fausse bonne idée ? - Xenos - 30-01-2015

Je pense qu'être obligé d'ajouter du code (peu importe que ce soit 1000, 100, 10 ou 1 ligne) pour faire de la nanoptimisation comme celle-ci est une approche très risquée, qui risque de te complexifier bien inutilement le développement pour espérer glaner quelques millisecondes qui, de toute façon, ne seront pas utilisée: à quoi bon optimiser si le serveur n'est pas déjà à 100% de charge? Optimiser pour tourner à 70% au lieu de 85% en sacrifiant la maintenabilité et la simplicité, c'est se faire du mal pour rien...


RE: Fausse bonne idée ? - Harparine - 30-01-2015

Salutations,
Sur le principe, je trouve qu'un système de cache dédié à chacun est plutôt une bonne chose si tu n'as pas trop d'interactions entre joueurs.
La question que je me pose est "pourquoi un cookie et pas une session ?" et je rejoins Xenos sur ses remarques.
Les sessions sont plus sûres car il n'y a pas la possibilité de toucher aux données (le seul risque concerne un éventuel vol de session mais c'est un risque inhérent à tout site avec accès privé). Même remarque pour la lenteur des transferts. Enfin, dernier point en faveur des sessions : tu as la possibilité de les stocker en RAM sur un dédié avec des trucs du style Memcached. En cas de forte charge, tu t'évites des accès systématiques au disque ce qui joue pas mal sur les temps de réponse.
@+


RE: Fausse bonne idée ? - Xenos - 30-01-2015

Je dirai que le risque de vol de session est un faux-risque: si la session est volée, que les données soient en cache dans cette session ou dans la BDD, le résultat sera le même car le voleur y aura accès. Passer les données de la BDD à la session ne fait aucune différence, donc le risque de vol de session n'est pas changé.

Stocker en RAM la session et stocker dans une table HEAP sur un serveur SQL (ou laissser le SQL gérer son cache tout seul), est-ce que cela fait une véritable différence, comparé aux temps de réponses généraux (temps réseau, temps d'ouverture du worker PHP,...)?


RE: Fausse bonne idée ? - niahoo - 30-01-2015

(29-01-2015, 11:36 PM)Max72 a écrit : Ensuite, de page en page, si le joueur ne fait aucune action spéciale (construire un bâtiment etc), les ressources sont recalculées de page en page, suivant ce que le joueur a en session. En gros, le joueur peut cliquer toutes les 2 secondes sur rafraichir pendant 3 heures, aucune requête à la BDD ne sera effectuée (c'est LE but désiré).

Mais je me pose la question sur la fiabilité de ce système. Imaginons que quelqu'un arrive à péter l'algo de cryptage, il a alors les pleins pouvoir sur sa cité (recherche, ressources etc).
Le cryptage est assez balèze (je ne mettrai pas le code ici XD ) mais, à votre avis, puis-je être serein sur ce système ?

Si j'en crois le premier paragraphe, il s'agit de garder en mémoire les ressources et leur évolution. Ce n'est qu'informatif.

Si j'en crois le second paragraphe, ce n'est plus informatif : en modifiant la session le joueur peur avoir un gain : quel est-il ?


RE: Fausse bonne idée ? - Max72 - 30-01-2015

Alors, je vais tâcher de répondre dans l'ordre :

Citation :Si ce système implique que la BDD n'est pas à jour (c'est à dire que certaines données sont dans les sessions, d'autres dans la BDD, etc), alors cela risque de rendre le tout impossible à maintenir...
En fait, tant que l'utilisateur ne fait pas d'action qui modifie d'une façon ou d'une autre les ressources, tout est calculé et affiché en fonction de la session. Si une valeur vient à être modifiée fortuitement (dépense, achat, pillage, etc), alors on recalcule depuis la session et on enregistre le tout en BDD.
Pas de problème de maintenabilité, en toute franchise.

Citation : • Si c'est un mix des deux, et que les données sont stockées coté client, dans un cookie, et que le serveur ne stocke que la signature du cookie (pour vérifier qu'il n'a pas été modifié), alors on doit être correct niveau sécurité.
→ On aura toujours le problème de la surcharge réseau, de la limite de taille des cookies, et de la possibilité de se faire sniffer ses cookies.

On est dans ce cas-là :
Si le joueur a modifié son cookie (cookie unique d'ailleurs, qui contient absolument toutes les données de la session) et que ce cookie n'est pas valable (donc mauvaise signature), la session est détruite.
Niveau surcharge réseau et taille cookies on doit être bon car j'ai une quinzaine d'éléments stockées en session, qui comportent en gros des int.
Maintenant pour le sniff de cookies, c'est vrai que c'est un problème que je n'avais pas réalisé, tellement obstiné par les vols de session..

Ensuite, j'ai bel et bien mes ressources qui sont en session. Du coup si quelqu'un réussit à modifier le cookie, il peut avoir autant de ressources qu'il souhaite. Là est mon problème.

Continuons :
Citation :La question que je me pose est "pourquoi un cookie et pas une session ?" et je rejoins Xenos sur ses remarques.

Au départ, c'était parce que je les croyais plus sûr malgré que ce soit stocké chez le client. Je pensais pouvoir éviter le vol de session avec ce système.
C'est la première fois que j'utilise ce principe, et j'hésite fortement là ^^

Citation : Si j'en crois le premier paragraphe, il s'agit de garder en mémoire les ressources et leur évolution. Ce n'est qu'informatif.

Si j'en crois le second paragraphe, ce n'est plus informatif : en modifiant la session le joueur peur avoir un gain : quel est-il ?

Malheureusement, ce n'est pas qu'informatif. J'utilise les données du cookie pour ENSUITE sauvegarder en BDD.
Comme dit plus haut, si le cookie vient à être modifié correctement, le joueur peut obtenir toutes les ressources qu'il souhaite.

______________________

Concernant l'optimisation :

J'aurai dû être plus clair concernant les avantages de ce système. Je ne considère pas que ce soit de la 'nanoptimisation' car ce mécanisme m'évite non pas UNE requête à la BDD, mais plus d'une dizaine sur chaque page ainsi que des calculs.

Exemple :
J'ai pour limiter le nombre de bâtiments une système de cases.
Le joueur a ainsi 40 cases disponibles au début du jeu, qu'il peut étendre via des extensions.
Chaque bâtiment occupe un certain nombre de cases, définit dans une base de données externe (de référence, communes à tous les serveurs).

Pour déterminer le nombre de cases occupées / disponibles, rien n'est stocké en BDD. Le tout est calculé à chaque initialisation de la session, construction de bâtiment etc, selon le principe :
Cases totales = Cases initiales + extensions (extensions stockées en BDD)
Cases occupées = Parcours de TOUS les bâtiments du joueur (stockées dans plusieurs tables), puis calcul. Ce calcul requiert d'aller chercher le nombre de cases qu'occupe chaque bâtiment dans ma base de référence.
Cases libres = Cases totales - Cases occupées

Puis je stocke ces infos en session. Du coup quand je construis un bâtiment, afin d'éviter de refaire X requêtes à la BDD, j'interroge la session pour savoir s'il a assez de cases disponibles.
Et j'ai plusieurs ressources gérées comme cela.

Donc le gain est réel si 100 membres actualisent la page toutes les 2 secondes, inutile si personne ne refresh jamais.


RE: Fausse bonne idée ? - niahoo - 30-01-2015

Mais quelles mesures as-tu faites qui te permettent de dire que cette optimisation est nécessaire ? C'est clairement de l'optimisation inutile (à un stade peu avancé de l'évolution du soft). « Une dizaine de requêtes » ce n'est pas grand chose. Tu pourrais plutôt optimiser tout ça en réduisant ce nombre, mais ce n'est absolument pas utile tant que tu ne rencontres pas des problèmes à ce niveau. Et « ainsi que des calculs » ça m'étonnerait que tu calcules la millième décimale de Pi à chaque mise à jour.

Donc selon moi :

Citation :En fait, tant que l'utilisateur ne fait pas d'action qui modifie d'une façon ou d'une autre les ressources, tout est calculé et affiché en fonction de la session.

ça, ok, pourquoi pas, c'est du cache. ça ne mange pas de pain même si ça n'apporte à mon avis aucun gain notable de performance (encore une fois, fais voir tes mesures).

Citation :Si une valeur vient à être modifiée fortuitement (dépense, achat, pillage, etc), alors on recalcule depuis la session et on enregistre le tout en BDD.
ça, par contre, c'est clairement une fausse bonne idée. Déjà parce que si tu permets à tes joueurs de lancer un achat avec toutes leus PO de manière fortuite ils vont faire la gueule, ensuite parce-que tu dois décrypter des cookies cryptés à chaque requête, ce qui te fait autant perdre de temps que tu en as gagné avec ton optimisation (mais de toute façon c'est négligeable) ; les sessions sont duplicables : en l'état, si je me connecte au même compte en même temps avec deux navigateurs, puis que je fais plein d'achats dans Firefox et qu'ensuite dans Chrome je fais juste un petit achat, est-ce que tu recalcules tout simplement avec les données dans les cookies de Chrome, oubliant les modifs faites dans firefox ? Est-ce que je garde mes items achetés mais que le porte-monnaie garde juste la modification faite dans Chrome ?

À mon avis, pour toute modification tu dois recharger tes données. ça ne coûte pas grande chose et ça simplifiera pas mal de choses.