[DB-RS] Kick d'un client sans personnage

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
Autodidactelife
Messages : 47
Inscription : 21 Fév 2018 23:04
Localisation : France

[DB-RS] Kick d'un client sans personnage

Message par Autodidactelife » 03 Juin 2018 15:04

Bonjour,

J'ai énormément du mal à trouver des sujets sur les jeux en ligne, à part des tutos avec des requêtes faites en PHP et moi ça me convient pas !

Alors j'avais d'abord l'idée qu'à la connexion le joueur doit envoyer une Cmd sous les 2s avant d'être kick mais je n'aimes pas l'idée d'avoir un joueur inexistant être connecté même pendant 2s.

J'ai alors le client qui ce connecte après avoir mis ces identifiants, j'ai retirer l'auto creat player et j'arrive à mon soucis !
Impossible de déconnecter le client si le login n'est pas bon.

D'abord dès que OnClientConnect dans mon NetworkManager est lancé j'appel la commande:

Code : Tout sélectionner

public override void OnClientConnect(NetworkConnection conn) {
         m_Connexion.GetComponent<Connexion>().CmdConnexion(m_UIPseudo.text, m_UIPassword.text);
	base.OnClientConnect(conn);
}
La commande ce trouvant sur un NetworkBehiavour (car impossible de Cmd sur un NetworkManager):

Code : Tout sélectionner

[Command]
public void CmdConnexion(string pseudo, string password) {
	//con = MysqlConnection qui est bien connecter sur la base de donneé
	MySqlConnection con = _Serveur.GetComponent<Serveur>().con;
	MySqlCommand CmdSql = new MySqlCommand("SELECT * FROM `joueurs` WHERE `Pseudo` = '" + pseudo + "'", con);
	MySqlDataReader MyReader = CmdSql.ExecuteReader();
	string data = null;

	while (MyReader.Read()) {
		data = MyReader["password"].ToString();
		if (data != null) break;
	}
	MyReader.Close();
	
	// Ceci fonctionne sans soucis !
	if (data == null) { // Aucune personne n'a ce pseudo
	
	} else if (data == password) { // Compte bon et même mot de passe        
	
	} else if (data != password) { // Compte bon mais pas ce mot de passe
		connectionToClient.Disconnect(); // L'erreur est ici ! Ceci ne marche pas sans avoir un joueur :/
	}
}
Si vous avez des pistes ou des tutoriels sur ça, j'ai évidemment déjà fais des recherches, mais on sait jamais ! :)
Merci de m'avoir lu !

Cordialement

Farstone
Messages : 187
Inscription : 04 Déc 2016 09:38

Re: [DB-RS] Kick d'un client sans personnage

Message par Farstone » 04 Juin 2018 12:55

Salut, je voie que tu a continué t'es recherches après ton post sur les tp, pour les tutos robuste sur le networking tu va devoir commencer à faire t'es recherches en anglais.
Je sait que je suis chiant avec ça mais évite de GetComponent dans des fonction aussi solicité pour aucune utilité, tu peux très bien faire ton script serveur en singleton ou alors le référencer pendant le Start, sa t'évite une perte de performance inutile.

Pour ton problème c'est un peu compliqué de répondre étant donné qu'on ne sait pas ce que fait "connectionToClient.Disconnect();"
J'ai utilisé pendant quelques temps UNET HLAPI et il me semble que tu doit avoir une référence de client, car la tu appel simplement une fonction qui n'a aucune connaissance de quel utilisateur tu traite actuellement au vue des paramètres de ta fonction.
Je n'ai jamais utilisé le NetworkManager mais il utilise logiquement un NetworkServer, normalement les RPCs que reçoit le serveur doivent avoir en paramètre un NetworkConnection pour savoir qui exécute actuellement la commande, un truc du style

Code : Tout sélectionner

public void CmdDbLogin(NetworkConnection conn, string username, string password)
{
	if (true)
	{
	// Le compte est correct
	}
	else
	{
	// Le compte est incorrect
	conn.Disconnect();
	}
}
Je ne sait pas comment ça fonctionne avec le NetworkManager, peux être que je dit n'importe quoi mais je pense que tu a simplement mal compris la doc et que tu n'a pas vraiment de référence sur le script qui gère le joueur en question qui exécute la commande, c'est un bel exemple qui te montre aussi les limites du HLAPI, qui t'oblige à crée d'autre script pour gérer d'autre variable importante d'un joueur (comme son pseudo), au final, si tu ne veux pas modifier les source, tu va finir par demander à un autre script quel est le pseudo d'un joueur basé sur son id, alors que sa pourrait être inclue directement dans le NetworkConnection (c'est un autre sujet, mais fait attention à ça) bref, essaie de te renseigner de ce côté car la tu ne sait tout simplement pas qui est qui :)

EDIT : Voici la version corrigé de ton script (d’ailleurs CmdConnexion n'a pas besoin d'être une commande car il est éxécuté depuis une commande, et donc depuis le serveur)

Code : Tout sélectionner

public override void OnClientConnect(NetworkConnection conn) {
	base.OnClientConnect(conn); // On exécute le base en premier pour être sur que le client est bien connecté du côté de UNET
         m_Connexion.GetComponent<Connexion>().CmdConnexion(conn, m_UIPseudo.text, m_UIPassword.text);
}

Code : Tout sélectionner

[Command]
public void CmdConnexion(NetworkConnection conn, string pseudo, string password) {
	//con = MysqlConnection qui est bien connecter sur la base de donneé
	MySqlConnection con = _Serveur.GetComponent<Serveur>().con;
	MySqlCommand CmdSql = new MySqlCommand("SELECT * FROM `joueurs` WHERE `Pseudo` = '" + pseudo + "'", con);
	MySqlDataReader MyReader = CmdSql.ExecuteReader();
	string data = null;

	while (MyReader.Read()) {
		data = MyReader["password"].ToString();
		if (data != null) break;
	}
	MyReader.Close();
	
	// Ceci fonctionne sans soucis !
	if (data == null) { // Aucune personne n'a ce pseudo
	
	} else if (data == password) { // Compte bon et même mot de passe        
	
	} else if (data != password) { // Compte bon mais pas ce mot de passe
		conn.Disconnect();
	}
}
C'est juste un manque de compréhension global de la programmation, ça va venir avec le temps, tient le coup !

Autodidactelife
Messages : 47
Inscription : 21 Fév 2018 23:04
Localisation : France

Re: [DB-RS] Kick d'un client sans personnage

Message par Autodidactelife » 05 Juin 2018 19:17

Bonjour Twiixy,

Pour le connectionToClient d'après les tests que j'ai fais sur le 1er projet, ceci utilise le NetworkIdentity du gameObject actuel pour retrouver le client lié. Et en effet le soucis c'est que ce n'est pas un joueur et donc qu'il n'appartient réellement à personne. :/

D'ailleurs ceci est un raccourci il peut s'écrire comme ça ou comme cela:

Code : Tout sélectionner

GetComponent<NetworkIdentity>().connectionToClient.Disconnect();
Pour le NetworkConnection en effet, c'est ce que je dois faire suivre je n'ai pas eu l'idée, mais le faite que ce soit le joueur qui l'envoie, c'est pas dangereux niveau sécurité ? Il ne pourrait pas le modifier ?

C'est vrais que pour savoir qui était qui je faisais des variables côté Serveur sur le script du joueur, en faite le script du joueur était un concentrer de fonctions au nom bien détailler sur son action, classer par qui l'actionne (une partie serveur, une partie client, une partie mixte (les variables principalement qui sont sync)).

J'avais comme ça sur la classe joueur le pseudo, les stats et tout ce que j'ai besoin sans que le joueur puisse les modifier du côté client puisqu'ils étaient sois côté serveur, sois sync et donc côté serveur encore, mais je vais me renseigner, ça me parait encore vague mais je prend note et je vais essayer de voir, si ça peut être plus propre, plus pro et plus simple pour la suite je veux bien ! :D


Edit:

Bah ...

Code : Tout sélectionner

UNetWeaver error: Command [Connexion:CmdConnexion] cannot use a NetworkConnection as a parameter. To access a player object's connection on the server use connectionToClient
Donc pas le droit d'utiliser NetworkConnection en paramètre, je vais essayer de chercher comment récupérer le NetworkConnection de la personne qui demande la commande, ça doit forcément être transmis ! Un joueur pourrait simuler le NetworkConnection donc je ne trouves pas ça "saint" de le faire passer par le client, même si j'avais eu l'idée de comparer avec tout les NetworkConnection de tout les joueurs pour voir si il existait x)

Mais dans le cas où c'était un fake, à part ne pas le connecter au personnage, j'aurais pas pu le déconnecter du serveur :/

Sachant que l'objet à un NetworkIdentity je pense que j'ai besoin de chance d'y arriver en recherchant sur ça :) je vais chercher toutes les fonctions qui retournent un "NetworkConnection" et les essayés, déjà connectionToClient marche pas, car la personne n'a aucune autorisations sur ce code là.

Sinon j'ai une solution de secoure ... Si le joueur ce connecte, ça créer automatiquement le personnage qui est en faite un script et qui lui vérifie si il existe ou non, si non kick et si oui il met le personnage mais ça part trop loin, trop complexe c'est trop bricolage ^^, je pense les grosses boites ce sont pas embêté et sont passer par des sockets manuel :/

Autodidactelife
Messages : 47
Inscription : 21 Fév 2018 23:04
Localisation : France

Re: [DB-RS] Kick d'un client sans personnage

Message par Autodidactelife » 06 Juin 2018 01:52

Je donne une nouvelle réponse, j'ai fais ceci à la connexion du joueur:

Code : Tout sélectionner

GameObject player = GameObject.Instantiate(send_Connexion, Vector3.zero, Quaternion.identity);
        NetworkServer.AddPlayerForConnection(conn, player, 0);
Comme ça tout passe par le serveur, le joueur à pas de personnage et ça ce co.
Bon je règle le soucis du personnage inexistant qui ce co mais ...
Il reste le soucis de la personne qui ce co voit tout ce qui ce passe sur le serveur même si il est auto kick 0,4s après s'être co si il essaye pas de s'identifier. (Il est directement kick si jamais il met des mauvais identifiants).

J'utilise la même méthode pour ajouté le joueur et je delete l'ancien script, comme ça je garde la co, il à le joueur et l'inutile disparaît :D

Je pensais avoir la solution: Faire spawn le joueur trèèèèèèèès loin comme ça il ne verra rien maiiiiiis ...
Après avoir fais un test le joueur voit tout ce qui ce passe même à 200 000 de distance ... Je pensais que seul une zone autour de lui était mis à jour pour évité de saturé inutilement le joueur mais visiblement ... Non :/

Je dois chercher comment empêcher la synchro si le joueur est à une certaine distance :/
Et à priori c'est loin d'être gagner ..

À la base je cherche juste à ce qu'un joueur ce log et ne puisse pas voir le serveur tant qu'il à pas était connecté ou inscrit (perso si le joueur ce log avec des identifiants inexistant ça inscrit le joueur, je m'embête pas), donc en vrais il y à sois la connexion/inscription sois le mauvais mot de passe, donc 2 seuls choix possible et j'aimerais qu'il ne voit rien tant que la co ou inscription n'est pas validé.

En faite j'essaye de refaire la même chose que le socket quoi:


- Le client demande une connexion
- Le serveur accepte la connexion (mais n'informe pas le client sur les joueurs)
- Le client envoie une demande de connexion
- Le serveur vérifie (le serveur n'envoie toujours rien sur les joueurs)
- Le client est soit remballer, sois connecté et là > Information sur les joueurs.

Farstone
Messages : 187
Inscription : 04 Déc 2016 09:38

Re: [DB-RS] Kick d'un client sans personnage

Message par Farstone » 12 Juin 2018 18:20

Autant pour moi alors je connait pas trop le NetworkManager je peux pas t'aider, j'ai l'impression que tu cherche un accès à t'es connexion mais c'est pas vraiment possible avec unet hlapi. Si tu fait ce projet pour apprendre je te conseille de partir directement avec une bibliothèque comme LiteNet qui est une api low level pour le socket, tu apprendras plus vite mais il va falloir forcer au début. L’expérience est plus agréable et je pense que c'est ce que tu recherche, tu pourras crée t'es propres script pour gérer les clients et communiquer à l'aide de bytes, sa va te permettre d'avoir une meilleur compréhension de ce qui se passe sur le client et le serveur quand il communique. J'ai moi même essayé de me convaincre que UNET était une bonne solution mais ça ne l'est pas, pour que le système soit simple à utiliser UNET utilise beaucoup d'extra dans les packet ce qui nui au performance du serveur et la bande passante du client, c'est bien au début mais tôt ou tard tu va te rendre compte que tu veux plus de contrôle sur ton code, alors autant partir direct sur une biblio socket, si tu comprend la logique du c# et c'est fonctionnalités ça devrais être ok. C'est un peu HS, juste un avis de ma propre expérience sur UNET je ne t'incite à rien :mrgreen:

Autodidactelife
Messages : 47
Inscription : 21 Fév 2018 23:04
Localisation : France

Re: [DB-RS] Kick d'un client sans personnage

Message par Autodidactelife » 15 Juin 2018 22:02

Twiixy a écrit :
12 Juin 2018 18:20
Autant pour moi alors je connait pas trop le NetworkManager je peux pas t'aider, j'ai l'impression que tu cherche un accès à t'es connexion mais c'est pas vraiment possible avec unet hlapi. Si tu fait ce projet pour apprendre je te conseille de partir directement avec une bibliothèque comme LiteNet qui est une api low level pour le socket, tu apprendras plus vite mais il va falloir forcer au début. L’expérience est plus agréable et je pense que c'est ce que tu recherche, tu pourras crée t'es propres script pour gérer les clients et communiquer à l'aide de bytes, sa va te permettre d'avoir une meilleur compréhension de ce qui se passe sur le client et le serveur quand il communique. J'ai moi même essayé de me convaincre que UNET était une bonne solution mais ça ne l'est pas, pour que le système soit simple à utiliser UNET utilise beaucoup d'extra dans les packet ce qui nui au performance du serveur et la bande passante du client, c'est bien au début mais tôt ou tard tu va te rendre compte que tu veux plus de contrôle sur ton code, alors autant partir direct sur une biblio socket, si tu comprend la logique du c# et c'est fonctionnalités ça devrais être ok. C'est un peu HS, juste un avis de ma propre expérience sur UNET je ne t'incite à rien :mrgreen:
Je n'avais pas vu la réponse, j'allais pas sur la bonne section du forum !
J'utilise le serveur Unity uniquement par flemme, mais je remarques petit à petit que pour un réel projet il n'est pas du tout convenable, il est bien pour des jeux style Agar.io mais en aucun cas pour des jeux avec une identification et tout.

Je travaillerais peut être sur un serveur plus tard, là c'est juste un projet plus délire, je comptes faire des jeux solo par la suite je n'aurais plus de soucis j'imagine, vu que les seuls soucis que je rencontre c'est uniquement le serveur. (Tout ça par flemme ^^')

Répondre

Revenir vers « (C#) CSharp »