private void ParseServerLoginMessage() { #if DEBUG_PROXY Trace.WriteLine("[DEBUG] Proxy [ParseServerLoginMessage]"); #endif serverInMessage.ReadPosition = 2; if (Adler.Generate(serverInMessage) != serverInMessage.ReadChecksum()) { throw new Exception("Wrong checksum."); } Xtea.Decrypt(serverInMessage, xteaKey); serverInMessage.Size = serverInMessage.ReadInternalHead() + 8; serverInMessage.ReadPosition = 8; clientOutMessage.Reset(); Array.Copy(serverInMessage.Buffer, clientOutMessage.Buffer, serverInMessage.Size); clientOutMessage.Size = serverInMessage.Size; while (serverInMessage.ReadPosition < serverInMessage.Size) { byte cmd = serverInMessage.ReadByte(); switch (cmd) { case 0x0A: //Error message var msg = serverInMessage.ReadString(); break; case 0x0B: //For your information serverInMessage.ReadString(); break; case 0x14: //MOTD serverInMessage.ReadString(); break; case 0x1E: //Patching exe/dat/spr messages case 0x1F: case 0x20: //DisconnectClient(0x0A, "A new client is avalible, please download it first!"); break; case 0x28: //Select other login server //selectedLoginServer = random.Next(0, loginServers.Length - 1); break; case 0x64: //character list if (client.Version.Number <= ClientVersion.Version1011.Number) { int nChar = (int)serverInMessage.ReadByte(); charList = new CharacterLoginInfo[nChar]; for (int i = 0; i < nChar; i++) { charList[i].CharName = serverInMessage.ReadString(); charList[i].WorldName = serverInMessage.ReadString(); clientOutMessage.WriteAt(new byte[] { 127, 0, 0, 1 }, serverInMessage.ReadPosition); charList[i].WorldIP = serverInMessage.ReadUInt(); clientOutMessage.WriteAt(BitConverter.GetBytes((ushort)worldClientPort), serverInMessage.ReadPosition); charList[i].WorldPort = serverInMessage.ReadUShort(); if (client.Version.Number >= ClientVersion.Version981.Number) { serverInMessage.ReadByte(); //isPreviewWorld } } if (client.Version.Number >= ClientVersion.Version1011.Number) { serverInMessage.ReadUShort(); //PremiumTime } } else if (client.Version.Number >= ClientVersion.Version1012.Number) { clientOutMessage.WritePosition = serverInMessage.ReadPosition; byte nWorlds = serverInMessage.ReadByte(); clientOutMessage.WriteByte(nWorlds); WorldLoginInfo[] worldList = new WorldLoginInfo[nWorlds]; for (byte i = 0; i < nWorlds; i++) { worldList[i].ID = serverInMessage.ReadByte(); clientOutMessage.WriteByte(worldList[i].ID); worldList[i].Name = serverInMessage.ReadString(); clientOutMessage.WriteString(worldList[i].Name); worldList[i].Hostname = serverInMessage.ReadString(); clientOutMessage.WriteString("127.0.0.1"); worldList[i].Port = serverInMessage.ReadUShort(); clientOutMessage.WriteUShort((ushort)worldClientPort); worldList[i].IsPreviewWorld = serverInMessage.ReadBool(); clientOutMessage.WriteByte(Convert.ToByte(worldList[i].IsPreviewWorld)); } byte nChars = serverInMessage.ReadByte(); clientOutMessage.WriteByte(nChars); charList = new CharacterLoginInfo[nChars]; for (byte j = 0; j < nChars; j++) { byte WorldID = serverInMessage.ReadByte(); clientOutMessage.WriteByte(WorldID); charList[j].CharName = serverInMessage.ReadString(); clientOutMessage.WriteString(charList[j].CharName); charList[j].WorldName = worldList[WorldID].Name; charList[j].WorldIP = BitConverter.ToUInt32(Dns.GetHostAddresses(worldList[WorldID].Hostname)[0].GetAddressBytes(), 0); charList[j].WorldPort = worldList[WorldID].Port; charList[j].WorldIPString = worldList[WorldID].Hostname; } ushort PremiumTime = serverInMessage.ReadUShort(); clientOutMessage.WriteUShort(PremiumTime); clientOutMessage.Size = clientOutMessage.WritePosition; } break; default: break; } } clientOutMessage.WriteInternalHead(); Xtea.Encrypt(clientOutMessage, xteaKey); Adler.Generate(clientOutMessage, true); clientOutMessage.WriteHead(); SendToClient(clientOutMessage); }
private void ParseServerLoginMessage() { #if DEBUG_PROXY Trace.WriteLine("[DEBUG] Proxy [ParseServerLoginMessage]"); #endif serverInMessage.ReadPosition = 2; if (Adler.Generate(serverInMessage) != serverInMessage.ReadChecksum()) { throw new Exception("Wrong checksum."); } Xtea.Decrypt(serverInMessage, xteaKey); serverInMessage.Size = serverInMessage.ReadInternalHead() + 8; serverInMessage.ReadPosition = 8; clientOutMessage.Reset(); Array.Copy(serverInMessage.Buffer, clientOutMessage.Buffer, serverInMessage.Size); clientOutMessage.Size = serverInMessage.Size; while (serverInMessage.ReadPosition < serverInMessage.Size) { byte cmd = serverInMessage.ReadByte(); switch (cmd) { case 0x0A: //Error message var msg = serverInMessage.ReadString(); break; case 0x0B: //For your information serverInMessage.ReadString(); break; case 0x0C: //token succes case 0x0D: //token error serverInMessage.ReadByte(); break; case 0x11: //update serverInMessage.ReadString(); break; case 0x14: //MOTD serverInMessage.ReadString(); break; case 0x1E: //Patching exe/dat/spr messages case 0x1F: case 0x20: //DisconnectClient(0x0A, "A new client is avalible, please download it first!"); break; case 0x28: //session key serverInMessage.ReadString(); break; case 0x64: //character list if (client.Version.Number <= ClientVersion.Version1011.Number) { int nChar = (int)serverInMessage.ReadByte(); charList = new CharacterLoginInfo[nChar]; for (int i = 0; i < nChar; i++) { charList[i].CharName = serverInMessage.ReadString(); charList[i].WorldName = serverInMessage.ReadString(); clientOutMessage.WriteAt(new byte[] { 127, 0, 0, 1 }, serverInMessage.ReadPosition); charList[i].WorldIP = serverInMessage.ReadUInt(); clientOutMessage.WriteAt(BitConverter.GetBytes((ushort)worldClientPort), serverInMessage.ReadPosition); charList[i].WorldPort = serverInMessage.ReadUShort(); if (client.Version.Number >= ClientVersion.Version981.Number) { serverInMessage.ReadByte(); //isPreviewWorld } } if (client.Version.Number >= ClientVersion.Version1011.Number) { serverInMessage.ReadUShort(); //PremiumTime } } else if (client.Version.Number >= ClientVersion.Version1012.Number) { clientOutMessage.WritePosition = serverInMessage.ReadPosition; byte nWorlds = serverInMessage.ReadByte(); clientOutMessage.WriteByte(nWorlds); WorldLoginInfo[] worldList = new WorldLoginInfo[nWorlds]; for (byte i = 0; i < nWorlds; i++) { worldList[i].ID = serverInMessage.ReadByte(); clientOutMessage.WriteByte(worldList[i].ID); worldList[i].Name = serverInMessage.ReadString(); clientOutMessage.WriteString(worldList[i].Name); worldList[i].Hostname = serverInMessage.ReadString(); clientOutMessage.WriteString("127.0.0.1"); worldList[i].Port = serverInMessage.ReadUShort(); clientOutMessage.WriteUShort((ushort)worldClientPort); worldList[i].IsPreviewWorld = serverInMessage.ReadBool(); clientOutMessage.WriteByte(Convert.ToByte(worldList[i].IsPreviewWorld)); } byte nChars = serverInMessage.ReadByte(); clientOutMessage.WriteByte(nChars); charList = new CharacterLoginInfo[nChars]; for (byte j = 0; j < nChars; j++) { byte WorldID = serverInMessage.ReadByte(); clientOutMessage.WriteByte(WorldID); charList[j].CharName = serverInMessage.ReadString(); clientOutMessage.WriteString(charList[j].CharName); charList[j].WorldName = worldList[WorldID].Name; charList[j].WorldIP = BitConverter.ToUInt32(Dns.GetHostAddresses(worldList[WorldID].Hostname)[0].GetAddressBytes(), 0); charList[j].WorldPort = worldList[WorldID].Port; charList[j].WorldIPString = worldList[WorldID].Hostname; } /** * Not very accurately named variables, but I'll settle for some pseudocode in case of futher implementations * * if version < 10.80: * ushort PremiumTime * else if version < 10.82 * bool isPremium * uint PremiumTime (In seconds from epoch - don't quote me on this :D) * else if version >= 10.82 * byte AccountStatus (0 = normal, 1 = frozen, 2 = suspended) * bool isPremium * uint PremiumTime */ ushort PremiumTime = serverInMessage.ReadUShort(); clientOutMessage.WriteUShort(PremiumTime); if (client.Version.Number >= ClientVersion.Version1090.Number) // From 10.80 - but haven't added 10.80 support. { uint PremiumSeconds = serverInMessage.ReadUInt(); // Not sure about this name. clientOutMessage.WriteUInt(PremiumSeconds); } clientOutMessage.Size = clientOutMessage.WritePosition; } break; default: break; } } clientOutMessage.WriteInternalHead(); Xtea.Encrypt(clientOutMessage, xteaKey); Adler.Generate(clientOutMessage, true); clientOutMessage.WriteHead(); SendToClient(clientOutMessage); }
private Thing GetThing(InMessage message) { //get thing type var thingId = message.ReadUShort(); if (thingId == 0x0061 || thingId == 0x0062) { //creatures Creature creature = null; if (thingId == 0x0062) { creature = client.BattleList.GetCreature(message.ReadUInt()); if (creature == null) { throw new Exception("[GetThing] (0x0062) Can't find the creature in the battle list."); } creature.Health = message.ReadByte(); } else if (thingId == 0x0061) { //creature is not known client.BattleList.RemoveCreature(message.ReadUInt()); creature = new Creature(message.ReadUInt()); client.BattleList.AddCreature(creature); creature.Type = (CreatureType)message.ReadByte(); creature.Name = message.ReadString(); creature.Health = message.ReadByte(); } var direction = (Direction)message.ReadByte(); creature.LookDirection = direction; creature.TurnDirection = direction; creature.Outfit = message.ReadOutfit(); creature.LightLevel = message.ReadByte(); creature.LightColor = message.ReadByte(); creature.Speed = message.ReadUShort(); creature.Skull = message.ReadByte(); creature.Shield = message.ReadByte(); if (thingId == 0x0061) // emblem is sent only in packet type 0x61 { creature.Emblem = message.ReadByte(); } creature.IsImpassable = message.ReadBool(); return(creature); } else if (thingId == 0x0063) { Creature creature = client.BattleList.GetCreature(message.ReadUInt()); if (creature == null) { throw new Exception("[GetThing] (0x0063) Can't find the creature in the battle list."); } creature.TurnDirection = (Direction)message.ReadByte(); creature.IsImpassable = message.ReadBool(); return(creature); } else { return(GetItem(message, thingId)); } }
private Thing GetThing(InMessage message) { //get thing type var thingId = message.ReadUShort(); if (thingId == 0x0061 || thingId == 0x0062) { //creatures Creature creature = null; if (thingId == 0x0062) { creature = client.BattleList.GetCreature(message.ReadUInt()); if (creature == null) throw new Exception("[GetThing] (0x0062) Can't find the creature in the battle list."); creature.Health = message.ReadByte(); } else if (thingId == 0x0061) { //creature is not known client.BattleList.RemoveCreature(message.ReadUInt()); creature = new Creature(message.ReadUInt()); client.BattleList.AddCreature(creature); creature.Type = (CreatureType)message.ReadByte(); creature.Name = message.ReadString(); creature.Health = message.ReadByte(); } var direction = (Direction)message.ReadByte(); creature.LookDirection = direction; creature.TurnDirection = direction; creature.Outfit = message.ReadOutfit(); creature.LightLevel = message.ReadByte(); creature.LightColor = message.ReadByte(); creature.Speed = message.ReadUShort(); creature.Skull = message.ReadByte(); creature.Shield = message.ReadByte(); if (thingId == 0x0061) // emblem is sent only in packet type 0x61 creature.Emblem = message.ReadByte(); creature.IsImpassable = message.ReadBool(); return creature; } else if (thingId == 0x0063) { Creature creature = client.BattleList.GetCreature(message.ReadUInt()); if (creature == null) throw new Exception("[GetThing] (0x0063) Can't find the creature in the battle list."); creature.TurnDirection = (Direction)message.ReadByte(); creature.IsImpassable = message.ReadBool(); return creature; } else return GetItem(message, thingId); }
private void ParseClientMarketCreate(InMessage message) { OfferKind Kind = (OfferKind)message.ReadByte(); ushort ItemId = message.ReadUShort(); ushort Amount = message.ReadUShort(); uint PiecePrice = message.ReadUInt(); bool IsAnonymous = message.ReadBool(); }
private Thing GetThing(InMessage message) { //get thing type var thingId = message.ReadUShort(); if (thingId == 0x0061 || thingId == 0x0062) { //creatures Creature creature = null; if (thingId == 0x0062) { creature = client.BattleList.GetCreature(message.ReadUInt()); if (creature == null) throw new Exception("[GetThing] (0x0062) Can't find the creature in the battle list."); creature.Health = message.ReadByte(); } else if (thingId == 0x0061) { //creature is not known client.BattleList.RemoveCreature(message.ReadUInt()); creature = new Creature(message.ReadUInt()); client.BattleList.AddCreature(creature); creature.Type = (CreatureType)message.ReadByte(); creature.Name = message.ReadString(); creature.Health = message.ReadByte(); } var direction = (Direction)message.ReadByte(); creature.LookDirection = direction; creature.TurnDirection = direction; creature.Outfit = message.ReadOutfit(); creature.LightLevel = message.ReadByte(); creature.LightColor = message.ReadByte(); creature.Speed = message.ReadUShort(); creature.Skull = message.ReadByte(); creature.Shield = message.ReadByte(); if (thingId == 0x0061) // emblem/guildflag is sent only in packet type 0x61 { if (client.Version.Number <= ClientVersion.Version986.Number) { creature.Emblem = message.ReadByte(); } if (client.Version.Number >= ClientVersion.Version1010.Number) { var GuildFlag = message.ReadByte(); } } if (client.Version.Number >= ClientVersion.Version1010.Number) { creature.Type = (CreatureType)message.ReadByte(); if (client.Version.Number >= ClientVersion.Version1036.Number) message.ReadByte(); //Speech Category var Mark = message.ReadByte(); var NumberOfPVPHelpers = message.ReadUShort(); } creature.IsImpassable = message.ReadBool(); return creature; } else if (thingId == 0x0063) { Creature creature = client.BattleList.GetCreature(message.ReadUInt()); if (creature == null) throw new Exception("[GetThing] (0x0063) Can't find the creature in the battle list."); creature.TurnDirection = (Direction)message.ReadByte(); creature.IsImpassable = message.ReadBool(); return creature; } else return GetItem(message, thingId); }