Menu
Forums
All threads
Latest threads
New posts
Trending threads
New posts
Search forums
Trending
What's new
New posts
New profile posts
Latest activity
Members
Current visitors
New profile posts
Search profile posts
Upgrades
Log in
Register
What's new
Search
Search
Search titles only
By:
All threads
Latest threads
New posts
Trending threads
New posts
Search forums
Menu
Log in
Register
Navigation
Install the app
Install
More options
Contact us
Close Menu
Forums
Server Development
Habbo Retros
Habbo Tutorials
Updating Packet Structures
JavaScript is disabled. For a better experience, please enable JavaScript in your browser before proceeding.
You are using an out of date browser. It may not display this or other websites correctly.
You should upgrade or use an
alternative browser
.
Reply to thread
Message
<blockquote data-quote="Sledmore" data-source="post: 386019" data-attributes="member: 591"><p>It's been a long time since I wrote the previous guide. So I guess it's time I write this guide. Hopefully this is written in good enough quality, although I've done it in quite a rush.</p><p></p><p>I will miss certain bits out, but for the most part the previous guide should cover it (AS3 Sorcerer and so on).</p><p>- <a href="https://devbest.com/threads/updating-header-packet-ids-not-yet-complete-client-only.63047/" target="_blank">https://devbest.com/threads/updating-header-packet-ids-not-yet-complete-client-only.63047/</a></p><p></p><p>Updating packet structures is very easy, after 3-5 times of doing it you'll no longer require looking at this guide. Now, let's begin.</p><p></p><p><strong>In this tutorial I'll be using the following revisions:</strong></p><ul> <li data-xf-list-type="ul">PRODUCTION-201601012205-226667486 (My original PlusEMU release).<br /> </li> <li data-xf-list-type="ul">PRODUCTION-201609221203-707282381</li> </ul><p>I'll go through a couple of packets that I know have since changed.</p><p>[SPOILER="public const int AvailabilityStatusMessageComposer = 2468;"]</p><p>[PHP]</p><p> class AvailabilityStatusComposer : ServerPacket</p><p> {</p><p> public AvailabilityStatusComposer()</p><p> : base(ServerPacketHeader.AvailabilityStatusMessageComposer)</p><p> {</p><p> base.WriteBoolean(true);</p><p> base.WriteBoolean(false);</p><p> }</p><p> }</p><p>[/PHP]</p><p>[/SPOILER]</p><p>[SPOILER="public const int MessengerInitMessageComposer = 391;"]</p><p>[PHP]</p><p> class MessengerInitComposer : ServerPacket</p><p> {</p><p> public MessengerInitComposer()</p><p> : base(ServerPacketHeader.MessengerInitMessageComposer)</p><p> {</p><p> base.WriteInteger(PlusStaticGameSettings.MessengerFriendLimit);//Friends max.</p><p> base.WriteInteger(300);</p><p> base.WriteInteger(800);</p><p> base.WriteInteger(1100);</p><p> base.WriteInteger(0); // category count</p><p> }</p><p> }</p><p>[/PHP]</p><p>[/SPOILER]</p><p>[SPOILER="public const int ModeratorInitMessageComposer = 2545;"]</p><p>[PHP]</p><p> class ModeratorInitComposer : ServerPacket</p><p> {</p><p> public ModeratorInitComposer(ICollection<string> UserPresets, ICollection<string> RoomPresets, Dictionary<string, List<ModerationPresetActionMessages>> UserActionPresets, ICollection<SupportTicket> Tickets)</p><p> : base(ServerPacketHeader.ModeratorInitMessageComposer)</p><p> {</p><p> base.WriteInteger(Tickets.Count);</p><p> foreach (SupportTicket ticket in Tickets.ToList())</p><p> {</p><p> base.WriteInteger(ticket.Id);</p><p> base.WriteInteger(ticket.TabId);</p><p> base.WriteInteger(1); // Type</p><p> base.WriteInteger(114); // Category</p><p> base.WriteInteger(((int)PlusEnvironment.GetUnixTimestamp() - Convert.ToInt32(ticket.Timestamp)) * 1000);</p><p> base.WriteInteger(ticket.Score);</p><p> base.WriteInteger(0);</p><p> base.WriteInteger(ticket.SenderId);</p><p> base.WriteString(ticket.SenderName);</p><p> base.WriteInteger(ticket.ReportedId);</p><p> base.WriteString(ticket.ReportedName);</p><p> base.WriteInteger((ticket.Status == TicketStatus.PICKED) ? ticket.ModeratorId : 0);</p><p> base.WriteString(ticket.ModName);</p><p> base.WriteString(ticket.Message);</p><p> base.WriteInteger(0);</p><p> base.WriteInteger(0);</p><p> }</p><p></p><p> base.WriteInteger(UserPresets.Count);</p><p> foreach (string pre in UserPresets)</p><p> {</p><p> base.WriteString(pre);</p><p> }</p><p></p><p> base.WriteInteger(UserActionPresets.Count);</p><p> foreach (KeyValuePair<string, List<ModerationPresetActionMessages>> Cat in UserActionPresets.ToList())</p><p> {</p><p> base.WriteString(Cat.Key);</p><p> base.WriteBoolean(true);</p><p> base.WriteInteger(Cat.Value.Count);</p><p> foreach (ModerationPresetActionMessages Preset in Cat.Value.ToList())</p><p> {</p><p> base.WriteString(Preset.Caption);</p><p> base.WriteString(Preset.MessageText);</p><p> base.WriteInteger(Preset.BanTime); // Account Ban Hours</p><p> base.WriteInteger(Preset.IPBanTime); // IP Ban Hours</p><p> base.WriteInteger(Preset.MuteTime); // Mute in Hours</p><p> base.WriteInteger(0);//Trading lock duration</p><p> base.WriteString(Preset.Notice + "\n\nPlease Note: Avatar ban is an IP ban!");</p><p> base.WriteBoolean(false);//Show HabboWay</p><p> }</p><p> }</p><p></p><p> base.WriteBoolean(true); // Ticket right</p><p> base.WriteBoolean(true); // Chatlogs</p><p> base.WriteBoolean(true); // User actions alert etc</p><p> base.WriteBoolean(true); // Kick users</p><p> base.WriteBoolean(true); // Ban users</p><p> base.WriteBoolean(true); // Caution etc</p><p> base.WriteBoolean(true); // Love you, Tom</p><p></p><p> base.WriteInteger(RoomPresets.Count);</p><p> foreach (string pre in RoomPresets)</p><p> {</p><p> base.WriteString(pre);</p><p> }</p><p> }</p><p> }</p><p>[/PHP]</p><p>[/SPOILER]</p><p></p><p>Okay, so starting from easy to "hard". Again, <strong>it's important to select match case on your text editor</strong>. So first, we search for the header in the AS3 Sorcerer scripts.</p><p></p><p>To make it easier, we search for the header in the following format "[PACKET_ID]", so in out case "[2468]". This will (in most times) bring us straight to the HabboMessages class, with a bunch of other packet IDs.</p><p></p><p><strong>Result:</strong></p><p>[CODE]_-09d[2468] = _-Dz;[/CODE]</p><p></p><p>Okay, so to break that down the first part (which will always change) identifies one of the hash maps/dictionaries at the top in our case:</p><p>[CODE]private static const _-09d:Map = new _-5vF();</p><p>private static const _-5Ii:Map = new _-5vF();[/CODE]</p><p>In our case, knowing this is useless - but it may help you get somewhat more familiar.</p><p></p><p>We just need to know the value, which is "<strong>_-Dz</strong>". This is the class, exactly where our packet structure is. So the next step is to find that.</p><p></p><p>Search for "class _-Dz" in your text editor (again, remember to have match case enabled in your text editor).</p><p></p><p><strong>Result:</strong></p><p>[CODE]</p><p>//------------------------------------------------------------</p><p>//_-51J._-Dz</p><p></p><p>package _-51J</p><p>{</p><p> import _-6Pm._-3gB;</p><p> import _-4Ie._-4rz;</p><p> import _-6Pm.*;</p><p></p><p> public class _-Dz extends _-3gB implements _-4LU </p><p> {</p><p> public function _-Dz(_arg1:Function)</p><p> {</p><p> super(_arg1, _-4rz);</p><p> }</p><p> public function _-1EC():_-4rz</p><p> {</p><p> return ((_-3LD as _-4rz));</p><p> }</p><p> }</p><p>}//package _-51J[/CODE]</p><p></p><p>Okay, so I don't really have much to explain here. I only know a select bits regarding the SWF, I haven't ever bothered to learn everything - I can make a pretty accurate guess about this class, but won't be explaining much.</p><p></p><p>There is two ways we can find the packet structure here, look at both the first and second methods - notice what sticks out the most?</p><p></p><p>This class: "<strong>_-4rz</strong>", now you can simply do it this way. However I typically prefer to use the namespaces - I've always done it that way for around 2 years or so.</p><p></p><p>So you can simply search "class _-4rz" to find the packet structure. But hold that thought for now. An alternative way is to use the namespaces.</p><p></p><p>So how do we do this? it's always the second to last namespace. In our case?</p><p></p><p>[CODE]_-4Ie._-4rz[/CODE]</p><p></p><p>You may have to search a couple of times, but you'll soon hit the packet structure class - which you may forget by the time you search, so the way to identify that you're in the right place?</p><p></p><p><strong>Result:</strong></p><p>[CODE]//_-4Ie._-4rz[/CODE]</p><p><strong>Which the full class will read:</strong></p><p>[CODE]</p><p>//------------------------------------------------------------</p><p>//_-4Ie._-4rz</p><p></p><p>package _-4Ie</p><p>{</p><p> import _-6Pm._-402;</p><p> import _-6Pm.*;</p><p></p><p> public class _-4rz implements for </p><p> {</p><p></p><p> private var _-4iW:Boolean;</p><p> private var _-6gh:Boolean;</p><p></p><p> public function get isOpen():Boolean</p><p> {</p><p> return (this._-4iW);</p><p> }</p><p> public function get _-4jg():Boolean</p><p> {</p><p> return (this._-6gh);</p><p> }</p><p> public function flush():Boolean</p><p> {</p><p> this._-4iW = false;</p><p> this._-6gh = false;</p><p> return (true);</p><p> }</p><p> public function parse(_arg1:_-402):Boolean</p><p> {</p><p> this._-4iW = _arg1.readBoolean();</p><p> this._-6gh = _arg1.readBoolean();</p><p> return (true);</p><p> }</p><p></p><p> }</p><p>}//package _-4Ie[/CODE]</p><p></p><p>So now we get down to business. You will always see a method in the class named "parse", in our case:</p><p></p><p>[CODE]</p><p> public function parse(_arg1:_-402):Boolean</p><p> {</p><p> this._-4iW = _arg1.readBoolean();</p><p> this._-6gh = _arg1.readBoolean();</p><p> return (true);</p><p> }[/CODE]</p><p></p><p>And bingo - our packet structure. We now know that this packet has two booleans, however this is for our old revision - so we have to do the exact same process again in the new revision. I'm not going to show that process, as it's the exact same - and our thread will be too long, instead I'll just include the class.</p><p></p><p>[CODE]</p><p>//------------------------------------------------------------</p><p>//_-6bS._-2dx</p><p></p><p>package _-6bS</p><p>{</p><p> import _-4vy._-3SP;</p><p> import _-4vy.*;</p><p></p><p> public class _-2dx implements _-5Jv </p><p> {</p><p></p><p> private var _-0lw:Boolean;</p><p> private var _-OK:Boolean;</p><p> private var _-5iM:Boolean;</p><p></p><p> public function get isOpen():Boolean</p><p> {</p><p> return (this._-0lw);</p><p> }</p><p> public function get _-0ZD():Boolean</p><p> {</p><p> return (this._-OK);</p><p> }</p><p> public function get _-2Ou():Boolean</p><p> {</p><p> return (this._-5iM);</p><p> }</p><p> public function flush():Boolean</p><p> {</p><p> this._-0lw = false;</p><p> this._-OK = false;</p><p> this._-5iM = false;</p><p> return (true);</p><p> }</p><p> public function parse(_arg1:_-3SP):Boolean</p><p> {</p><p> this._-0lw = _arg1.readBoolean();</p><p> this._-OK = _arg1.readBoolean();</p><p> if (_arg1.bytesAvailable){</p><p> this._-5iM = _arg1.readBoolean();</p><p> };</p><p> return (true);</p><p> }</p><p></p><p> }</p><p>}//package _-6bS[/CODE]</p><p></p><p>So again, all we need here is the parse method. We can see here that there are three booleans - need I say more? A new boolean needs adding to the bottom of your class. I'll have to go into finding the value etc another time.</p><p></p><p>Let's try the messenger.</p><p></p><p>Repeat the process. Here are both parse methods in the order of old revision to new revision.</p><p></p><p><strong>Old Revision:</strong></p><p>[CODE]</p><p> public function parse(_arg1:_-402):Boolean</p><p> {</p><p> this._-O8 = _arg1._-4pl();</p><p> this._-6I- = _arg1._-4pl();</p><p> this._-1y0 = _arg1._-4pl();</p><p> this._-0rL = _arg1._-4pl();</p><p> var k:int = _arg1._-4pl();</p><p> var k:int;</p><p> while (k < k) {</p><p> this._-0SH.push(new _-2h(_arg1));</p><p> k++;</p><p> };</p><p> return (true);</p><p> }[/CODE]</p><p></p><p><strong>New Revision:</strong></p><p>[CODE]</p><p> public function parse(_arg1:_-3SP):Boolean</p><p> {</p><p> this._-8e = _arg1._-0qG();</p><p> this._-4tz = _arg1._-0qG();</p><p> this._-1QF = _arg1._-0qG();</p><p> var k:int = _arg1._-0qG();</p><p> var k:int;</p><p> while (k < k) {</p><p> this._-0X3.push(new _-3Bk(_arg1));</p><p> k++;</p><p> };</p><p> return (true);</p><p> }[/CODE]</p><p></p><p>So, we'll break down this one. I don't feel I need to explain how to identify a string, integer and boolean as it's straight forward (just look over the class, you can see within 5 seconds what is an integer or not).</p><p></p><p>The old structure is: INT, INT, INT, INT (count) { // }</p><p>The new structure is: INT, INT, INT, INT (count) { // }</p><p></p><p>So we simply need to remove one of the integers, again it's tricky to explain on how to find which one we need to remove - so we'll save that for now, just simply compare the classes to find out.</p><p></p><p>Another thing - we haven't completed the structure there, as we need to figure out what the structure inside the loop is.</p><p></p><p>[CODE]</p><p>while (k < k) {</p><p> this._-0X3.push(new _-3Bk(_arg1));</p><p> k++;</p><p> };[/CODE]</p><p></p><p>Simply take the instance in the middle, where the argument is. "_-3Bk". It's pretty obvious that this is a class. So what do we do? Duh.</p><p></p><p>Search for "class _-3Bk" and bingo. The constructor contains the missing packet structure:</p><p>[CODE]</p><p> public function _-3Bk(_arg1:_-3SP)</p><p> {</p><p> this._-6BE = _arg1._-0qG();</p><p> this._name = _arg1.readString();</p><p> }[/CODE]</p><p></p><p><strong>Which means our final structure is:</strong></p><p>[CODE]</p><p>INTEGER,</p><p>INTEGER,</p><p>INTEGER,</p><p>INTEGER (COUNT)</p><p>{</p><p>INTEGER,</p><p>STRING</p><p>}</p><p>[/CODE]</p><p></p><p>And that about wraps it up. I was going to include the moderation packet, but I think this thread is already too long. If someone wants to do that and post it in the comments I'll happily answer if it's correct or not.</p><p></p><p>Thanks.</p></blockquote><p></p>
[QUOTE="Sledmore, post: 386019, member: 591"] It's been a long time since I wrote the previous guide. So I guess it's time I write this guide. Hopefully this is written in good enough quality, although I've done it in quite a rush. I will miss certain bits out, but for the most part the previous guide should cover it (AS3 Sorcerer and so on). - [URL]https://devbest.com/threads/updating-header-packet-ids-not-yet-complete-client-only.63047/[/URL] Updating packet structures is very easy, after 3-5 times of doing it you'll no longer require looking at this guide. Now, let's begin. [B]In this tutorial I'll be using the following revisions:[/B] [LIST] [*]PRODUCTION-201601012205-226667486 (My original PlusEMU release). [*]PRODUCTION-201609221203-707282381 [/LIST] I'll go through a couple of packets that I know have since changed. [SPOILER="public const int AvailabilityStatusMessageComposer = 2468;"] [PHP] class AvailabilityStatusComposer : ServerPacket { public AvailabilityStatusComposer() : base(ServerPacketHeader.AvailabilityStatusMessageComposer) { base.WriteBoolean(true); base.WriteBoolean(false); } } [/PHP] [/SPOILER] [SPOILER="public const int MessengerInitMessageComposer = 391;"] [PHP] class MessengerInitComposer : ServerPacket { public MessengerInitComposer() : base(ServerPacketHeader.MessengerInitMessageComposer) { base.WriteInteger(PlusStaticGameSettings.MessengerFriendLimit);//Friends max. base.WriteInteger(300); base.WriteInteger(800); base.WriteInteger(1100); base.WriteInteger(0); // category count } } [/PHP] [/SPOILER] [SPOILER="public const int ModeratorInitMessageComposer = 2545;"] [PHP] class ModeratorInitComposer : ServerPacket { public ModeratorInitComposer(ICollection<string> UserPresets, ICollection<string> RoomPresets, Dictionary<string, List<ModerationPresetActionMessages>> UserActionPresets, ICollection<SupportTicket> Tickets) : base(ServerPacketHeader.ModeratorInitMessageComposer) { base.WriteInteger(Tickets.Count); foreach (SupportTicket ticket in Tickets.ToList()) { base.WriteInteger(ticket.Id); base.WriteInteger(ticket.TabId); base.WriteInteger(1); // Type base.WriteInteger(114); // Category base.WriteInteger(((int)PlusEnvironment.GetUnixTimestamp() - Convert.ToInt32(ticket.Timestamp)) * 1000); base.WriteInteger(ticket.Score); base.WriteInteger(0); base.WriteInteger(ticket.SenderId); base.WriteString(ticket.SenderName); base.WriteInteger(ticket.ReportedId); base.WriteString(ticket.ReportedName); base.WriteInteger((ticket.Status == TicketStatus.PICKED) ? ticket.ModeratorId : 0); base.WriteString(ticket.ModName); base.WriteString(ticket.Message); base.WriteInteger(0); base.WriteInteger(0); } base.WriteInteger(UserPresets.Count); foreach (string pre in UserPresets) { base.WriteString(pre); } base.WriteInteger(UserActionPresets.Count); foreach (KeyValuePair<string, List<ModerationPresetActionMessages>> Cat in UserActionPresets.ToList()) { base.WriteString(Cat.Key); base.WriteBoolean(true); base.WriteInteger(Cat.Value.Count); foreach (ModerationPresetActionMessages Preset in Cat.Value.ToList()) { base.WriteString(Preset.Caption); base.WriteString(Preset.MessageText); base.WriteInteger(Preset.BanTime); // Account Ban Hours base.WriteInteger(Preset.IPBanTime); // IP Ban Hours base.WriteInteger(Preset.MuteTime); // Mute in Hours base.WriteInteger(0);//Trading lock duration base.WriteString(Preset.Notice + "\n\nPlease Note: Avatar ban is an IP ban!"); base.WriteBoolean(false);//Show HabboWay } } base.WriteBoolean(true); // Ticket right base.WriteBoolean(true); // Chatlogs base.WriteBoolean(true); // User actions alert etc base.WriteBoolean(true); // Kick users base.WriteBoolean(true); // Ban users base.WriteBoolean(true); // Caution etc base.WriteBoolean(true); // Love you, Tom base.WriteInteger(RoomPresets.Count); foreach (string pre in RoomPresets) { base.WriteString(pre); } } } [/PHP] [/SPOILER] Okay, so starting from easy to "hard". Again, [B]it's important to select match case on your text editor[/B]. So first, we search for the header in the AS3 Sorcerer scripts. To make it easier, we search for the header in the following format "[PACKET_ID]", so in out case "[2468]". This will (in most times) bring us straight to the HabboMessages class, with a bunch of other packet IDs. [B]Result:[/B] [CODE]_-09d[2468] = _-Dz;[/CODE] Okay, so to break that down the first part (which will always change) identifies one of the hash maps/dictionaries at the top in our case: [CODE]private static const _-09d:Map = new _-5vF(); private static const _-5Ii:Map = new _-5vF();[/CODE] In our case, knowing this is useless - but it may help you get somewhat more familiar. We just need to know the value, which is "[B]_-Dz[/B]". This is the class, exactly where our packet structure is. So the next step is to find that. Search for "class _-Dz" in your text editor (again, remember to have match case enabled in your text editor). [B]Result:[/B] [CODE] //------------------------------------------------------------ //_-51J._-Dz package _-51J { import _-6Pm._-3gB; import _-4Ie._-4rz; import _-6Pm.*; public class _-Dz extends _-3gB implements _-4LU { public function _-Dz(_arg1:Function) { super(_arg1, _-4rz); } public function _-1EC():_-4rz { return ((_-3LD as _-4rz)); } } }//package _-51J[/CODE] Okay, so I don't really have much to explain here. I only know a select bits regarding the SWF, I haven't ever bothered to learn everything - I can make a pretty accurate guess about this class, but won't be explaining much. There is two ways we can find the packet structure here, look at both the first and second methods - notice what sticks out the most? This class: "[B]_-4rz[/B]", now you can simply do it this way. However I typically prefer to use the namespaces - I've always done it that way for around 2 years or so. So you can simply search "class _-4rz" to find the packet structure. But hold that thought for now. An alternative way is to use the namespaces. So how do we do this? it's always the second to last namespace. In our case? [CODE]_-4Ie._-4rz[/CODE] You may have to search a couple of times, but you'll soon hit the packet structure class - which you may forget by the time you search, so the way to identify that you're in the right place? [B]Result:[/B] [CODE]//_-4Ie._-4rz[/CODE] [B]Which the full class will read:[/B] [CODE] //------------------------------------------------------------ //_-4Ie._-4rz package _-4Ie { import _-6Pm._-402; import _-6Pm.*; public class _-4rz implements for { private var _-4iW:Boolean; private var _-6gh:Boolean; public function get isOpen():Boolean { return (this._-4iW); } public function get _-4jg():Boolean { return (this._-6gh); } public function flush():Boolean { this._-4iW = false; this._-6gh = false; return (true); } public function parse(_arg1:_-402):Boolean { this._-4iW = _arg1.readBoolean(); this._-6gh = _arg1.readBoolean(); return (true); } } }//package _-4Ie[/CODE] So now we get down to business. You will always see a method in the class named "parse", in our case: [CODE] public function parse(_arg1:_-402):Boolean { this._-4iW = _arg1.readBoolean(); this._-6gh = _arg1.readBoolean(); return (true); }[/CODE] And bingo - our packet structure. We now know that this packet has two booleans, however this is for our old revision - so we have to do the exact same process again in the new revision. I'm not going to show that process, as it's the exact same - and our thread will be too long, instead I'll just include the class. [CODE] //------------------------------------------------------------ //_-6bS._-2dx package _-6bS { import _-4vy._-3SP; import _-4vy.*; public class _-2dx implements _-5Jv { private var _-0lw:Boolean; private var _-OK:Boolean; private var _-5iM:Boolean; public function get isOpen():Boolean { return (this._-0lw); } public function get _-0ZD():Boolean { return (this._-OK); } public function get _-2Ou():Boolean { return (this._-5iM); } public function flush():Boolean { this._-0lw = false; this._-OK = false; this._-5iM = false; return (true); } public function parse(_arg1:_-3SP):Boolean { this._-0lw = _arg1.readBoolean(); this._-OK = _arg1.readBoolean(); if (_arg1.bytesAvailable){ this._-5iM = _arg1.readBoolean(); }; return (true); } } }//package _-6bS[/CODE] So again, all we need here is the parse method. We can see here that there are three booleans - need I say more? A new boolean needs adding to the bottom of your class. I'll have to go into finding the value etc another time. Let's try the messenger. Repeat the process. Here are both parse methods in the order of old revision to new revision. [B]Old Revision:[/B] [CODE] public function parse(_arg1:_-402):Boolean { this._-O8 = _arg1._-4pl(); this._-6I- = _arg1._-4pl(); this._-1y0 = _arg1._-4pl(); this._-0rL = _arg1._-4pl(); var k:int = _arg1._-4pl(); var k:int; while (k < k) { this._-0SH.push(new _-2h(_arg1)); k++; }; return (true); }[/CODE] [B]New Revision:[/B] [CODE] public function parse(_arg1:_-3SP):Boolean { this._-8e = _arg1._-0qG(); this._-4tz = _arg1._-0qG(); this._-1QF = _arg1._-0qG(); var k:int = _arg1._-0qG(); var k:int; while (k < k) { this._-0X3.push(new _-3Bk(_arg1)); k++; }; return (true); }[/CODE] So, we'll break down this one. I don't feel I need to explain how to identify a string, integer and boolean as it's straight forward (just look over the class, you can see within 5 seconds what is an integer or not). The old structure is: INT, INT, INT, INT (count) { // } The new structure is: INT, INT, INT, INT (count) { // } So we simply need to remove one of the integers, again it's tricky to explain on how to find which one we need to remove - so we'll save that for now, just simply compare the classes to find out. Another thing - we haven't completed the structure there, as we need to figure out what the structure inside the loop is. [CODE] while (k < k) { this._-0X3.push(new _-3Bk(_arg1)); k++; };[/CODE] Simply take the instance in the middle, where the argument is. "_-3Bk". It's pretty obvious that this is a class. So what do we do? Duh. Search for "class _-3Bk" and bingo. The constructor contains the missing packet structure: [CODE] public function _-3Bk(_arg1:_-3SP) { this._-6BE = _arg1._-0qG(); this._name = _arg1.readString(); }[/CODE] [B]Which means our final structure is:[/B] [CODE] INTEGER, INTEGER, INTEGER, INTEGER (COUNT) { INTEGER, STRING } [/CODE] And that about wraps it up. I was going to include the moderation packet, but I think this thread is already too long. If someone wants to do that and post it in the comments I'll happily answer if it's correct or not. Thanks. [/QUOTE]
Insert quotes…
Verification
Post reply
Forums
Server Development
Habbo Retros
Habbo Tutorials
Updating Packet Structures
Top