public WorldServerClient(IPEndPoint ep, string username, byte[] key) { isRunning = false; mSendCryptSize = 6; // 2 length + 4 opcode mRecvCryptSize = 2; // 2 opcode mUsername = username; Key = key; try { mSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP); mSocket.Connect(ep); } catch (SocketException ex) { BoogieCore.Log(LogType.Error, "Failed to connect to realm: {0}", ex.Message); return; } isRunning = true; WorldThread = new Thread(new ThreadStart(this.Start)); WorldThread.Name = "WS Client Thread"; WorldThread.IsBackground = true; LastUpdateTime = MM_GetTime(); WorldThread.Start(); BoogieCore.Log(LogType.System, "{0}: WS Thread Started", Time.GetTime()); }
private void Loop() { byte[] data; int dataSize; do { try { UInt32 TimeNow = MM_GetTime(); Update(TimeNow - LastUpdateTime); LastUpdateTime = MM_GetTime(); dataSize = parseSize(OnReceive(2)); data = OnReceive(dataSize); decryptData(data); processData(data); } catch (Exception ex) // Server dc'd us most likely ;P { BoogieCore.Log(LogType.Error, "Caught Exception while reading off the network: {0}", ex.Message); BoogieCore.Log(LogType.Error, "{0}", ex.StackTrace); } }while (isRunning); isRunning = false; if (mSocket.Connected) { mSocket.Disconnect(false); } BoogieCore.Log(LogType.System, "WS: Thread Stopping: {0}", Time.GetTime()); }
public void UpdatePosition(UInt32 diff) { if (TrackObj != null) { Object player = BoogieCore.world.getPlayerObject(); player.SetOrientation( player.CalculateAngle( TrackObj.GetPositionX(), TrackObj.GetPositionY() ) ); } if (MoveFlags == 0) { return; // no need to predict coordinates if we aint movin', yo } BoogieCore.Log(LogType.System, "UpdatePos diff: {0}", diff); float predictedDX = 0; float predictedDY = 0; if (oldLocation == null) { oldLocation = BoogieCore.world.getPlayerObject().GetCoordinates(); } // update predicted location double h; double speed; h = BoogieCore.world.getPlayerObject().GetOrientation(); speed = 7.0;//BoogieCore.world.getPlayerObject().runSpeed; float dt = (float)diff / 1000f; float dx = (float)Math.Cos(h) * (float)speed * dt; float dy = (float)Math.Sin(h) * (float)speed * dt; BoogieCore.Log(LogType.System, "speed: {0} dt: {1} dx: {2} dy : {3}", speed, dt, dx, dy); predictedDX = dx; predictedDY = dy; Coordinate loc = BoogieCore.world.getPlayerObject().GetCoordinates(); float realDX = loc.X - oldLocation.X; float realDY = loc.Y - oldLocation.Y; BoogieCore.Log(LogType.System, " dx: " + predictedDX + " dy : " + predictedDY + " Real dx: " + realDX + " dy : " + realDY); float predictDist = (float)Math.Sqrt(predictedDX * predictedDX + predictedDY * predictedDY); float realDist = (float)Math.Sqrt(realDX * realDX + realDY * realDY); BoogieCore.Log(LogType.System, "predict dist: {0} real dist: {1}", predictDist, realDist); if (predictDist > 0.0) { Coordinate expected = new Coordinate(loc.X + predictedDX, loc.Y + predictedDY, BoogieCore.world.getPlayerObject().GetPositionZ(), BoogieCore.world.getPlayerObject().GetOrientation()); BoogieCore.Log(LogType.System, "new loc x {0}, y {1}, z {2}", expected.X, expected.Y, expected.Z); BoogieCore.world.getPlayerObject().SetCoordinates(expected); } oldLocation = loc; }
private void TeleportHandler(WoWReader wr) { float x, y, z, orient; byte mask = wr.ReadByte(); WoWGuid guid = new WoWGuid(mask, wr.ReadBytes(WoWGuid.BitCount8(mask))); wr.ReadUInt32(); // flags wr.ReadUInt32(); // time? wr.ReadByte(); // unk 2.3.0 wr.ReadSingle(); // unk2 x = wr.ReadSingle(); y = wr.ReadSingle(); z = wr.ReadSingle(); orient = wr.ReadSingle(); wr.ReadUInt16(); // unk3 wr.ReadByte(); // unk4 BoogieCore.Log(LogType.SystemDebug, "Got teleport to: {0} {1} {2} {3}", x, y, z, orient); BoogieCore.world.getPlayerObject().SetCoordinates(new Coordinate(x, y, z, orient)); WoWWriter ww = new WoWWriter(OpCode.MSG_MOVE_TELEPORT_ACK); ww.Write(BoogieCore.world.getPlayerObject().GUID.GetOldGuid()); Send(ww.ToArray()); SendMoveHeartBeat(BoogieCore.world.getPlayerObject().GetCoordinates()); }
private void RetrieveRealmList() { Realm[] Realms; byte op = win.ReadByte(); UInt16 Length = win.ReadUInt16(); UInt32 Request = win.ReadUInt32(); UInt16 NumOfRealms = win.ReadUInt16(); Realms = new Realm[NumOfRealms]; for (int i = 0; i < NumOfRealms; i++) { if ((i + 1) % 10 == 0) { BoogieCore.Log(LogType.SystemDebug, "Retrieved realm {0} of {1}.", i + 1, NumOfRealms); } Realms[i].Type = win.ReadByte(); Realms[i].Color = win.ReadByte(); win.ReadByte(); // unk Realms[i].Name = win.ReadString(); Realms[i].Address = win.ReadString(); Realms[i].Population = win.ReadFloat(); Realms[i].NumChars = win.ReadByte(); Realms[i].Language = win.ReadByte(); Realms[i].Unk = win.ReadByte(); } byte Unk1 = win.ReadByte(); byte Unk2 = win.ReadByte(); BoogieCore.Log(LogType.SystemDebug, "Done."); String defaultRealm = BoogieCore.configFile.ReadString("Connection", "DefaultRealm"); if (defaultRealm != "") { foreach (Realm r in Realms) { if (r.Name.ToLower() == defaultRealm.ToLower()) { BoogieCore.Log(LogType.System, "Defaulting to realm {0}", defaultRealm); string[] address = r.Address.Split(':'); BoogieCore.Log(LogType.System, "Defaulting to realm {0} IP: {1} port: {2}", defaultRealm, address[0], address[1]); IPAddress WSAddr = IPAddress.Parse(address[0]);//Dns.GetHostEntry(address[0]).AddressList[0]; BoogieCore.Log(LogType.System, "IP: {0}", WSAddr.ToString()); int WSPort = Int32.Parse(address[1]); BoogieCore.ConnectToWorldServer(new IPEndPoint(WSAddr, WSPort)); return; } } } BoogieCore.Event(new Event(EventType.EVENT_REALMLIST, Time.GetTime(), Realms)); }
public static Boolean ConnectToRealmListServer() { if (!inited) { throw new Exception("Run BoogieCore.Init() first."); } if (realmListClient != null) { throw new Exception("Already connected?"); } IPAddress RLAddr; string Address = configFile.ReadString("Connection", "Host", "us.logon.worldofwarcraft.com"); int Port = configFile.ReadInteger("Connection", "Port", 3724); Regex DnsMatch = new Regex("[a-zA-Z]"); if (DnsMatch.IsMatch(Address)) { RLAddr = Dns.GetHostEntry(Address).AddressList[0]; } else { RLAddr = System.Net.IPAddress.Parse(Address); } IPEndPoint RLDest = new IPEndPoint(RLAddr, Port); Log(LogType.System, "Attempting connection to Realm List Server at {0}.", Address); try { realmListClient = new RealmListClient(); if (!realmListClient.Connect(RLDest)) { realmListClient = null; return(false); } if (!realmListClient.Logon()) { realmListClient = null; return(false); } } catch (Exception ex) { BoogieCore.Log(LogType.System, "Failed to maintain connection with realm list server. Details below:\n{0}", ex.Message); realmListClient = null; return(false); } return(true); }
public void SendChatMsg(ChatMsg Type, Languages Language, string Message) { if (Type != ChatMsg.CHAT_MSG_WHISPER || Type != ChatMsg.CHAT_MSG_CHANNEL) { SendChatMsg(Type, Language, Message, ""); } else { BoogieCore.Log(LogType.Error, "Got whisper message to send without destination"); } }
public RealmListClient(string Username, string Password) { mUsername = Username; mPassword = Password; if (mUsername.Length < 3 || mPassword.Length < 3) { BoogieCore.Log(LogType.Error, "Invalid user/pass given ({0} - {1}). Please correct in boogiebot.ini", mUsername, mPassword); mSocket.Disconnect(false); return; } }
public RealmListClient() { mUsername = BoogieCore.configFile.ReadString("Connection", "User").ToUpper(); mPassword = BoogieCore.configFile.ReadString("Connection", "Pass").ToUpper(); if (mUsername.Length < 3 || mPassword.Length < 3) { BoogieCore.Log(LogType.Error, "Invalid user/pass given ({0} - {1}). Please correct in boogiebot.ini", mUsername, mPassword); mSocket.Disconnect(false); return; } }
private bool HandleLogonChallenge() { byte op = win.ReadByte(); byte unk = win.ReadByte(); BoogieCore.Log(LogType.System, "Login Challenge: Response Type = {0}", unk); byte error = win.ReadByte(); if (error > 0) { BoogieCore.Log(LogType.System, "Login Challenge: Error = {0}", error); return(false); } B = new BigInteger(win.ReadBytes(32)); // Varies byte glen = win.ReadByte(); // Length = 1 g = win.ReadBytes(glen); // g = 7 byte Nlen = win.ReadByte(); // Length = 32 N = win.ReadBytes(Nlen); // N = B79B3E2A87823CAB8F5EBFBF8EB10108535006298B5BADBD5B53E1895E644B89 Salt = new BigInteger(win.ReadBytes(32)); // Salt = 3516482AC96291B3C84B4FC204E65B623EFC2563C8B4E42AA454D93FCD1B56BA crcsalt = win.ReadBytes(16); // Varies srp = new Srp6(new BigInteger(N), new BigInteger(g)); // A hack, yes. We just keep trying till we get an S thats not negative so we get rid of auth=4 error logging on. BigInteger S; do { a = BigInteger.Random(19 * 8); A = srp.GetA(a); I = Srp6.GetLogonHash(mUsername, mPassword); BigInteger x = Srp6.Getx(Salt, I); BigInteger u = Srp6.Getu(A, B); S = srp.ClientGetS(a, B, x, u); }while (S < 0); K = Srp6.ShaInterleave(S); M = srp.GetM(mUsername, Salt, A, B, new BigInteger(K)); unk = win.ReadByte(); // BoogieCore.wardenClient.Initialize(K); // shame you don't have this class. return(true); }
private void Handle_CreatureQuery(WoWReader wr) { Entry entry = new Entry(); entry.entry = wr.ReadUInt32(); entry.name = wr.ReadString(); entry.blarg = wr.ReadBytes(3); entry.subname = wr.ReadString(); entry.flags = wr.ReadUInt32(); entry.subtype = wr.ReadUInt32(); entry.family = wr.ReadUInt32(); entry.rank = wr.ReadUInt32(); BoogieCore.Log(LogType.NeworkComms, "Got CreatureQuery Response - Entry: {0} - Name: {1} - SubName {2}", entry.entry, entry.name, entry.subname); if (EntryList.ContainsKey(entry.entry) == false) { EntryList.Add(entry.entry, entry); } if (EntryQueue.ContainsKey(entry.entry)) { EntryQueue.Remove(entry.entry); } foreach (Object obj in BoogieCore.world.getObjectList()) { if (obj.Fields != null) { if (obj.Fields[(int)UpdateFields.OBJECT_FIELD_ENTRY] == entry.entry) { if (entry.name.Contains("Auctioneer") && SentHello == false) { WoWWriter ww = new WoWWriter(OpCode.MSG_AUCTION_HELLO); ww.Write(obj.GUID.GetOldGuid()); Send(ww.ToArray()); BoogieCore.Log(LogType.SystemDebug, "Sent AH Hello!"); SentHello = true; } obj.Name = entry.name; obj.SubName = entry.subname; obj.SubType = entry.subtype; obj.Family = entry.family; obj.Rank = entry.rank; } } } }
// Update Player, with Player Object Update Fields :D public void updatePlayer(Object po) { if (!inited) { return; } obj = po; BoogieCore.Log(LogType.System, "Player Class Updated!"); level = po.Fields[(int)UpdateFields.UNIT_FIELD_LEVEL]; //exp = po.Fields[(int)UpdateFields.PLAYER_XP]; //nextlevelexp = po.Fields[(int)UpdateFields.PLAYER_NEXT_LEVEL_XP]; hp = po.Fields[(int)UpdateFields.UNIT_FIELD_HEALTH]; // probably wrong? }
private void Handle_NameQuery(WoWReader wr) { WoWGuid guid = new WoWGuid(wr.ReadUInt64()); string name = wr.ReadString(); UInt16 unk = wr.ReadByte(); UInt32 Race = wr.ReadUInt32(); UInt32 Gender = wr.ReadUInt32(); UInt32 Level = wr.ReadUInt32(); BoogieCore.Log(LogType.NeworkComms, "Got NameQuery Response - GUID: {4} Name: {0} - Race: {1} - Gender: {2} - Level: {3}", name, Race, Gender, Level, BitConverter.ToUInt64(guid.GetNewGuid(), 0)); Object obj = BoogieCore.world.getObject(guid); if (obj != null) // Update existing object { obj.Name = name; obj.Race = Race; obj.Gender = Gender; obj.Level = Level; BoogieCore.world.updateObject(obj); } else // Create new Object -- FIXME: Add to new 'names only' list? { obj = new Object(); obj.GUID = guid; obj.Name = name; obj.Race = Race; obj.Gender = Gender; obj.Level = Level; BoogieCore.world.newObject(obj, true); } /* Process chat message if we looked them up now */ for (int i = 0; i < ChatQueued.Count; i++) { ChatQueue message = (ChatQueue)ChatQueued[i]; if (message.GUID.GetOldGuid() == guid.GetOldGuid()) { BoogieCore.Event(new Event(EventType.EVENT_CHAT, Time.GetTime(), message, name)); ChatQueued.Remove(message); } } // WoWChat uses this to retrive names on friends and ignore list. BoogieCore.Event(new Event(EventType.EVENT_NAMEQUERY_RESPONSE, Time.GetTime(), guid, name)); }
/// <summary>Tells the server to retrieve the mail list. Must be near a mailbox to work.</summary> public void getMail() { // Find the mailbox on the object list. (FIXME: Need to work out which is closest, and check if we are in range?) /*for (int i = 0; i < mObjects.Count; i++) * { * if(mObjects[i].Fields != null) // Must have Fields * if(mObjects[i].Fields.Length >= (uint)UpdateFields.GAMEOBJECT_END) // Fields array must go far enough * if(mObjects[i].Fields[(int)UpdateFields.GAMEOBJECT_TYPE_ID] == (uint)GAMEOBJECT_TYPES.GAMEOBJECT_TYPE_MAILBOX) // If its a mailbox * { * BoogieCore.Log(LogType.SystemDebug, "Attempting to read mail using mailbox {0}", mObjects[i].GUID); * BoogieCore.WorldServerClient.Query_GetMailList(mObjects[i].GUID); * return; * } * }*/ BoogieCore.Log(LogType.SystemDebug, "No nearby or known mailbox found!"); }
private void Handle_AuthResponse(WoWReader wr) { byte error = wr.ReadByte(); if (error != 0x0C) { BoogieCore.Log(LogType.Error, "WS: Authentication Failed: Error = {0}", error); return; } BoogieCore.Log(LogType.System, "WS: Authentication Successful!"); BoogieCore.Log(LogType.System, "WS: Requesting Character List..."); WoWWriter ww = new WoWWriter(OpCode.CMSG_CHAR_ENUM); Send(ww.ToArray()); PingTimer.Enabled = true; }
private void Handle_NewWorld(WoWReader wr) { Object obj = BoogieCore.world.getPlayerObject(); WorldZone(obj.GUID.GetOldGuid()); UInt32 mapid = wr.ReadUInt32(); BoogieCore.world.zoned(mapid); // Tell World we zoned, and give new mapid obj.coord = new Coordinate(wr.ReadSingle(), wr.ReadSingle(), wr.ReadSingle(), wr.ReadSingle()); WoWWriter ww = new WoWWriter(OpCode.MSG_MOVE_WORLDPORT_ACK); //ww.Write(BoogieCore.world.getPlayerObject().GUID.GetOldGuid()); Send(ww.ToArray()); SendMoveHeartBeat(obj.coord); BoogieCore.Log(LogType.System, "Got worldport for mapid: {0} xyz: {1} {2} {3}", mapid, obj.coord.X, obj.coord.Y, obj.coord.Z); BoogieCore.world.updatePlayerLocationUI(); }
private void Ping(object source, ElapsedEventArgs e) { if (!mSocket.Connected) { PingTimer.Enabled = false; PingTimer.Stop(); return; } Ping_Req_Time = MM_GetTime(); BoogieCore.Log(LogType.NeworkComms, "Ping!"); WoWWriter ww = new WoWWriter(OpCode.CMSG_PING); ww.Write(Ping_Seq); ww.Write(Latency); Send(ww.ToArray()); }
private bool HandleLogonProof() { byte op = win.ReadByte(); byte error = win.ReadByte(); if (error > 0) { BoogieCore.Log(LogType.System, "Login Proof: Error = {0}", error); return(false); } M2 = win.ReadBytes(20); int unknown = win.ReadInt32(); UInt16 unk2 = win.ReadUInt16(); win.ReadUInt32(); return(true); }
private byte[] GenerateCrc(byte[] crcsalt) { Sha1Hash sha; byte[] buffer1 = new byte[0x40]; byte[] buffer2 = new byte[0x40]; for (int i = 0; i < 0x40; ++i) { buffer1[i] = 0x36; buffer2[i] = 0x5c; } for (int i = 0; i < crcsalt.Length; ++i) { buffer1[i] ^= crcsalt[i]; buffer2[i] ^= crcsalt[i]; } sha = new Sha1Hash(); sha.Update(buffer1); try { FileStream fs = new FileStream("hash.bin", FileMode.Open, FileAccess.Read); byte[] Buffer = new byte[fs.Length]; fs.Read(Buffer, 0, (int)fs.Length); sha.Update(Buffer); } catch (Exception e) { BoogieCore.Log(LogType.Error, e.Message); } byte[] hash1 = sha.Final(); sha = new Sha1Hash(); sha.Update(buffer2); sha.Update(hash1); return(sha.Final()); }
// Initialize Player, with Player Object Update Fields :D public void setPlayer(Object po) { obj = po; BoogieCore.Log(LogType.System, "Player Class Initialized!"); level = po.Fields[(int)UpdateFields.UNIT_FIELD_LEVEL]; exp = po.Fields[(int)UpdateFields.PLAYER_XP]; nextlevelexp = po.Fields[(int)UpdateFields.PLAYER_NEXT_LEVEL_XP]; hp = po.Fields[(int)UpdateFields.UNIT_FIELD_HEALTH]; // probably wrong? // Create contained Objects questLog = new QuestLog(po); inventory = new Inventory(po); bank = new Bank(po); equipped = new Equipped(po); talents = new Talents(po); buffs = new Buffs(po); debuffs = new Debuffs(po); inited = true; }
public bool Connect(IPEndPoint ep) { try { mSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP); mSocket.Connect(ep); ns = new NetworkStream(mSocket, true); win = new WoWReader(ns); wout = new WoWWriter(ns); BoogieCore.Log(LogType.System, "Connected successfully."); return(true); } catch (Exception ex) { BoogieCore.Log(LogType.System, "Failed to open connection to realm list server. Details below:\n{0}", ex.Message); return(false); } }
public bool Logon() { if (mSocket.Connected == false) { return(false); } BoogieCore.Log(LogType.System, "Login Challenge: Sending..."); DoLogonChallenge(); BoogieCore.Log(LogType.System, "Login Challenge: Waiting on response..."); if (HandleLogonChallenge() == false) { BoogieCore.Log(LogType.System, "Login Challenge: Failed!"); mSocket.Close(); return(false); } BoogieCore.Log(LogType.System, "Login Challenge: Success!"); BoogieCore.Log(LogType.System, "Login Proof: Sending..."); DoLogonProof(); BoogieCore.Log(LogType.System, "Login Proof: Waiting on response..."); if (HandleLogonProof() == false) { BoogieCore.Log(LogType.System, "Login Proof: Authentication Failure."); mSocket.Close(); return(false); } BoogieCore.Log(LogType.System, "Login Proof: Authentication Successful"); BoogieCore.Log(LogType.System, "Sending RealmList Request..."); SendRealmlistRequest(); BoogieCore.Log(LogType.System, "Retrieving RealmList..."); RetrieveRealmList(); mSocket.Close(); return(true); }
private void Handle_GameObjectQuery(WoWReader wr) { Entry entry = new Entry(); entry.entry = wr.ReadUInt32(); if (entry.entry < 1 || wr.Remaining < 4) { BoogieCore.Log(LogType.System, "Got {1} in GameObject query response for entryid or remaining in packet too small {0}", wr.Remaining, entry.entry); return; } entry.Type = wr.ReadUInt32(); entry.DisplayID = wr.ReadUInt32(); entry.name = wr.ReadString(); BoogieCore.Log(LogType.NeworkComms, "Got GameObject Query Response - Entry: {0} - Name: {1} - Type {2}", entry.entry, entry.name, entry.Type); if (EntryList.ContainsKey(entry.entry) == false) { EntryList.Add(entry.entry, entry); } if (EntryQueue.ContainsKey(entry.entry)) { EntryQueue.Remove(entry.entry); } foreach (Object obj in BoogieCore.world.getObjectList()) { if (obj.Fields != null) { if (obj.Fields[(int)UpdateFields.OBJECT_FIELD_ENTRY] == entry.entry) { obj.Type = (byte)entry.Type; obj.Name = entry.name; } } } }
public void Send(byte[] Data) { #if (LOG) WoWReader wr = new WoWReader(Data); UInt16 Op2 = wr.ReadUInt16(); OpCode Op = (OpCode)Op2; int left = wr.Remaining; tw.Write("{"); tw.Write("CLIENT"); tw.Write("}"); tw.WriteLine(" Packet: (0x{2:x4}) {1} PacketSize = {0} TimeStamp = 0", Data.Length, Op, Op2); tw.WriteLine("|------------------------------------------------|----------------|"); tw.WriteLine("|00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F |0123456789ABCDEF|"); tw.WriteLine("|------------------------------------------------|----------------|"); Debug.DumpBuffer(wr.ReadRemaining(), left, tw); tw.WriteLine("-------------------------------------------------------------------"); tw.WriteLine(); tw.Flush(); #endif int Length = Data.Length; byte[] Packet = new byte[2 + Length]; Packet[0] = (byte)(Length >> 8); Packet[1] = (byte)(Length & 0xff); Data.CopyTo(Packet, 2); mCrypt.Encrypt(Packet, mSendCryptSize); try { mSocket.Send(Packet); } catch (SocketException e) { BoogieCore.Log(LogType.Error, "Unable to send packet! Error: {0}", e.Message); isRunning = false; } }
private void Handle_CharEnum(WoWReader wr) { BoogieCore.Log(LogType.NeworkComms, "WS: Recieved Character List.."); byte count = wr.ReadByte(); characterList = new Character[count]; for (int i = 0; i < count; i++) { characterList[i].GUID = wr.ReadUInt64(); characterList[i].Name = wr.ReadString(); characterList[i].Race = wr.ReadByte(); characterList[i].Class = wr.ReadByte(); characterList[i].Gender = wr.ReadByte(); characterList[i].Skin = wr.ReadByte(); characterList[i].Face = wr.ReadByte(); characterList[i].HairStyle = wr.ReadByte(); characterList[i].HairColor = wr.ReadByte(); characterList[i].FacialHair = wr.ReadByte(); characterList[i].Level = wr.ReadByte(); characterList[i].ZoneID = wr.ReadUInt32(); characterList[i].MapID = wr.ReadUInt32(); characterList[i].X = wr.ReadFloat(); characterList[i].Y = wr.ReadFloat(); characterList[i].Z = wr.ReadFloat(); characterList[i].Guild = wr.ReadUInt32(); characterList[i].Unk = wr.ReadUInt32(); characterList[i].RestState = wr.ReadByte(); characterList[i].PetInfoID = wr.ReadUInt32(); characterList[i].PetLevel = wr.ReadUInt32(); characterList[i].PetFamilyID = wr.ReadUInt32(); CharEquipment[] equip = new CharEquipment[20]; for (int x = 0; x < 20; x++) { equip[x].EntryID = wr.ReadUInt32(); equip[x].Type = wr.ReadByte(); wr.ReadUInt32(); // enchant (2.4 patch) } characterList[i].Equipment = equip; } BoogieCore.Log(LogType.NeworkComms, "{0} characters in total.", characterList.Length); String defaultChar = BoogieCore.configFile.ReadString("Connection", "DefaultChar"); if (defaultChar != "") { foreach (Character c in characterList) { if (c.Name.ToLower() == defaultChar.ToLower()) { BoogieCore.Log(LogType.System, "Defaulting to Character {0}", defaultChar); BoogieCore.WorldServerClient.LoginChar(c.GUID); return; } } } if (count < 1) { string name = RandomString(6, false); BoogieCore.Log(LogType.System, "Auto-Generating Human Character with the name {0}", name); WoWWriter ww = new WoWWriter(OpCode.CMSG_CHAR_CREATE); ww.Write(name); ww.Write((byte)1); // race - human ww.Write((byte)1); // class - warrior ww.Write((byte)0); // gender - male ww.Write((byte)1); // skin ww.Write((byte)1); // face ww.Write((byte)1); // hair style ww.Write((byte)1); // hair color ww.Write((byte)1); // facial hair ww.Write((byte)1); // outfit id Send(ww.ToArray()); ww = new WoWWriter(OpCode.CMSG_CHAR_ENUM); Send(ww.ToArray()); return; } if (count == 1) { BoogieCore.Log(LogType.System, "Defaulting to Character {0}", characterList[0].Name); BoogieCore.WorldServerClient.LoginChar(characterList[0].GUID); return; } BoogieCore.Event(new Event(EventType.EVENT_CHAR_LIST, Time.GetTime(), characterList)); }
private void Handle_ObjUpdate(WoWReader wr, bool Compressed) { if (Compressed) { Int32 size = wr.ReadInt32(); byte[] decomped = Foole.Utils.Compression.Decompress(size, wr.ReadRemaining()); wr = new WoWReader(decomped); } WoWGuid guid; UInt32 blockCount; byte unk1; byte blockType; byte objTypeId; blockCount = wr.ReadUInt32(); unk1 = wr.ReadByte(); BoogieCore.Log(LogType.Error, "Got obj update with {0} blocks", blockCount); for (UInt32 i = 0; i < blockCount; i++) { blockType = wr.ReadByte(); #if (DEBUG) BoogieCore.Log(LogType.NeworkComms, "Block #{0}/{1} Type: {2}", i + 1, blockCount, blockType); #endif switch (blockType) { case 0: // Fields update { byte mask = wr.ReadByte(); if (mask == 0x00) { break; } guid = new WoWGuid(mask, wr.ReadBytes(WoWGuid.BitCount8(mask))); UpdateMask UpdateMask = new UpdateMask(); byte bc = wr.ReadByte(); // Block Count UpdateMask.SetCount((ushort)(bc * 32)); UpdateMask.SetMask(wr.ReadBytes(bc * 4), bc); #if (DEBUG) BoogieCore.Log(LogType.Error, "Field Update! FieldCount: {0}", UpdateMask.GetCount()); #endif UInt32[] Fields = new UInt32[UpdateMask.GetCount()]; Object obj = BoogieCore.World.getObject(guid); if (obj == null) { BoogieCore.Log(LogType.Error, "Object with the guid {0} not recognized in field update.", guid.GetOldGuid()); } for (ushort x = 0; x < UpdateMask.GetCount(); x++) { if (UpdateMask.GetBit(x)) { if (obj == null) // FixMe { wr.ReadUInt32(); } else { obj.Fields[x] = wr.ReadUInt32(); } } } // Update Player Class if these are Player Fields being changed. if (obj != null) { if (obj.GUID.GetOldGuid() == BoogieCore.Player.Character.GUID) { BoogieCore.Player.updatePlayer(obj); } } break; } case 1: // Movement Update { byte mask = wr.ReadByte(); if (mask == 0x00) { break; } guid = new WoWGuid(mask, wr.ReadBytes(WoWGuid.BitCount8(mask))); #if (DEBUG) BoogieCore.Log(LogType.NeworkComms, "Got Movement update for GUID {0}", BitConverter.ToUInt64(guid.GetNewGuid(), 0)); #endif UInt32 flags2 = 0, unk3; float posX = 0; float posY = 0; float posZ = 0; float facing = 0; float walkSpeed, runSpeed, backWalkSpeed, swimSpeed, backSwimSpeed, turnRate = 0; byte flags = wr.ReadByte(); if ((flags & 0x20) >= 1) { #if (DEBUG) BoogieCore.Log(LogType.NeworkComms, "(flags & 20)"); #endif flags2 = wr.ReadUInt32(); wr.ReadByte(); // 2.3.3 unk3 = wr.ReadUInt32(); } if ((flags & 0x40) >= 1) { #if (DEBUG) BoogieCore.Log(LogType.NeworkComms, "(flags & 40)"); #endif posX = wr.ReadSingle(); posY = wr.ReadSingle(); posZ = wr.ReadSingle(); facing = wr.ReadSingle(); #if (DEBUG) BoogieCore.Log(LogType.NeworkComms, "Position - X: {0} Y: {1} Z: {2} Orient: {3} ", posX, posY, posZ, facing); #endif if ((flags2 & 0x02000000) >= 1) // player being transported { #if (DEBUG) BoogieCore.Log(LogType.NeworkComms, "(flags2 & 0x02000000)"); #endif wr.ReadUInt32(); //guidlow wr.ReadUInt32(); //guidhigh wr.ReadSingle(); //x wr.ReadSingle(); //y wr.ReadSingle(); //z wr.ReadSingle(); //o wr.ReadSingle(); // unk } } if ((flags & 0x20) >= 1) { #if (DEBUG) BoogieCore.Log(LogType.NeworkComms, "(flags & 20)"); #endif wr.ReadSingle(); //unk if ((flags2 & 0x2000) >= 1) { #if (DEBUG) BoogieCore.Log(LogType.NeworkComms, "(flags & 2000)"); #endif wr.ReadSingle(); // pos unk1 wr.ReadSingle(); // pos unk1 wr.ReadSingle(); // pos unk1 wr.ReadSingle(); // pos unk1 //BoogieCore.Log(LogType.NeworkComms, "Position 2 - X: {0} Y: {1} Z: {2} Orient: {3} ", punk1, punk2, punk3, punk1); } } if ((flags & 0x20) >= 1) { #if (DEBUG) BoogieCore.Log(LogType.NeworkComms, "(flags & 20)"); #endif walkSpeed = wr.ReadSingle(); runSpeed = wr.ReadSingle(); backWalkSpeed = wr.ReadSingle(); swimSpeed = wr.ReadSingle(); backSwimSpeed = wr.ReadSingle(); wr.ReadSingle(); //unk1 wr.ReadSingle(); //unk2 turnRate = wr.ReadSingle(); //BoogieCore.Log(LogType.NeworkComms, "Speed - (flags & 0x20)"); } if ((flags & 0x20) >= 1) { //BoogieCore.Log(LogType.NeworkComms, "(flags & 0x20)"); if ((flags2 & 0x00400000) >= 1) { //BoogieCore.Log(LogType.NeworkComms, "(flags2 & 0x00400000)"); UInt32 splineFlags; splineFlags = wr.ReadUInt32(); if ((splineFlags & 0x00010000) >= 1) { //BoogieCore.Log(LogType.NeworkComms, "(splineFlags & 0x00010000)"); posX = wr.ReadSingle(); posY = wr.ReadSingle(); posZ = wr.ReadSingle(); //BoogieCore.Log(LogType.NeworkComms, "Position 3 - X: {0} Y: {1} Z: {2} Orient: {3} ", posX, posY, posZ, facing); } if ((splineFlags & 0x00020000) >= 1) { //BoogieCore.Log(LogType.NeworkComms, "(splineFlags & 0x00020000)"); wr.ReadUInt64(); } if ((splineFlags & 0x00040000) >= 1) { //BoogieCore.Log(LogType.NeworkComms, "(splineFlags & 0x00040000)"); float f; f = wr.ReadSingle(); } UInt32 time1, time2, splineCount, unk4; //1.8 time1 = wr.ReadUInt32(); time2 = wr.ReadUInt32(); unk4 = wr.ReadUInt32(); splineCount = wr.ReadUInt32(); //BoogieCore.Log(LogType.NeworkComms, "splineCount = {0}", splineCount); for (UInt32 j = 0; j < splineCount + 1; j++) { posX = wr.ReadSingle(); posY = wr.ReadSingle(); posZ = wr.ReadSingle(); //BoogieCore.Log(LogType.NeworkComms, "Position 4 - X: {0} Y: {1} Z: {2} Orient: {3} ", posX, posY, posZ, facing); } } } if ((flags & 0x8) >= 1) { #if (DEBUG) BoogieCore.Log(LogType.NeworkComms, "(flags & 8)"); #endif wr.ReadUInt32(); if ((flags & 0x10) >= 1) { #if (DEBUG) BoogieCore.Log(LogType.NeworkComms, "(flags & 10)"); #endif wr.ReadUInt32(); } } else if ((flags & 0x10) >= 1) { #if (DEBUG) BoogieCore.Log(LogType.NeworkComms, "(flags & 10)"); #endif wr.ReadUInt32(); } if ((flags & 0x2) >= 1) { #if (DEBUG) BoogieCore.Log(LogType.NeworkComms, "(flags & 0x2)"); #endif wr.ReadUInt32(); } break; } case 2: // ObjCreate case 3: // ObjCreate { byte mask = wr.ReadByte(); guid = new WoWGuid(mask, wr.ReadBytes(WoWGuid.BitCount8(mask))); objTypeId = wr.ReadByte(); #if (DEBUG) BoogieCore.Log(LogType.NeworkComms, "Got Object Create Mask: 0x{0:x2} GUID: {1} ObjTypeID: {2} ", mask, BitConverter.ToUInt64(guid.GetNewGuid(), 0), objTypeId); #endif UInt32 flags2 = 0, unk3; float posX = 0; float posY = 0; float posZ = 0; float facing = 0; float walkSpeed = 0, runSpeed = 0, backWalkSpeed = 0, swimSpeed = 0, backSwimSpeed = 0, turnRate = 0; byte flags = wr.ReadByte(); if ((flags & 0x20) >= 1) { //BoogieCore.Log(LogType.NeworkComms, "(flags & 20)"); flags2 = wr.ReadUInt32(); wr.ReadByte(); // 2.3.3 unk3 = wr.ReadUInt32(); } if ((flags & 0x40) >= 1) { //BoogieCore.Log(LogType.NeworkComms, "(flags & 40)"); posX = wr.ReadSingle(); posY = wr.ReadSingle(); posZ = wr.ReadSingle(); facing = wr.ReadSingle(); //BoogieCore.Log(LogType.NeworkComms, "Position - X: {0} Y: {1} Z: {2} Orient: {3} ", posX, posY, posZ, facing); if (((flags & 0x20) >= 1 && (flags2 & 0x0200) >= 1)) // player being transported { //BoogieCore.Log(LogType.NeworkComms, "(flags & 0x20 && flags2 & 0x0200)"); wr.ReadUInt32(); //guidlow wr.ReadUInt32(); //guidhigh wr.ReadSingle(); //x wr.ReadSingle(); //y wr.ReadSingle(); //z wr.ReadSingle(); //o wr.ReadSingle(); // unk } } if ((flags & 0x20) >= 1) { //BoogieCore.Log(LogType.NeworkComms, "(flags & 20)"); wr.ReadSingle(); //unk if ((flags2 & 0x2000) >= 1) { //BoogieCore.Log(LogType.NeworkComms, "(flags & 2000)"); wr.ReadSingle(); // pos unk1 wr.ReadSingle(); // pos unk1 wr.ReadSingle(); // pos unk1 wr.ReadSingle(); // pos unk1 //BoogieCore.Log(LogType.NeworkComms, "Position 2 - X: {0} Y: {1} Z: {2} Orient: {3} ", punk1, punk2, punk3, punk1); } } if ((flags & 0x20) >= 1) { //BoogieCore.Log(LogType.NeworkComms, "(flags & 20)"); walkSpeed = wr.ReadSingle(); runSpeed = wr.ReadSingle(); backWalkSpeed = wr.ReadSingle(); swimSpeed = wr.ReadSingle(); backSwimSpeed = wr.ReadSingle(); wr.ReadSingle(); //unk1 wr.ReadSingle(); //unk2 turnRate = wr.ReadSingle(); //BoogieCore.Log(LogType.NeworkComms, "Speed - (flags & 0x20)"); } if ((flags & 0x20) >= 1) { //BoogieCore.Log(LogType.NeworkComms, "(flags & 0x20)"); if ((flags2 & 0x08000000) >= 1) { //BoogieCore.Log(LogType.NeworkComms, "(flags2 & 0x00400000)"); UInt32 splineFlags; splineFlags = wr.ReadUInt32(); if ((splineFlags & 0x00010000) >= 1) { BoogieCore.Log(LogType.NeworkComms, "(splineFlags & 0x00010000)"); posX = wr.ReadSingle(); posY = wr.ReadSingle(); posZ = wr.ReadSingle(); BoogieCore.Log(LogType.NeworkComms, "Position 3 - X: {0} Y: {1} Z: {2} Orient: {3} ", posX, posY, posZ, facing); } if ((splineFlags & 0x00020000) >= 1) { BoogieCore.Log(LogType.NeworkComms, "(splineFlags & 0x00020000)"); wr.ReadUInt64(); } if ((splineFlags & 0x00040000) >= 1) { BoogieCore.Log(LogType.NeworkComms, "(splineFlags & 0x00040000)"); float f; f = wr.ReadSingle(); } UInt32 time1, time2, splineCount, unk4; //1.8 time1 = wr.ReadUInt32(); time2 = wr.ReadUInt32(); unk4 = wr.ReadUInt32(); splineCount = wr.ReadUInt32(); BoogieCore.Log(LogType.NeworkComms, "splineCount = {0}", splineCount); for (UInt32 j = 0; j < splineCount + 1; j++) { posX = wr.ReadSingle(); posY = wr.ReadSingle(); posZ = wr.ReadSingle(); //BoogieCore.Log(LogType.NeworkComms, "Position 4 - X: {0} Y: {1} Z: {2} Orient: {3} ", posX, posY, posZ, facing); } } } if ((flags & 0x8) >= 1) { //BoogieCore.Log(LogType.NeworkComms, "(flags & 8)"); wr.ReadUInt32(); if ((flags & 0x10) >= 1) { //BoogieCore.Log(LogType.NeworkComms, "(flags & 10)"); wr.ReadUInt32(); } } else if ((flags & 0x10) >= 1) { //BoogieCore.Log(LogType.NeworkComms, "(flags & 10)"); wr.ReadUInt32(); } if ((flags & 0x2) >= 1) { //BoogieCore.Log(LogType.NeworkComms, "(flags & 0x2)"); wr.ReadUInt32(); } UpdateMask UpdateMask = new UpdateMask(); byte bc = wr.ReadByte(); // Block Count //BoogieCore.Log(LogType.Error, "Block Count = {0}, Mask = {1}, flags = {2}, flags2 = {3}", bc * 32, mask, flags, flags2); UpdateMask.SetCount((ushort)(bc * 32)); UpdateMask.SetMask(wr.ReadBytes(bc * 4), bc); if (UpdateMask.GetCount() > 2500) { int count = UpdateMask.GetCount(); BoogieCore.Log(LogType.Error, "Bad mask count = {0} ! aborting parse", count); return; } //BoogieCore.Log(LogType.NeworkComms, "(ObjCreate) FieldCount: {0}", UpdateMask.GetCount()); UInt32[] Fields = new UInt32[UpdateMask.GetCount()]; for (ushort x = 0; x < UpdateMask.GetCount(); x++) { if (UpdateMask.GetBit(x)) { Fields[x] = wr.ReadUInt32(); } } if (!BoogieCore.world.objectExists(guid)) // Add new Object { UInt32 entryid = Fields[(int)UpdateFields.OBJECT_FIELD_ENTRY]; Object NewObj = new Object(); NewObj.GUID = guid; NewObj.coord = new Coordinate(posX, posY, posZ, facing); NewObj.Type = flags; NewObj.Fields = Fields; NewObj.walkSpeed = walkSpeed; NewObj.runSpeed = runSpeed; NewObj.backWalkSpeed = backWalkSpeed; NewObj.swimSpeed = swimSpeed; NewObj.backSwimSpeed = backSwimSpeed; NewObj.turnRate = turnRate; BoogieCore.world.newObject(NewObj, false); //MoveUpdateTimer.Enabled = true; if (objTypeId == 4) { QueryName(guid); BoogieCore.Log(LogType.NeworkComms, "Adding new Player {0}", BitConverter.ToUInt64(guid.GetNewGuid(), 0)); } if (objTypeId == 3 || objTypeId == 5) { BoogieCore.Log(LogType.System, "Querying for name of object with an entry of {0} and type of {1}", entryid, objTypeId); if (EntryList.ContainsKey(entryid) == false && EntryQueue.ContainsKey(entryid) == false) { EntryQueue.Add(entryid, true); if (objTypeId == 3) { WoWWriter wr2 = CreatureQuery(guid, entryid); Send(wr2.ToArray()); BoogieCore.Log(LogType.NeworkComms, "Adding new Unit {0}", BitConverter.ToUInt64(guid.GetNewGuid(), 0)); } if (objTypeId == 5) { WoWWriter wr2 = GameObjectQuery(guid, entryid); Send(wr2.ToArray()); BoogieCore.Log(LogType.NeworkComms, "Adding new GameObject {0}", BitConverter.ToUInt64(guid.GetNewGuid(), 0)); } } } } else // Update Existing Object { Object updateObj = BoogieCore.world.getObject(guid); updateObj.coord = new Coordinate(posX, posY, posZ, facing); updateObj.Type = flags; updateObj.Fields = Fields; BoogieCore.world.updateObject(updateObj); } break; } case 4: // Out Of Range update { UInt32 count = wr.ReadUInt32(); for (UInt32 j = 0; j < count; j++) { byte mask = wr.ReadByte(); guid = new WoWGuid(mask, wr.ReadBytes(WoWGuid.BitCount8(mask))); BoogieCore.world.delObject(guid); } break; } } } }
private void Handle_InitWorldStates(WoWReader wr) { BoogieCore.Log(LogType.NeworkComms, "WS: Recieved Init World States.."); SMSG_Debug(wr); }
private void Handle_LoginSetTimeSpeed(WoWReader wr) { BoogieCore.Log(LogType.NeworkComms, "WS: Recieved Login SetTimeSpeed (??).."); SMSG_Debug(wr); }
private void Handle_SpellLogExecute(WoWReader wr) { BoogieCore.Log(LogType.NeworkComms, "WS: Recieved Spell Log Execute.."); SMSG_Debug(wr); }
private void Handle_MailList(WoWReader wr) { BoogieCore.Log(LogType.NeworkComms, "WS: Recieved Mail List.. {0} bytes.", wr.Remaining); SMSG_Debug(wr); }