PDA

View Full Version : [C#] Errore System.IndexOutOfRangeException


coleseya
08-04-2011, 19:16
Salve,
avrei un problema di questo genere, come errore generico:

Error during removing user from room:System.IndexOutOfRangeException: Index was outside the bounds of the array.
at Rooms.Room.RemoveUserFromRoom(GameClient Session, Boolean NotifyClient, Boolean NotifyKick)


qui è il codcie dorgente dove è posizionato l'errore sapete dirmi dove e come sbaglio?

public void RemoveUserFromRoom(GameClient Session, Boolean NotifyClient, Boolean NotifyKick)
{
try
{
if (Session == null)
{
return;
}

if (Session.GetRooms() == null)
return;

RoomUser User = GetRoomUserByRooms(Session.GetRooms().Id);

if (User != null)
{
int ID = User.InternalRoomID;
UserList[User.InternalRoomID] = null;

User.InternalRoomID = -1;
mGameMap[User.X, User.Y] = 0;
}

if (NotifyClient)
{
if (NotifyKick)
{
Session.GetMessageHandler().GetResponse().Init(33);
Session.GetMessageHandler().GetResponse().AppendInt32(4008);
Session.GetMessageHandler().SendResponse();
}

Session.GetMessageHandler().GetResponse().Init(18);
Session.GetMessageHandler().SendResponse();
}

List<RoomUser> PetsToRemove = new List<RoomUser>();

if (User != null)
{
if (Session.GetRooms() != null)
{
if (!User.IsSpectator)
{
//UserMatrix[User.X, User.Y] = false;

ServerMessage LeaveMessage = new ServerMessage(29);
LeaveMessage.AppendRawInt32(User.VirtualId);
SendMessage(LeaveMessage);

if (Session.GetRooms() != null)
{
if (HasActiveTrade(Session.GetRooms().Id))
{
TryStopTrade(Session.GetRooms().Id);
}

if (Session.GetRooms().Username.ToLower() == Owner.ToLower())
{
if (HasOngoingEvent)
{
Event = null;

ServerMessage Message = new ServerMessage(370);
Message.AppendStringWithBreak("-1");
SendMessage(Message);
}
}

Session.GetRooms().OnLeaveRoom();
}

UpdateUserCount();

List<RoomUser> Bots = new List<RoomUser>();

for (int i = 0; i < UserList.Length; i++)
{
RoomUser Usr = UserList[i];
if (Usr == null)
continue;
if (Usr.IsBot)
Bots.Add(Usr);
}

foreach (RoomUser Bot in Bots)
{
Bot.BotAI.OnUserLeaveRoom(Session);

if (Bot.IsPet && Bot.PetData.OwnerId == Session.GetRooms().Id && !CheckRights(Session, true))
{
PetsToRemove.Add(Bot);
}
}
}
}
}

foreach (RoomUser toRemove in PetsToRemove)
{
Session.GetRooms().GetInventoryComponent().AddPet(toRemove.PetData);
RemoveBot(toRemove.VirtualId, false);
}

}
catch (Exception e) { Logging.LogCriticalException("Error during removing user from room:" + e.ToString()); }
}

Attento suggerimenti, Grazie!

Ballantine
08-04-2011, 22:26
Ti ho sottolineato in rosso i pezzi che forse possono darti quel tipo di errore:

public void RemoveUserFromRoom(GameClient Session, Boolean NotifyClient, Boolean NotifyKick)
{
try
{
if (Session == null)
{
return;
}

if (Session.GetRooms() == null)
return;

RoomUser User = GetRoomUserByRooms(Session.GetRooms().Id);

if (User != null)
{
int ID = User.InternalRoomID;
UserList[User.InternalRoomID] = null;

User.InternalRoomID = -1;
mGameMap[User.X, User.Y] = 0;
}

if (NotifyClient)
{
if (NotifyKick)
{
Session.GetMessageHandler().GetResponse().Init(33);
Session.GetMessageHandler().GetResponse().AppendInt32(4008);
Session.GetMessageHandler().SendResponse();
}

Session.GetMessageHandler().GetResponse().Init(18);
Session.GetMessageHandler().SendResponse();
}

List<RoomUser> PetsToRemove = new List<RoomUser>();

if (User != null)
{
if (Session.GetRooms() != null)
{
if (!User.IsSpectator)
{
//UserMatrix[User.X, User.Y] = false;

ServerMessage LeaveMessage = new ServerMessage(29);
LeaveMessage.AppendRawInt32(User.VirtualId);
SendMessage(LeaveMessage);

if (Session.GetRooms() != null)
{
if (HasActiveTrade(Session.GetRooms().Id))
{
TryStopTrade(Session.GetRooms().Id);
}

if (Session.GetRooms().Username.ToLower() == Owner.ToLower())
{
if (HasOngoingEvent)
{
Event = null;

ServerMessage Message = new ServerMessage(370);
Message.AppendStringWithBreak("-1");
SendMessage(Message);
}
}

Session.GetRooms().OnLeaveRoom();
}

UpdateUserCount();

List<RoomUser> Bots = new List<RoomUser>();

for (int i = 0; i < UserList.Length; i++)
{
RoomUser Usr = UserList[i];
if (Usr == null)
continue;
if (Usr.IsBot)
Bots.Add(Usr);
}

foreach (RoomUser Bot in Bots)
{
Bot.BotAI.OnUserLeaveRoom(Session);

if (Bot.IsPet && Bot.PetData.OwnerId == Session.GetRooms().Id && !CheckRights(Session, true))
{
PetsToRemove.Add(Bot);
}
}
}
}
}

foreach (RoomUser toRemove in PetsToRemove)
{
Session.GetRooms().GetInventoryComponent().AddPet(toRemove.PetData);
RemoveBot(toRemove.VirtualId, false);
}

}
catch (Exception e) { Logging.LogCriticalException("Error during removing user from room:" + e.ToString()); }
}

In particolare:
- User.InternalRoomID potrebbe essere null/minore di 0/maggiore della dimensione massima di UserList;
- User.X e/o User.Y potrebbero essere null/minori di 0/maggiori della dimensione massima di mGameMap;

coleseya
09-04-2011, 01:15
Dall'errore avevo capito che c'è un Indice oltre i limiti della matrice.
Potrebbe dare anche lo stesso tipo di errore se supera 0/maggiori della dimensione massima giusto?



if (User != null)
{
int ID = User.InternalRoomID;
UserList[User.InternalRoomID] = null;

User.InternalRoomID = -1;
mGameMap[User.X, User.Y] = 0;
}


l'unico valore che risulta minore di 0 è questo in rosso, potrebbe essere il problema?

Ballantine
09-04-2011, 10:17
if (User != null)
{
int ID = User.InternalRoomID;
UserList[User.InternalRoomID] = null;

User.InternalRoomID = -1;
mGameMap[User.X, User.Y] = 0;
}


l'unico valore che risulta minore di 0 è questo in rosso, potrebbe essere il problema?

La riga dove assegni -1 ad User.InternalRoomID direi che possiamo escluderla, poiché User.InternalRoomID non viene più riutilizzato in questo metodo.

Potrebbe dare anche lo stesso tipo di errore se supera 0/maggiori della dimensione massima giusto?
Esattamente. Un errore molto comune ad esempio è quello di considerare a[a.Length] come un elemento valido, mentre in realtà a.Length è il primo indice al di fuori dell'array.
Nel tuo caso sarebbe utile vedere come crei UserList e mGameMap, e come inizializzi InternalRoomID, UserX e UserY.
Per semplificarti la vita potresti anche mettere delle stampe all'interno del metodo per vedere in che punto si ferma l'esecuzione (non è molto elegante ma ti evita di fare troppe modifiche al codice), aggiungere alla stampa dell'eccezione e.StackTrace (è la via più veloce ma non è detto che le informazioni aggiuntive siano utili) oppure "spezzettare" il tuo try-catch in diversi blocchi.