Character visual change

04/10/2021 19:05 #KB#1
Hello community,
i am wondering if the GameServer sending a custom packet to whoever spawns in the fortresswar areas during fortresswar time to switch their equipped item into a colored uniform i thought of charactervisualchange.txt i tried to replace those lines

[Only registered and activated users can see links. Click Here To Register...]

with FreePVP mode to force change character visuality while wearing pvp cap to the uniform and it worked , which means somehow the client determines player's location if isfortresswar region and fortresswar time then the client changes his equipped item to the suit.
i hope you get what i am looking for, thanks in advance.
04/10/2021 20:30 sigel123456789#2
Quote:
Originally Posted by #KB View Post
Hello community,
i am wondering if the GameServer sending a custom packet to whoever spawns in the fortresswar areas during fortresswar time to switch their equipped item into a colored uniform i thought of charactervisualchange.txt i tried to replace those lines

[Only registered and activated users can see links. Click Here To Register...]

with FreePVP mode to force change character visuality while wearing pvp cap to the uniform and it worked , which means somehow the client determines player's location if isfortresswar region and fortresswar time then the client changes his equipped item to the suit.
i hope you get what i am looking for, thanks in advance.
+1
i think = change char icon
04/10/2021 20:31 JellyBitz#3
You could try to check the region from character location directly.
They are pretty close to make a quick check about it.
[Only registered and activated users can see links. Click Here To Register...]

I left here a quick example to detect if it's inside some fortress:
[Only registered and activated users can see links. Click Here To Register...]
04/10/2021 23:38 #KB#4
Quote:
Originally Posted by JellyBitz View Post
You could try to check the region from character location directly.
They are pretty close to make a quick check about it.
[Only registered and activated users can see links. Click Here To Register...]

I left here a quick example to detect if it's inside some fortress:
[Only registered and activated users can see links. Click Here To Register...]
Hey jelly,
i appreciate your reply, but you misunderstand, my problem isn't determines player if he is in the fortress or no, my problem is how to change character suit by entering a specific region.
thanks.
04/11/2021 01:16 JellyBitz#5
Quote:
Originally Posted by #KB View Post
... my problem is how to change character suit by entering a specific region.
I get it, and yes. It's easy to find out checking the packet logs inside there.

I doubt it's something coded into the client, it should be a packet handling this information because there is no item on any inventory slot (I checked some videos).

Maybe has something to do with the packet 0x3058 if I can remember correctly, which applies client effects on objects like potions usage, scrolls usage, maybe others. I didn't check futher more last time.
04/11/2021 13:22 chipno0p#6
I think you can make a auto buff which has change the character visual (just like the way how new job suit work by using skill implement on it) and then when the player teleport into specific place then using that buff. xD
04/11/2021 18:15 #KB#7
Quote:
Originally Posted by JellyBitz View Post
I get it, and yes. It's easy to find out checking the packet logs inside there.

I doubt it's something coded into the client, it should be a packet handling this information because there is no item on any inventory slot (I checked some videos).

Maybe has something to do with the packet 0x3058 if I can remember correctly, which applies client effects on objects like potions usage, scrolls usage, maybe others. I didn't check futher more last time.
Thank you bro i appreciate your every single word you wrote to help me.
but i don't think so , 0x3058 is never sent while teleporting to GATE 1 of fortresswar while fortresswar time,
by retrying i discovered something, if ignored the whole packet 0x385F gameserver won't recognize that there's a fortresswar and you won't even be able to check if theres a running fortresswar or no, i believe it is something related to 0x385F.


Quote:
Originally Posted by chipno0p View Post
I think you can make a auto buff which has change the character visual (just like the way how new job suit work by using skill implement on it) and then when the player teleport into specific place then using that buff. xD
Hello chipno0p, first thanks for your reply, i thought of this but i will have to send 0xB070 everytime someone trying to teleport to the specific region.
04/11/2021 19:17 Over56#8
Quote:
Originally Posted by #KB View Post
Hello community,
i am wondering if the GameServer sending a custom packet to whoever spawns in the fortresswar areas during fortresswar time to switch their equipped item into a colored uniform i thought of charactervisualchange.txt i tried to replace those lines

[Only registered and activated users can see links. Click Here To Register...]

with FreePVP mode to force change character visuality while wearing pvp cap to the uniform and it worked , which means somehow the client determines player's location if isfortresswar region and fortresswar time then the client changes his equipped item to the suit.
i hope you get what i am looking for, thanks in advance.
the idea it's working only with event time such as fortress , arena,ctf and ofc region also but mostlay depend on event time
04/11/2021 20:41 #KB#9
Quote:
Originally Posted by Over56 View Post
the idea it's working only with event time such as fortress , arena,ctf and ofc region also but mostlay depend on event time
Yea recently i recognized that, no event no suit, but it is still there's a packet is being sent to the client to switch the player's uniform :rtfm:
04/12/2021 02:20 JellyBitz#10
0x385F is all about fortress war notifications.

Looks like it is handled 50% internally by client since it still requires that packet.
You can try to inject to the client these and confirm that behavior.

Quote:
Opcode: 0x385F
Data: 02 // Fortress War started
Quote:
Opcode: 0x385F
Data: 06 // Fortress War ended
04/12/2021 03:20 DaxterSoul#11
Quote:
Originally Posted by JellyBitz View Post
You could try to check the region from character location directly.
They are pretty close to make a quick check about it.
[Only registered and activated users can see links. Click Here To Register...]

I left here a quick example to detect if it's inside some fortress:
[Only registered and activated users can see links. Click Here To Register...]
You should consider decomposing the RID bits into it's 3 components.
Code:
//(MSB)                                                                       (LSB)
// | 15 | 14 | 13 | 12 | 11 | 10 | 09 | 08 | 07 | 06 | 05 | 04 | 03 | 02 | 01 | 00 |
// | DB |               Z (0-127)          |              X (0 - 255)              |
// DB = DungeonBit
Build a struct that access those Information from the backing field (ushort).

If that is to complicated you are lucky because altho we don't have language features to create bit fields in C# we can create a make-shift union with StructLayout because the major components happen be 8 bits.
Code:
        [StructLayout(LayoutKind.Explicit)]
        private struct RID : IEquatable<RID>
        {
            private const int DUNGEON_MASK = 0b10000000_00000000;

            [FieldOffset(0)]
            private ushort _value;

            [FieldOffset(0)]
            private byte _x;

            [FieldOffset(1)]
            private byte _z;

            public bool IsDungeon => (_value & DUNGEON_MASK) != 0;
            public byte X => _x;
            public byte Z => _z;

            public RID(byte x, byte z)
            {
                _value = 0;
                _x = x;
                _z = z;
            }

            public RID(ushort value)
            {
                _x = 0;
                _z = 0;
                _value = value;
            }

            public RID(short value)
            {
                _x = 0;
                _z = 0;
                _value = unchecked((ushort)value);
            }

            public override string ToString() => $"{_value} [{_x}x{_z}]";

            public override int GetHashCode() => _value.GetHashCode();

            public bool Equals(RID other) => _value == other._value;

            public override bool Equals(object obj) => obj is RID other && this.Equals(other);

            public static bool operator ==(RID left, RID right) => left.Equals(right);

            public static bool operator !=(RID left, RID right) => !left.Equals(right);

            public static implicit operator ushort(RID id) => id._value;

            public static implicit operator short(RID id) => unchecked((short)id._value);

            public static implicit operator RID(ushort id) => new RID(id);

            public static implicit operator RID(short id) => new RID(id);
        }
This is old code and I didn't care to implement any fancy logic to create a Dungeon RID at that time and I'll leave the rest as homework to you.

Now onto the topic...

Quote:
Originally Posted by #KB View Post
if ignored the whole packet 0x385F gameserver won't recognize that there's a fortresswar and you won't even be able to check if theres a running fortresswar or no, i believe it is something related to 0x385F.
0x385F - SERVER_AGENT_SIEGE_UPDATE has a lot of SiegeUpdateTypes. It manages everything the client knows about fortress war but it does not specify the suit a given character is wearing. By default every character in a siege region during war period is wearing the green suit. Siege period is controlled by 0x385F. But the color of the suit is determined by the guild information about the other character, the client adjusts this automatically.
[Only registered and activated users can see links. Click Here To Register...]
The left picture shows the character after spawn injection (0x3015).
The right picture shows the character after guild assign injection (0x30FF).

FLAGWAR (CTF) and BARENA (Battle Arena) are different tho. This is mostly off the top of my head because I didn't bother checking but here the suit is determined by the PKFlag from the spawn packet. The only proof I currently have for that is, that UIIT_MSG_FLAGWAR_PICKUP_MASTERKEY is only shown if the PKFlag of your player is the same as specified in the message (packet) which I assume to be from the triggering player...
There is no packet I know off, that updates the PKFlag of an entity in the client.

So with all that out of the way...

Quote:
Originally Posted by #KB View Post
Yea recently i recognized that, no event no suit, but it is still there's a packet is being sent to the client to switch the player's uniform :rtfm:
I don't know any packet that does that and I've analyzed, named and documented about 1000 of them.

Quote:
Originally Posted by #KB View Post
i will have to send 0xB070 everytime someone trying to teleport to the specific region.
This is currently your easiest option.

Now we come to the advanced/experimental solution.
Code:
// 0 = Green
// 3 = Red
// 4 = Blue
/setoptimizecloth 0
/setoptimizecloth 3
/setoptimizecloth 4
The GM console command /setoptimizecloth is able to do just what you want and an easy entry to reverse engineer and replicate how and where the client calls 00A60F90. Being able to call this from a custom packet is the first step. But every equipment change remove this effect. A more advanced way would be to hook 9DB940. This function evaluates whether or not optimized clothing should be applied whenever equipment changes. You may add your own logic to it to work with your World- or RegionIDs.
05/10/2021 05:05 nouvolx01#12
Quote:
Originally Posted by DaxterSoul View Post
You should consider decomposing the RID bits into it's 3 components.
Code:
//(MSB)                                                                       (LSB)
// | 15 | 14 | 13 | 12 | 11 | 10 | 09 | 08 | 07 | 06 | 05 | 04 | 03 | 02 | 01 | 00 |
// | DB |               Z (0-127)          |              X (0 - 255)              |
// DB = DungeonBit
Build a struct that access those Information from the backing field (ushort).

If that is to complicated you are lucky because altho we don't have language features to create bit fields in C# we can create a make-shift union with StructLayout because the major components happen be 8 bits.
Code:
        [StructLayout(LayoutKind.Explicit)]
        private struct RID : IEquatable<RID>
        {
            private const int DUNGEON_MASK = 0b10000000_00000000;

            [FieldOffset(0)]
            private ushort _value;

            [FieldOffset(0)]
            private byte _x;

            [FieldOffset(1)]
            private byte _z;

            public bool IsDungeon => (_value & DUNGEON_MASK) != 0;
            public byte X => _x;
            public byte Z => _z;

            public RID(byte x, byte z)
            {
                _value = 0;
                _x = x;
                _z = z;
            }

            public RID(ushort value)
            {
                _x = 0;
                _z = 0;
                _value = value;
            }

            public RID(short value)
            {
                _x = 0;
                _z = 0;
                _value = unchecked((ushort)value);
            }

            public override string ToString() => $"{_value} [{_x}x{_z}]";

            public override int GetHashCode() => _value.GetHashCode();

            public bool Equals(RID other) => _value == other._value;

            public override bool Equals(object obj) => obj is RID other && this.Equals(other);

            public static bool operator ==(RID left, RID right) => left.Equals(right);

            public static bool operator !=(RID left, RID right) => !left.Equals(right);

            public static implicit operator ushort(RID id) => id._value;

            public static implicit operator short(RID id) => unchecked((short)id._value);

            public static implicit operator RID(ushort id) => new RID(id);

            public static implicit operator RID(short id) => new RID(id);
        }
This is old code and I didn't care to implement any fancy logic to create a Dungeon RID at that time and I'll leave the rest as homework to you.

Now onto the topic...


0x385F - SERVER_AGENT_SIEGE_UPDATE has a lot of SiegeUpdateTypes. It manages everything the client knows about fortress war but it does not specify the suit a given character is wearing. By default every character in a siege region during war period is wearing the green suit. Siege period is controlled by 0x385F. But the color of the suit is determined by the guild information about the other character, the client adjusts this automatically.
[Only registered and activated users can see links. Click Here To Register...]
The left picture shows the character after spawn injection (0x3015).
The right picture shows the character after guild assign injection (0x30FF).

FLAGWAR (CTF) and BARENA (Battle Arena) are different tho. This is mostly off the top of my head because I didn't bother checking but here the suit is determined by the PKFlag from the spawn packet. The only proof I currently have for that is, that UIIT_MSG_FLAGWAR_PICKUP_MASTERKEY is only shown if the PKFlag of your player is the same as specified in the message (packet) which I assume to be from the triggering player...
There is no packet I know off, that updates the PKFlag of an entity in the client.

So with all that out of the way...


I don't know any packet that does that and I've analyzed, named and documented about 1000 of them.


This is currently your easiest option.

Now we come to the advanced/experimental solution.
Code:
// 0 = Green
// 3 = Red
// 4 = Blue
/setoptimizecloth 0
/setoptimizecloth 3
/setoptimizecloth 4
The GM console command /setoptimizecloth is able to do just what you want and an easy entry to reverse engineer and replicate how and where the client calls 00A60F90. Being able to call this from a custom packet is the first step. But every equipment change remove this effect. A more advanced way would be to hook 9DB940. This function evaluates whether or not optimized clothing should be applied whenever equipment changes. You may add your own logic to it to work with your World- or RegionIDs.
can you share hook 9DB940 func?

Quote:
Originally Posted by nouvolx01 View Post
can you share hook 9DB940 func?
Quote:
void CICUser::Func_16() {
reinterpret_cast<void(__thiscall*)(CICUser*)>(0x00 9db940)(this);
}
I tried but nothing changed