Characters Stuck Online

10/31/2010 18:59 ryuchetval#1
Hey guys...I got a problem with characters getting stuck in-game (even though the players are not in-game)...I tried changing the disconnect void, the logoff void...to check every minute if there's a client not connected but still added to a client hashtable to be logged off but still nothing...
here are my voids...

LogOff
Code:
public void LogOff()
        {
            try
            {
                Game.Buff B = MyChar.BuffOf(NewestCOServer.Features.SkillsClass.ExtraEffect.Transform);
                MyChar.RemoveBuff(B);
                if (MyChar.MyCompanion != null)
                    MyChar.MyCompanion.Dissappear();
                if (MyChar.MyTeam != null)
                {
                    if (MyChar.TeamLeader)
                        MyChar.MyTeam.Dismiss(MyChar);
                    else
                        MyChar.MyTeam.Leaves(MyChar);
                }
                if (MyChar.Loc.Map == 1039 || MyChar.Loc.Map == 1036 || MyChar.Loc.Map == 2021 || MyChar.Loc.Map == 2022 || MyChar.Loc.Map == 2023 || MyChar.Loc.Map == 2024 || MyChar.Loc.Map == 1051)
                {
                    Game.Vector2 V = (Game.Vector2)Database.DefaultCoords[MyChar.Loc.PreviousMap];
                    MyChar.Teleport(MyChar.Loc.PreviousMap, V.X, V.Y);
                }
                if (MyChar.MyShop != null)
                    MyChar.MyShop.Close();
                foreach (Game.Friend F in MyChar.Friends.Values)
                {
                    AddSend(Packets.FriendEnemyPacket(F.UID, F.Name, 15, Convert.ToByte(F.Online)));
                    if (F.Online)
                    {
                        F.Info.MyClient.AddSend(Packets.FriendEnemyPacket(MyChar.EntityID, MyChar.Name, 14, 1));
                        F.Info.MyClient.AddSend(Packets.FriendEnemyPacket(MyChar.EntityID, MyChar.Name, 15, 0));
                        F.Info.MyClient.LocalMessage(2005, "Your friend " + MyChar.Name + " has logged off.");
                    }
                }
                if (!MyChar.Alive)
                {
                    if (MyChar.Loc.Map == 1038 && Features.GuildWars.War)
                    {
                        MyChar.Loc.PreviousMap = MyChar.Loc.Map;
                        MyChar.Loc.Map = 6001;
                        MyChar.Loc.X = 32;
                        MyChar.Loc.Y = 72;
                    }
                    else
                    {
                        foreach (ushort[] Point in Database.RevPoints)
                            if (Point[0] == MyChar.Loc.Map)
                            {
                                MyChar.Loc.PreviousMap = MyChar.Loc.Map;
                                MyChar.Loc.Map = Point[1];
                                MyChar.Loc.X = Point[2];
                                MyChar.Loc.Y = Point[3];
                                break;
                            }

                    }
                    MyChar.CurHP = 1;
                }
            }
            catch { }
            if (Game.World.H_Chars.Contains(MyChar.EntityID) || Game.World.H_Clients.Contains(MyChar.EntityID))
            {
                Program.WriteLine("User " + MyChar.Name + " disconnected.");
                //here starts the part to tell me some infos about the character
                string Profs = "";
                string Skills = "";
                foreach (Game.Skill S in MyChar.Skills.Values)
                    Skills += S.ID + "~" + S.Lvl + "~" + S.Exp + "  ";
                if (Skills != "")
                    Program.WriteLine(MyChar.Name + " had Skills: " + Skills);
                foreach (Game.Prof P in MyChar.Profs.Values)
                    Profs += P.ID + "~" + P.Lvl + "~" + P.Exp + "  ";
                if (Profs != "")
                    Program.WriteLine(MyChar.Name + " had Profs: " + Profs);
                if (MyChar.DoubleExpLeft > 0)
                    Program.WriteLine(MyChar.Name + " had DoubleExp: " + MyChar.DoubleExpLeft);
                if (MyChar.VipLevel != 0)
                    Program.WriteLine(MyChar.Name + " had VIPLevel: " + MyChar.VipLevel + " days: " + MyChar.VIPDays);
                if (MyChar.VP > 0)
                    Program.WriteLine(MyChar.Name + " had " + MyChar.VP + " VPS.");
                if (MyChar.Reborns > 0)
                {
                    Program.WriteLine(MyChar.Name + " was class " + MyChar.PreviousJob1 + " before reborning.");
                    if (MyChar.PreviousJob2 != 0)
                        Program.WriteLine(MyChar.Name + " was class " + MyChar.PreviousJob2 + " before reborning second time.");
                }
                string Items = "";
                foreach (Game.Item I in MyChar.Inventory)
                    Items += I.ID + "~" + I.Plus + "~" + I.Bless + "~" + I.Enchant + "~" + I.Soc1 + "~" + I.Soc2 + "~" + I.Progress + "  ";
                Program.WriteLine(MyChar.Name + " had items in Inventory: " + Items);
                Items = "MA WH: ";
                foreach (Game.Item I in MyChar.Warehouses.MAWarehouse)
                    Items += I.ID + "~" + I.Plus + "~" + I.Bless + "~" + I.Enchant + "~" + I.Soc1 + "~" + I.Soc2 + "~" + I.Progress + "  ";
                Program.WriteLine(MyChar.Name + " had " + Items);
                Items = "TC WH: ";
                foreach (Game.Item I in MyChar.Warehouses.TCWarehouse)
                    Items += I.ID + "~" + I.Plus + "~" + I.Bless + "~" + I.Enchant + "~" + I.Soc1 + "~" + I.Soc2 + "~" + I.Progress + "  ";
                Program.WriteLine(MyChar.Name + " had " + Items);
                Items = "PC WH: ";
                foreach (Game.Item I in MyChar.Warehouses.PCWarehouse)
                    Items += I.ID + "~" + I.Plus + "~" + I.Bless + "~" + I.Enchant + "~" + I.Soc1 + "~" + I.Soc2 + "~" + I.Progress + "  ";
                Program.WriteLine(MyChar.Name + " had " + Items);
                Items = "AC WH: ";
                foreach (Game.Item I in MyChar.Warehouses.ACWarehouse)
                    Items += I.ID + "~" + I.Plus + "~" + I.Bless + "~" + I.Enchant + "~" + I.Soc1 + "~" + I.Soc2 + "~" + I.Progress + "  ";
                Program.WriteLine(MyChar.Name + " had " + Items);
                Items = "DC WH: ";
                foreach (Game.Item I in MyChar.Warehouses.DCWarehouse)
                    Items += I.ID + "~" + I.Plus + "~" + I.Bless + "~" + I.Enchant + "~" + I.Soc1 + "~" + I.Soc2 + "~" + I.Progress + "  ";
                Program.WriteLine(MyChar.Name + " had " + Items);
                Items = "BI WH: ";
                foreach (Game.Item I in MyChar.Warehouses.BIWarehouse)
                    Items += I.ID + "~" + I.Plus + "~" + I.Bless + "~" + I.Enchant + "~" + I.Soc1 + "~" + I.Soc2 + "~" + I.Progress + "  ";
                Program.WriteLine(MyChar.Name + " was level: " + MyChar.Level + " PC: " + (MyChar.Experience * 100) / Database.LevelExp[MyChar.Level]);
                Program.WriteLine(MyChar.Name + " had job: " + MyChar.Job);
                Program.WriteLine(MyChar.Name + " had silvers: " + MyChar.Silvers);
                Program.WriteLine(MyChar.Name + " had WH silvers: " + MyChar.WHSilvers);
                Program.WriteLine(MyChar.Name + " had WH: " + Items);
                Program.WriteLine(MyChar.Name + " had top gear: " + MyChar.Equips.HeadGear.ID + "~" + MyChar.Equips.HeadGear.Plus + "~" + MyChar.Equips.HeadGear.Bless + "~" + MyChar.Equips.HeadGear.Enchant + "~" + MyChar.Equips.HeadGear.Soc1 + "~" + MyChar.Equips.HeadGear.Soc2 + "~" + MyChar.Equips.HeadGear.Progress);
                Program.WriteLine(MyChar.Name + " had necklace: " + MyChar.Equips.Necklace.ID + "~" + MyChar.Equips.Necklace.Plus + "~" + MyChar.Equips.Necklace.Bless + "~" + MyChar.Equips.Necklace.Enchant + "~" + MyChar.Equips.Necklace.Soc1 + "~" + MyChar.Equips.Necklace.Soc2 + "~" + MyChar.Equips.Necklace.Progress);
                Program.WriteLine(MyChar.Name + " had ring: " + MyChar.Equips.Ring.ID + "~" + MyChar.Equips.Ring.Plus + "~" + MyChar.Equips.Ring.Bless + "~" + MyChar.Equips.Ring.Enchant + "~" + MyChar.Equips.Ring.Soc1 + "~" + MyChar.Equips.Ring.Soc2 + "~" + MyChar.Equips.Ring.Progress);
                Program.WriteLine(MyChar.Name + " had right hand: " + MyChar.Equips.RightHand.ID + "~" + MyChar.Equips.RightHand.Plus + "~" + MyChar.Equips.RightHand.Bless + "~" + MyChar.Equips.RightHand.Enchant + "~" + MyChar.Equips.RightHand.Soc1 + "~" + MyChar.Equips.RightHand.Soc2 + "~" + MyChar.Equips.RightHand.Progress);
                Program.WriteLine(MyChar.Name + " had left hand: " + MyChar.Equips.LeftHand.ID + "~" + MyChar.Equips.LeftHand.Plus + "~" + MyChar.Equips.LeftHand.Bless + "~" + MyChar.Equips.LeftHand.Enchant + "~" + MyChar.Equips.LeftHand.Soc1 + "~" + MyChar.Equips.LeftHand.Soc2 + "~" + MyChar.Equips.LeftHand.Progress);
                Program.WriteLine(MyChar.Name + " had armor: " + MyChar.Equips.Armor.ID + "~" + MyChar.Equips.Armor.Plus + "~" + MyChar.Equips.Armor.Bless + "~" + MyChar.Equips.Armor.Enchant + "~" + MyChar.Equips.Armor.Soc1 + "~" + MyChar.Equips.Armor.Soc2 + "~" + MyChar.Equips.Armor.Progress);
                Program.WriteLine(MyChar.Name + " had boots: " + MyChar.Equips.Boots.ID + "~" + MyChar.Equips.Boots.Plus + "~" + MyChar.Equips.Boots.Bless + "~" + MyChar.Equips.Boots.Enchant + "~" + MyChar.Equips.Boots.Soc1 + "~" + MyChar.Equips.Boots.Soc2 + "~" + MyChar.Equips.Boots.Progress);
                //and here ends the info part
                if (MyChar.MyGuild != null)
                    MyChar.MyGuild.GuildMsg("SYSTEM", MyChar.MyGuild.Members.Values.ToString(), MyChar.Name + " has logged off.", 0);
                Database.SaveCharacter(MyChar, AuthInfo.Account);
                    Game.World.H_Chars.Remove(MyChar.EntityID);
                    Game.World.H_Clients.Remove(MyChar.EntityID);
                if (Game.World.H_CharsDrawing.Contains(MyChar.EntityID))
                    Game.World.H_CharsDrawing.Remove(MyChar.EntityID);
                Game.World.Action(MyChar, Packets.GeneralData(MyChar.EntityID, 0, 0, 0, 135).Get);
                MyChar.MyClient = null;
            }
        }
Disconnect
Code:
        public void Disconnect()
        {
            try
            {
                if (Soc.Connected)
                {
                    Soc.Shutdown(SocketShutdown.Both);
                    LogOff();
                    Soc.Close();
                }
            }
            catch (Exception Exc) { Program.WriteLine(Exc); }
        }
And even more...there are no errors on the console...so IDK what's the problem...

the repeated check....(maybe it has to be removed idk....it was the same without this)
Code:
            try
            {
                foreach (Main.GameClient C in World.H_Clients.Values)
                    if ((!C.Soc.Connected || C.Soc == null || C == null) && !World.Exit)
                    {
                        C.LogOff();
                    }
            }
            catch { }
Any suggestions what could cause this character stuck in-game?
10/31/2010 20:48 _DreadNought_#2
Your problem is that your using Newestcoserver. Thank me later.
10/31/2010 20:57 ryuchetval#3
so this occurs in all newestcoserver? o.O
10/31/2010 23:32 hunterman01#4
Pretty much lol
10/31/2010 23:46 StefanHAKER#5
In Mine not... Anyway I'm gonna quit that shit soon (Also release it soon)
11/01/2010 01:15 pwerty#6
Edit : nvm =/
11/01/2010 02:32 copz1337#7
Quote:
Originally Posted by StefanHAKER View Post
In Mine not... Anyway I'm gonna quit that shit soon (Also release it soon)
Maybe because nobody logs on.
11/01/2010 10:10 ryuchetval#8
well....I though of something not sure if it's right or wrong...
I have this in a thread that runs every 200 ms....
Code:
lock (World.H_Chars)
{
some codes....
}
does this prevent players from logging out correctly?
11/01/2010 10:25 Korvacs#9
No, the lock should delay any requesting threads untill the code within the lock has completed, it doesnt cancel and requests to the object, just delays them.

Basically what your doing is, your removing an object from an array while your navigating through the array, doing this will throw an exception, you have a try {} catch {} surrounding the piece of code however you dont tell it to catch exceptions, so it doesnt catch anything and just allows the code to continue.

What you need to do is loop through your list of clients and mark those needing to be logged of, put them in a temporary dictionary for example, then once you have got all the clients that need logging off, then log them off. This must be done outside of the foreach loop you have currently.
11/01/2010 17:09 ryuchetval#10
Quote:
Originally Posted by Korvacs View Post
No, the lock should delay any requesting threads untill the code within the lock has completed, it doesnt cancel and requests to the object, just delays them.

Basically what your doing is, your removing an object from an array while your navigating through the array, doing this will throw an exception, you have a try {} catch {} surrounding the piece of code however you dont tell it to catch exceptions, so it doesnt catch anything and just allows the code to continue.

What you need to do is loop through your list of clients and mark those needing to be logged of, put them in a temporary dictionary for example, then once you have got all the clients that need logging off, then log them off. This must be done outside of the foreach loop you have currently.
so you mean something like this?
Code:
                Hashtable TempClients = World.H_Clients;
                foreach (Main.GameClient C in TempClients)
                        if ((!C.Soc.Connected || C.Soc == null || C == null) && !World.Exit)
                        {
                            C.LogOff();
                        }
                TempClients = null;
or like this
Code:
                ArrayList Clients = new ArrayList();
                foreach (Main.GameClient C in World.H_Clients.Values)
                    Clients.Add(C);
                foreach (Main.GameClient C in Clients)
                        if ((!C.Soc.Connected || C.Soc == null || C == null) && !World.Exit)
                        {
                            C.LogOff();
                        }
                Clients = null;
or both work...
11/01/2010 17:30 Korvacs#11
Both appear to be acceptable, give them a try, although out of the 2 i would suggest the first one.
11/01/2010 17:35 ryuchetval#12
k i'll try em thanks :)
11/01/2010 18:50 _DreadNought_#13
Heres an example of a try catch that will catch exceptions
Code:
try
{
      //code, ex: Every character spawn a npc next to and start sucking her/his dick
}
catch (exception e)
{
       Console.WriteLine("Exception caught! \n\n\n\t {0}", e);
}