public void SendGroupList() { var groupCount = GetMembersCount(); for (byte i = 0, loopTo = (byte)(Members.Length - 1); i <= loopTo; i++) { if (Members[i] is object) { var packet = new PacketClass(Opcodes.SMSG_GROUP_LIST); packet.AddInt8((byte)Type); // GroupType 0:Party 1:Raid var memberFlags = (byte)(i / _clusterServiceLocator.GlobalConstants.GROUP_SUBGROUPSIZE); // If Members(i).GroupAssistant Then MemberFlags = MemberFlags Or &H1 packet.AddInt8(memberFlags); packet.AddInt32(groupCount - 1); for (byte j = 0, loopTo1 = (byte)(Members.Length - 1); j <= loopTo1; j++) { if (Members[j] is object && !ReferenceEquals(Members[j], Members[i])) { packet.AddString(Members[j].Name); packet.AddUInt64(Members[j].Guid); if (Members[j].IsInWorld) { packet.AddInt8(1); // CharOnline? } else { packet.AddInt8(0); } // CharOnline? memberFlags = (byte)(j / _clusterServiceLocator.GlobalConstants.GROUP_SUBGROUPSIZE); // If Members(j).GroupAssistant Then MemberFlags = MemberFlags Or &H1 packet.AddInt8(memberFlags); } } packet.AddUInt64(Members[Leader].Guid); packet.AddInt8((byte)LootMethod); if (_lootMaster != 255) { packet.AddUInt64(Members[_lootMaster].Guid); } else { packet.AddUInt64(0UL); } packet.AddInt8((byte)LootThreshold); packet.AddInt16(0); if (Members[i].Client is object) { Members[i].Client.Send(packet); } packet.Dispose(); } } }
private bool _disposedValue; // To detect redundant calls // IDisposable protected virtual void Dispose(bool disposing) { if (!_disposedValue) { // TODO: free unmanaged resources (unmanaged objects) and override Finalize() below. // TODO: set large fields to null. PacketClass packet; if (Type == GroupType.RAID) { packet = new PacketClass(Opcodes.SMSG_GROUP_LIST); packet.AddInt16(0); // GroupType 0:Party 1:Raid packet.AddInt32(0); // GroupCount } else { packet = new PacketClass(Opcodes.SMSG_GROUP_DESTROYED); } for (byte i = 0, loopTo = (byte)(Members.Length - 1); i <= loopTo; i++) { if (Members[i] is object) { Members[i].Group = null; if (Members[i].Client is object) { Members[i].Client.SendMultiplyPackets(packet); Members[i].GetWorld.ClientSetGroup(Members[i].Client.Index, -1); } Members[i] = null; } } packet.Dispose(); _clusterServiceLocator.WcNetwork.WorldServer.GroupSendUpdate(Id); _clusterServiceLocator.WcHandlersGroup.GrouPs.Remove(Id); } _disposedValue = true; }
public void On_CMSG_AUTH_SESSION(PacketClass packet, ClientClass client) { // _WorldCluster.Log.WriteLine(LogType.DEBUG, "[{0}] [{1}:{2}] CMSG_AUTH_SESSION", Format(TimeOfDay, "hh:mm:ss"), client.IP, client.Port) packet.GetInt16(); var clientVersion = packet.GetInt32(); var clientSessionId = packet.GetInt32(); var clientAccount = packet.GetString(); var clientSeed = packet.GetInt32(); var clientHash = new byte[20]; for (var i = 0; i <= 19; i++) { clientHash[i] = packet.GetInt8(); } var clientAddOnsSize = packet.GetInt32(); // DONE: Set client.Account var tmp = clientAccount; // DONE: Kick if existing foreach (var tmpClientEntry in _clusterServiceLocator.WorldCluster.ClienTs) { if (tmpClientEntry.Value is object) { if (tmpClientEntry.Value.Account == tmp) { if (tmpClientEntry.Value.Character is object) { tmpClientEntry.Value.Character.Dispose(); tmpClientEntry.Value.Character = null; } tmpClientEntry.Value.Dispose(); } } } client.Account = tmp; // DONE: Set client.SS_Hash var result = new DataTable(); string query; query = "SELECT sessionkey, gmlevel FROM account WHERE username = '******';"; _clusterServiceLocator.WorldCluster.GetAccountDatabase().Query(query, ref result); if (result.Rows.Count > 0) { tmp = result.Rows[0].As <string>("sessionkey"); client.Access = (AccessLevel)result.Rows[0]["gmlevel"]; } else { _clusterServiceLocator.WorldCluster.Log.WriteLine(LogType.USER, "[{0}:{1}] AUTH_UNKNOWN_ACCOUNT: Account not in DB!", client.IP, client.Port); var responseUnkAcc = new PacketClass(Opcodes.SMSG_AUTH_RESPONSE); responseUnkAcc.AddInt8((byte)AuthResult.WOW_FAIL_UNKNOWN_ACCOUNT); client.Send(responseUnkAcc); return; } client.Client.PacketEncryption.Hash = new byte[40]; for (int i = 0, loopTo = Strings.Len(tmp) - 1; i <= loopTo; i += 2) { client.Client.PacketEncryption.Hash[i / 2] = (byte)Conversion.Val("&H" + Strings.Mid(tmp, i + 1, 2)); } client.Client.PacketEncryption.IsEncryptionEnabled = true; // DONE: Disconnect clients trying to enter with an invalid build if (clientVersion < REQUIRED_BUILD_LOW || clientVersion > REQUIRED_BUILD_HIGH) { var invalidVersion = new PacketClass(Opcodes.SMSG_AUTH_RESPONSE); invalidVersion.AddInt8((byte)AuthResult.WOW_FAIL_VERSION_INVALID); client.Send(invalidVersion); return; } // TODO: Make sure the correct client connected // Dim temp() As Byte = System.Text.Encoding.ASCII.GetBytes(clientAccount) // temp = Concat(temp, BitConverter.GetBytes(0)) // temp = Concat(temp, BitConverter.GetBytes(clientSeed)) // temp = Concat(temp, BitConverter.GetBytes(client.Index)) // temp = Concat(temp, client.SS_Hash) // Dim ShaDigest() As Byte = New System.Security.Cryptography.SHA1Managed().ComputeHash(temp) // _WorldCluster.Log.WriteLine(LogType.DEBUG, "Client Hash: {0}", BitConverter.ToString(clientHash).Replace("-", "")) // _WorldCluster.Log.WriteLine(LogType.DEBUG, "Server Hash: {0}", BitConverter.ToString(ShaDigest).Replace("-", "")) // For i As Integer = 0 To 19 // If clientHash(i) <> ShaDigest(i) Then // Dim responseFail As New PacketClass(OPCODES.SMSG_AUTH_RESPONSE) // responseFail.AddInt8(AuthResponseCodes.AUTH_FAILED) // client.Send(responseFail) // Exit Sub // End If // Next // DONE: If server full then queue, If GM/Admin let in if (_clusterServiceLocator.WorldCluster.ClienTs.Count > configurationProvider.GetConfiguration().ServerPlayerLimit & client.Access <= AccessLevel.Player) { ThreadPool.QueueUserWorkItem(client.EnQueue); } else { SendLoginOk(client); } // DONE: Addons info reading var decompressBuffer = new byte[packet.Data.Length - packet.Offset + 1]; Array.Copy(packet.Data, packet.Offset, decompressBuffer, 0, packet.Data.Length - packet.Offset); packet.Data = _clusterServiceLocator.GlobalZip.DeCompress(decompressBuffer); packet.Offset = 0; // DumpPacket(packet.Data) var addOnsNames = new List <string>(); var addOnsHashes = new List <uint>(); // Dim AddOnsConsoleWrite As String = String.Format("[{0}:{1}] Client addons loaded:", client.IP, client.Port) while (packet.Offset < clientAddOnsSize) { addOnsNames.Add(packet.GetString()); addOnsHashes.Add(packet.GetUInt32()); packet.GetInt32(); // Unk7 packet.GetInt8(); // Unk6 // AddOnsConsoleWrite &= String.Format("{0}{1} AddOnName: [{2,-30}], AddOnHash: [{3:X}]", vbCrLf, vbTab, AddOnsNames(AddOnsNames.Count - 1), AddOnsHashes(AddOnsHashes.Count - 1)) } // _WorldCluster.Log.WriteLine(LogType.DEBUG, AddOnsConsoleWrite) // DONE: Build mysql addons query // Not needed already - in 1.11 addons list is removed. // DONE: Send packet var addOnsEnable = new PacketClass(Opcodes.SMSG_ADDON_INFO); for (int i = 0, loopTo1 = addOnsNames.Count - 1; i <= loopTo1; i++) { if (File.Exists(string.Format(@"interface\{0}.pub", addOnsNames[i])) && addOnsHashes[i] != 0x1C776D01U) { // We have hash data addOnsEnable.AddInt8(2); // AddOn Type [1-enabled, 0-banned, 2-blizzard] addOnsEnable.AddInt8(1); // Unk var fs = new FileStream(string.Format(@"interface\{0}.pub", addOnsNames[i]), FileMode.Open, FileAccess.Read, FileShare.Read, 258, FileOptions.SequentialScan); var fb = new byte[257]; fs.Read(fb, 0, 257); // NOTE: Read from file addOnsEnable.AddByteArray(fb); addOnsEnable.AddInt32(0); addOnsEnable.AddInt8(0); } else { // We don't have hash data or already sent to client addOnsEnable.AddInt8(2); // AddOn Type [1-enabled, 0-banned, 2-blizzard] addOnsEnable.AddInt8(1); // Unk addOnsEnable.AddInt32(0); addOnsEnable.AddInt16(0); } } client.Send(addOnsEnable); addOnsEnable.Dispose(); }