Could use help with 5165 socket glitch

10/31/2013 14:20 ~Templar~#1
Edit- Found an easy fix for the problem. Edited code below on the off chance anyone else ever has this problem. (Second socket glitch)
I've been working on an old private server source (I believe its Impulses) mostly for my own programming experience. I've been able to work around or fix every glitch I've run into but there's one thing I haven't been able to figure out how to fix.
When you put a 2 socket item in Phoenix Castle gem socket screen and remove it the 2 slots stay on the GUI and you can replace it with a 1 sock item and make it 2 sock.
This is the code that came with the source regarding socketing. Can anyone point me in the direction of where to add a check for the socket actually being in the item or possibly how to make the item not removable from the GUI to start with?

case 1027:
{
uint MainUID = BitConverter.ToUInt32(Data, 8);
uint GemUID = BitConverter.ToUInt32(Data, 12);

Game.Item MainItem = GC.MyChar.FindInvItem(MainUID);
Game.Item Gem = GC.MyChar.FindInvItem(GemUID);

byte Mode = Data[18];
byte Slot = Data[16];

if (Mode == 0)
{
GC.MyChar.RemoveItem(MainItem);
GC.MyChar.RemoveItem(Gem);

if (Slot == 1 && MainItem.Soc1 != NewestCOServer.Game.Item.Gem.NoSocket)
MainItem.Soc1 = (Game.Item.Gem)(Gem.ID - 700000);
if (Slot == 2 && MainItem.Soc2 != NewestCOServer.Game.Item.Gem.NoSocket)
MainItem.Soc2 = (Game.Item.Gem)(Gem.ID - 700000);
GC.MyChar.AddItem(MainItem);
}
else
{
GC.MyChar.RemoveItem(MainItem);
if (Slot == 1 && MainItem.Soc1 != NewestCOServer.Game.Item.Gem.NoSocket)
MainItem.Soc1 = Game.Item.Gem.EmptySocket;
if (Slot == 2 && MainItem.Soc2 != NewestCOServer.Game.Item.Gem.NoSocket)
MainItem.Soc2 = Game.Item.Gem.EmptySocket;
GC.MyChar.AddItem(MainItem);
}

break;
}
11/25/2013 14:47 Ciarda#2
This works a charm! :) only problem I have now is that when I tested it when I double click the 2 soc item to remove it and put the 1 socket in and it allows to put 2 gems in still and when I click socket it uses both gems but only puts 1 gem in the item and it keeps it 1 socket do you have a fix for this? it needs to know that if its 1 socket to only display 1 gem slot and not 2 :P

When I do 1 socket item then replace it with 2 socket item it corrects the gem slots but when 2 socket to 1 socket it keeps 2 gem slots
11/25/2013 15:47 Super Aids#3
Check whether the item has 2sockets? LOL.

Here is how I do it in my source.
Copy-pasting won't work, so use it as a reference.
Code:
public static void Handle(Entities.GameClient client, DataPacket packet)
		{
			if (client.Booth != null)
				return;
			using (var socket = new GemSocketingPacket(packet))
			{
				if (!client.Inventory.ContainsByUID(socket.ItemUID) &&
				    !client.Inventory.ContainsByUID(socket.GemUID))
				{
					return;
				}
				
				Data.ItemInfo SocketItem = client.Inventory.GetItemByUID(socket.ItemUID);
				if (SocketItem.CurrentDura < SocketItem.MaxDura)
					return;
				if (!socket.RemoveGem)
				{
					if (SocketItem.Gem1 != Enums.SocketGem.EmptySocket && socket.Socket == 1)
					{
						return;
					}
					else if (SocketItem.Gem2 != Enums.SocketGem.EmptySocket)
					{
						return;
					}
					
					Data.ItemInfo Gem = client.Inventory.GetItemByUID(socket.GemUID);
					if (Gem == null || SocketItem == null)
					{
						return;
					}
					if (SocketItem.IsGarment() || SocketItem.IsArrow() || SocketItem.IsBottle() ||
					    SocketItem.IsSteed() || SocketItem.IsMisc() || SocketItem.IsFan() || SocketItem.IsTower())
					{
						return;
					}
					
					Enums.SocketGem gem = (Enums.SocketGem)(Gem.ItemID % 100);
					
					if (gem != Enums.SocketGem.NormalThunderGem &&
					    gem != Enums.SocketGem.RefinedThunderGem &&
					    gem != Enums.SocketGem.SuperThunderGem &&
					    gem != Enums.SocketGem.NormalGloryGem &&
					    gem != Enums.SocketGem.RefinedGloryGem &&
					    gem != Enums.SocketGem.SuperGloryGem)
					{
						if (socket.Socket == 1)
						{
							SocketItem.Gem1 = gem;
						}
						else
						{
							SocketItem.Gem2 = gem;
						}
						
						Database.CharacterDatabase.SaveInventory(client, SocketItem, client.Inventory.GetPositionFromItemUID(SocketItem.UID));
						client.Inventory.RemoveItemByUID(Gem.UID);
						SocketItem.SendPacket(client, 3);
					}
				}
				else
				{
					if (SocketItem.Gem1 == Enums.SocketGem.EmptySocket && socket.Socket == 1
					    || SocketItem.Gem1 == Enums.SocketGem.NoSocket && socket.Socket == 1)
					{
						return;
					}
					else if (SocketItem.Gem2 == Enums.SocketGem.EmptySocket && socket.Socket != 1
					         ||SocketItem.Gem2 == Enums.SocketGem.NoSocket && socket.Socket != 1)
					{
						return;
					}
					
					if (socket.Socket == 1)
					{
						SocketItem.Gem1 = Enums.SocketGem.EmptySocket;
					}
					else
					{
						SocketItem.Gem2 = Enums.SocketGem.EmptySocket;
					}
					
					Database.CharacterDatabase.SaveInventory(client, SocketItem, client.Inventory.GetPositionFromItemUID(SocketItem.UID));
					SocketItem.SendPacket(client, 3);
				}
			}
		}
11/25/2013 17:21 Ciarda#4
Thanks didnt even think about that done and working now ty
01/09/2014 10:57 ~Templar~#5
I'm working on another problem now that I just recently discovered... Could use some help with it.

If a player logs on to the same character that's already online it usually has a code to deal with it and kick one- BUT if the player opens 2 clients and clicks login at the EXACT same time both clients are able to login to the same character.

This leaves huge room for exploitation/duplication and I need a fix.

I've tried thread sleeps, delaying connections, tried to figure out a way to check for character logged in twice... not having much luck in my endeavor.

Thanks in advance for any assistance or guidance.
01/09/2014 21:52 Super Aids#6
Packet 1052.
01/10/2014 14:54 ~Templar~#7
So what does packet 1052 need added to it to stop this from happening?
It already has:

Code:
                                    while (Game.World.H_Chars.Contains(GC.MyChar.EntityID))
                                    {
                                        GC.MyChar = Database.LoadCharacter(GC.AuthInfo.Character, ref Acc);
                                        Game.Character Old = (Game.Character)Game.World.H_Chars[GC.MyChar.EntityID];
                                        Old.MyClient.Disconnect();
                                        Program.WriteLine("   " + GC.MyChar.Name + " was kicked off a different client.");
                                        new System.Threading.Thread(new ThreadStart(
                                        delegate()
                                        {
                                            System.Threading.Thread.Sleep(200);
                                            Game.World.H_Chars.Remove(Old.EntityID);
                                            System.Threading.Thread.Sleep(200);
                                            GC.LocalMessage(2000, "This account has been logged in from different client! You are advised to change you password immediately!");
                                        }
                                        )).Start();

                                    }
                                    GC.MyChar.MyClient = GC;
                                    GC.MyChar.AccountName = Acc;
                                    GC.AddSend(Packets.SystemMessage(GC.MessageID, "ANSWER_OK"));
                                    GC.AddSend(Packets.CharacterInfo(GC.MyChar));
                                    GC.AddSend(Packets.Status(GC.MyChar.EntityID, Game.Status.VIPLevel, GC.MyChar.VipLevel));
                                    GC.AddSend(Packets.Time());
                                    GC.AddSend(Packets.Donators(GC.MyChar));
                                    GC.AddSend(Packets.Status(GC.MyChar.EntityID, Game.Status.Effect, 0));
                                    Program.WriteLine("      " + GC.MyChar.Name + " has logged on.");

                                }
                                GC.EndSend();
But that only prevents logging onto a character twice if its already on, not if you login to it at the same time.
Is there some kind of
if (GC.MyClient > 1)
GC.MyChar.Disconnect();
Code I can use?