Question relations jeu en ligne/sql

Pour les scripts écrits en C#
Règles du forum
Merci de respecter la NOMENCLATURE suivante pour vos TITRES de messages :

Commencez par le niveau de vos scripts
DB = Débutant
MY = Moyen
CF = Confirmé

Puis le domaine d'application
-RS = Réseau
-AL = Algorithmie

Exemple :

[DB-RS] Mouvement perso multijoueur
Répondre
Avatar de l’utilisateur
Silverglade
Messages : 264
Inscription : 04 Août 2012 17:52

Question relations jeu en ligne/sql

Message par Silverglade » 25 Fév 2015 11:26

Hello,

(edit: j'oubliais, désolé pour le choix de la section si il n'est pas bon, je ne savais pas du tout ou mettre ça :s)

Je suis ces temps-ci sur l'étude d'un projet de jeu en ligne et je me pose certaines questions à propos des relations jeu/base de données.
Notamment, les bdd sont-elles ce qui est utilisé partout pour faire les liens jeu/clients ?

Par exemple, dans le jeu on pourra créer des prefabs à des emplacements dédiés.
Si tel joueur créer un prefab sur la place x celle-ci n'est donc plus disponible.
Je dois donc renvoyer l'état de ces emplacements (vide/occupé) aux autres joueurs et ce serait donc via une bdd ? (après lecture du forum j'utilise actuellement pour mes tests le système unity <- -> val.php <- -> bdd, qui fonctionne )

Autre domaine, pour des options payantes (ambition quand tu nous tiens... ), est-ce le même système, à savoir, utilisation d'une page de paiement internet ou serait récupérée une valeur genre $_GET["valeur"] (le get ne dépend pas de moi) qui serait envoyée dans la bdd via le log du joueur en session lors de l'achat, puis récupérée par le jeu par le même val.php ?

Et enfin, pour le tout, niveau sécurité c'est genre basique ou faut que ça casse 18 pattes à un canard ?

Merci :)

error404
Messages : 160
Inscription : 13 Nov 2010 07:51
Contact :

Re: Question relations jeu en ligne/sql

Message par error404 » 25 Fév 2015 12:35

Bonjour,

Oui, les BDD sont utilisés pour stocker les données des joueurs, les données du monde virtuel etc. après pour les gros jeux il y a certainement beaucoup d'autres choses utilisés.
Si tu veux faire un jeu en ligne temps réel, ill te faudra plus qu'une base de données.

Tu peux utiliser la classe WWW d'Unity pour transmettre / récupérer des données dans ta base. Ainsi tu peux savoir si l'emplacement est libre ou a qui il appartient. C'est assez facile à faire quand tu as déjà utilisé WWW 2 / 3 fois. C'est un simple formulaire POST qui est envoyé à un script PHP.

Pour la sécurité il faut bien faire attention. Ce que je fais dans mon cas c'est que je crypte les données (MD5 + SALT) dans le jeu et j'envoie les données cryptées à mon script PHP. Ca évite les interceptions / modifications. Ensuite je décrypte en PHP avec la clé secrète (SALT). C'est le minimum à faire si tu ne veux pas que certains joueurs s'amusent à modifier les valeurs comme bon leur semble.

Pour le paiement ben ça dépend de la solution que tu veux utiliser. Tu peux faire une page web + paypal + système de crédits et dans ta base tu sais que Joueur1 a 10 crédits par exemple. Si tu passes par une page web c'est plus facile à faire.

Avatar de l’utilisateur
Silverglade
Messages : 264
Inscription : 04 Août 2012 17:52

Re: Question relations jeu en ligne/sql

Message par Silverglade » 25 Fév 2015 13:47

Bonjour,

Merci pour les réponses :)

Pour le moyen de paiement j'ai finalisé ce matin tout fonctionne pour ce qui est de crédité une variable sur le compte d'un joueur précis.

Par contre du coup, pour récupérer la variable dans unity je passai par une page php qui ne contenait que celle-ci et me renvoyais mavaleur/100, 100 que je récupérai donc, mais ça c'était avec 1 compte.
Lorsqu'il y a plusieurs comptes forcément ça me récupère toutes les variables du même nom : mavaleur/100mavaleur/0mavaleur/10 ... etc
Et le "var datas : String[] = formText.Split("/"[0]);" dans unity ne correspond plus, et surtout donne accès à toutes les valeurs de tous les comptes.

Si je passe par la page login du site je récupère toute la page :
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> blablabla, ce qui me vas pas d'ou l'utilité de ma page php secondaire. Ma question étant comment passer une variable session de ma page login a ma page secondaire sachant que personne n'a accès à cette page secondaire (donc la session ne s'active pas, je crois) ?

Ou si pas possible, comment tronquer proprement et radicalement la page login pour arriver à ma valeur uniquement ?
Ou est ce que plus simplement un système de log dans le jeu résoudrait le problème en allant chercher seulement la variable correspondant au compte identifié dans le jeu ?

Pour la sécurité j'avais déjà survolé ça quelques part ici je crois, mais concrètement c'est donné à tout le monde d'intercepter/modifier les données ?
( Sachant que dans la page d'achat et dans la page login j'ai déjà des lignes anti-injections )

error404
Messages : 160
Inscription : 13 Nov 2010 07:51
Contact :

Re: Question relations jeu en ligne/sql

Message par error404 » 25 Fév 2015 17:41

Ca me parait compliqué la façon dont tu as géré le truc.
Le joueur doit se connecter pour pouvoir jouer ? Donc tu sais quel est l'id du joueur. Dans ta requête SQL tu peux récupérer uniquement les crédits du joueur en filtrant par son id. Normalement si tu fais bien ton script PHP, il ne te renvoie que ce que tu lui demande (pas tout le code de la page). Il peut te retourner que le montant des crédits. Un simple echo permet de renvoyer au jeu une valeur.

Pour la sécurité je répondrait que oui, presque n'importe qui peut intercepter / modifier des données. J'ai déjà eu des problèmes avec un de mes jeux avec des mecs avec un score de plusieurs milliards (je n'avais pas crypté les données). Donc mieux vaut prévenir que guérir.

Voilà comment crypter :

Code : Tout sélectionner

string hash = Md5Sum(_name + _score + secretKey).ToLower();
La fonction Md5Sum :

Code : Tout sélectionner

	
public string Md5Sum(string input)
	{
    	System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create();
    	byte[] inputBytes 	= System.Text.Encoding.ASCII.GetBytes(input);
    	byte[] hash 		= md5.ComputeHash(inputBytes);
    	StringBuilder sb = new StringBuilder();
    	for (int i = 0; i < hash.Length; i++)
    	{    	    sb.Append(hash[i].ToString("X2"));    	}
    	return sb.ToString();
	}
et en PHP :

Code : Tout sélectionner

$hash = safe($_POST['hash']);
$real_hash 	= md5($name . $score . $secretKey);
puis

Code : Tout sélectionner

if($real_hash == $hash)

Avatar de l’utilisateur
Silverglade
Messages : 264
Inscription : 04 Août 2012 17:52

Re: Question relations jeu en ligne/sql

Message par Silverglade » 25 Fév 2015 19:50

Normalement si tu fais bien ton script PHP, il ne te renvoie que ce que tu lui demande (pas tout le code de la page). Il peut te retourner que le montant des crédits. Un simple echo permet de renvoyer au jeu une valeur.
J'ai du mal m'exprimer en fait; La valeur je sais la récupérer en php, mais c'est la récupérer dans unity le problème. La seule façon que j'ai trouvé c'est sur ce forum avec script qui récupère toute la page php ou se trouve la valeur et ce dans un champs Gui.TextArea que je dois ensuite tronquer avec montext.Split("/"[0]);
Ce qui me retournais bien la bonne valeur quand je n'avais qu'un compte enregistrer.

Donc en résumé oui la connexion sera obligatoire pour poursuivre, mais justement je n'ai pas encore ce système de log.
Je comptais suivre ceci : http://forum.unity3d.com/threads/tutori ... ful.24721/ (c'est là que j'ai lu l'histoire de hash et md5 )

Je me posais une question toutefois, peut-être un peu bête : si deux joueurs font une connexion en même temps sur la page php, elle leur renverra bien leur compte respectif ?
Fin, par exemple dans le lien que j'ai cité, le check_scores.php s’exécute indépendamment pour chaque personne un peu comme des copies ou c'est le même pour tout le monde ? Je sais pas si je suis clair :?

Edit : Ma dernière question est toujours d'actualité mais pour le reste j'ai bon, j'ai finalement refais un script secondaire pour l'identification ingame en plus clair et simple par rapport au premier.
Reste à stocker les id pendant le jeux mais c'est pas ce qui a de plus dur ^^

Une autre question s'ajoute à celle pour check_score.php :
Pour sauvegarder les changements de valeur d'une variable en jeu, je dois sans arrêt envoyer une requête au serveur ?
Ca peut faire beaucoup comme trafic... il n'y a pas un autre moyen ? Genre des "auto-save" réguliers ? Car si le joueur gagne de l'argent toutes les 2 secondes ca fait une requête toutes les deux secondes. C'est pas génial multiplié par le nombre de joueurs.

error404
Messages : 160
Inscription : 13 Nov 2010 07:51
Contact :

Re: Question relations jeu en ligne/sql

Message par error404 » 26 Fév 2015 11:12

Il n'y aura pas de problèmes si deux joueurs se connectent en même temps.
Pour l'optimisation il faut bien sûr éviter de faire trop de requêtes vers le serveur. Il ne faut pas envoyer toutes les 2 secondes une variable. Il faut stocker la valeur en local (PlayerPrefs) et éventuellement faire une sauvegarde toutes les 5 minutes vers le serveur ou faire une sauvegarde quand le joueur quitte le jeu ou sauvegarde.

Avatar de l’utilisateur
Silverglade
Messages : 264
Inscription : 04 Août 2012 17:52

Re: Question relations jeu en ligne/sql

Message par Silverglade » 26 Fév 2015 11:52

Ah oui j'avais pas pensé à ça merci :D
Par contre j'en profite, je sais qu'il y a moyen très facilement d'aller changer des valeurs dans les playerspref via la base de registre, y'a un moyen d'empêcher ça ?

Avatar de l’utilisateur
LudlowFx
Messages : 1367
Inscription : 19 Sep 2013 05:50

Re: Question relations jeu en ligne/sql

Message par LudlowFx » 26 Fév 2015 12:15

Silverglade a écrit :Ah oui j'avais pas pensé à ça merci :D
Par contre j'en profite, je sais qu'il y a moyen très facilement d'aller changer des valeurs dans les playerspref via la base de registre, y'a un moyen d'empêcher ça ?
On en parlait une fois avec Arte sur le tchat (il y a un moment). Tu peux hasher ce que tu enregistres dans PlayerPrefs. C'est, en effet, très simple de modifier les valeurs d'un jeu depuis le registre. En général, je suppose que beaucoup le font ainsi, je fais en sorte que le nom des entrées que je définis ne soient jamais écrit en claire.

Par exemple imaginons que tu enregistres tes points de vie (pour faire simple), au lieu de nommer l'entrée par exemple comme ceci :

Code : Tout sélectionner

PlayerPrefs.SetInt("VieDuJoueur", "95");
J'écrirais plutôt l'identifiant comme ceci :

Code : Tout sélectionner

PlayerPrefs.SetInt("A4zaCXD2cq6s", VariableVieDuJoueurHashé);
Bon, "VariableVieDuJoueurHashé" n'est qu'à titre d'exemple ne pas le nommer ainsi. Mais bon, nommer ses entrées ainsi c'est cool mais cela peut vite être complexe pour se souvenir de quoi veut signifier quoi ^^ (surtout s'il y a énormément d'entrées, donc il faut tenir une note sur tout cela afin de s'en souvenir).

Après, quelqu'un qui s'y connaît pourra largement déterminer ce à quoi "A4zaCXD2cq6s" correspond et avec certaines techniques trouver la méthode de Hash utilisé pour "VariableVieDuJoueurHashé".

Après la sécurité, c'est loin d'être aisé. Obfuscator... Cela n'assure pas la sécurité extrême, mais découragera toujours les plus basiques tricheurs si l'on peut dire ainsi.
Merci de lire et de prendre en considération la Nétiquette des Forums avant de poster un sujet !

Avatar de l’utilisateur
Silverglade
Messages : 264
Inscription : 04 Août 2012 17:52

Re: Question relations jeu en ligne/sql

Message par Silverglade » 26 Fév 2015 13:17

Ok ok, je pense que ce sera la plus grosse prise de tête pour sécuriser mes playerprefs mais passage obligé.
Pour la variable joueur hashé je pense que je vais faire une correspondance des valeurs numérique en lettre genre A = 1 mais en bien plus complexe.

Merci à vous pour vos réponses :)

error404
Messages : 160
Inscription : 13 Nov 2010 07:51
Contact :

Re: Question relations jeu en ligne/sql

Message par error404 » 26 Fév 2015 17:11

Après c'est pas bien compliqué. Tu te crée 2 fonctions "encrypt" et "decrypt" et à chaque fois que tu veux enregistrer le score, tu fais newScore = encrype(score); et après tu enregistre newScore qui est crypté.
Au pire tu prends du MD http://wiki.unity3d.com/index.php?title=MD5

Répondre

Revenir vers « (C#) CSharp »