Laden...

C# List und Klasse - Daten Speichern und Abfragen

Erstellt von Ortator vor 6 Jahren Letzter Beitrag vor 6 Jahren 2.572 Views
O
Ortator Themenstarter:in
7 Beiträge seit 2017
vor 6 Jahren
C# List und Klasse - Daten Speichern und Abfragen

Hallo,

ich habe ein kleines Problem:

Und zwar möchte ich wenn ein Packet ankommt ( TCP Server ) Überprüfen ob schon eine Session vorhanden ist ( Falls nicht == 0 dann .. )

Das ist die Klasse die ich benutze: ( Soll für jeden Benutzer eine Liste erstellen )

    public class PlayerManager{
        public class PlayerData{
            string[] PlayerDataString = { "" };
            int[] PlayerDataInt = { 0 };
            Socket PlayerDataSocket;
            /* === PlayerDataString ===
             * [0] PlayerName
             * 
             * 
             * */
            /* === PlayerDataInt === 
             * [0] Session ID
             * 
             * */
            public void SetName(string PlayerName){
                try{
                    this.PlayerDataString[0] = PlayerName;
                }
                catch{}
            }
            public void SetSocket(Socket handler){
                try{
                    this.PlayerDataSocket = handler;
                }
                catch { }
            }
            public void SetSessionID(int SessionID){
                try{
                    this.PlayerDataInt[0] = SessionID;
                }
                catch { }
            }
            public Socket GetSocket(){return this.PlayerDataSocket;}
            public int GetSessionID() { return this.PlayerDataInt[0]; }
        }
        private static List<PlayerData> PlayerDataList = new List<PlayerData>();
        public static void CreatePlayerData(Socket PlayerHandler,string PlayerName,int SessionID){
            try{
                PlayerData CreateNewPlayer = new PlayerData();
                //--------------------------------------------
                CreateNewPlayer.SetName(PlayerName);
                CreateNewPlayer.SetSessionID(SessionID);
                CreateNewPlayer.SetSocket(PlayerHandler);
                //--------------------------------------------
                PlayerDataList.Add(CreateNewPlayer);
            }
            catch (Exception ex) { GameConsole.WriteConsoleGameParams(System.ConsoleColor.Red, $"ERROR GetPlayerBySocket()", ex.ToString()); }
        }
        public static PlayerData GetPlayerBySocket(Socket handler){
            PlayerData rtrn = null;
            try {
                for (int i = 0; i <= PlayerDataList.Count - 1; i++) {
                    if (PlayerDataList[i].GetSocket() == handler){
                        rtrn = PlayerDataList[i];
                        break;
                    }
                }
                return rtrn;
            }
            catch (Exception ex) { GameConsole.WriteConsoleGameParams(System.ConsoleColor.Red, $"ERROR GetPlayerBySocket()", ex.ToString()); return rtrn; }
        }
    }

Und hier wird es abgefragt:

        public static void IncommingPacket(Socket handler,byte[] PacketByte){
            try{
                PlayerManager.PlayerData GetPlayer = PlayerManager.GetPlayerBySocket(handler);
                if (GetPlayer.GetSessionID() == 0){
                    string SessionPacket = GameCrypto.DecryptCustomParameter(PacketByte);
                    string[] SessionParts = SessionPacket.Split(' ');
                    if (!SessionParts.Any()){
                        return;
                    }
                    if (SessionParts.Length < 2){
                        return;
                    }
                    int SessionID;
                    if (int.TryParse(SessionParts[1].Split('\\').FirstOrDefault(), out SessionID)){
                        Console.WriteLine("Session hat sich verbunden: " + SessionID);
                    }
                }
            }
            catch (Exception ex) { GameConsole.WriteConsoleGameParams(System.ConsoleColor.Red, $"ERROR IncommingPacket", ex.ToString()); }
        }
                PlayerManager.PlayerData GetPlayer = PlayerManager.GetPlayerBySocket(handler);
                if (GetPlayer.GetSessionID() == 0){

Aber das Problem ist das es nicht funktionieren möchte und ich den Fehler bekomme bei IncommingPacket das eine Objektinstanz erst erstellt werden muss.

Wie behebe ich diesen Fehler oder wie mach ich es am besten besser.

MfG

16.835 Beiträge seit 2008
vor 6 Jahren

[Artikel] Debugger: Wie verwende ich den von Visual Studio?
[FAQ] NullReferenceException: Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt

Wo es bei Dir aktuell null ist sehen wir auch nicht; das musst schon selbst debuggen.

.ToString() ist bei den vielen Sachen der falsche Weg bzw. wird einfach missbraucht, wie zB. bei Exceptions.
Dort willst Du eigentlich <Exception>.Message.

PS: gewöhn Dir die C# Namenskonvention an.
[Artikel] C#: Richtlinien für die Namensvergabe

2.207 Beiträge seit 2011
vor 6 Jahren

Hallo Ortator,

ich hoffe mal die Catch-Blöcke sind nicht wirklich leer. Falls doch: Dann schluckst du die Exceptions. Bau dir, wenn dus es schon einsetzt und das kann bei "komischen" Fehlern manchmal recht hilfreich sein, ein sauberes Exception-Handling auf. Dann kommst du den Fehlern eher auf die Schliche - Siehe auch den Stacktrace dann. Dann erfährst du eventuell sogar, wo irgendwas "null" ist und nicht "null" sein sollte.

Ich tippe mal auf irgendein Array-Zugriff und da steht nix. Aber das ist rein aus dem Bauch raus. Du hältst dir zwei Listen, mit unterschiedlichen Sachen drin die du ständig synchronisieren musst. Du willst dir doch nur eine Playerlist halten und anhand des handlers den passenden raussuchen, oder? Was spricht gegen eine stinknormale Klasse für einen Player und eine Klasse, die eine Liste von Playern hält?

Kurz heruntergetippt:


public class PlayerRepo
{
	private List<Player> _playerList = new List<Player>();

	public Player AddPlayer(Socket handler, string name, int sessionId)
	{
		Player playerToAdd = new Player(handler, name, sessionId);
		_playerList.Add(playerToAdd);
		return playerToAdd;
	}

	public Player GetPlayerBySocket(Socket handler)
	{
		return _playerList.FirstOrDefault(x => x.Socket == handler);
	}
}

public class Player
{
	public Socket Socket { get; }
	public string Name { get; }
	public int SessionId { get; }

	public Player(Socket handler, string name, int sessionId)
	{
		Socket = handler;
		Name = name;
		SessionId = sessionId;
	}
}

sowas in der Art?

Weiter: Nenne niemals etwas "Manager". Das sagt absolut gar nichts aus über das, was die Klasse macht 😉

Debugger wurde ja schon verlinkt. Schau dir auch mal Linq an, statt Array nimm Listen, dann kannst du dir die for-Schleife sparen, dein Code wird leserlicher und einfacher.

Gruss

Coffeebean

16.835 Beiträge seit 2008
vor 6 Jahren

.. und Socket-Objekte in eine POCO-Klasse (Plain old CLR object) zu packen ist keine gute Idee.
Bau Dir lieber ein Dictionary, das die Player zu den Sockets verwaltet - oder designe die Klasse anders.