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
[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
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
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
Microsoft MVP // Me // Blog // GitHub // @Egghead // All my talks // Speakerdeck
.. 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.
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code