* SMSG_CHANNEL_NOTIFY with ChannelNotification.YouJoined.
* SMSG_CHANNEL_NOTIFY with ChannelNotification.YouLeft.
* SMSG_USERLIST_ADD/SMSG_USERLIST_UPDATE opcodes. These may not be 100% correct, however. Needs checking. Seemngly SMSG_USERLIST_UPDATE is never sent?
* SMSG_CHANNEL_LIST, the channel user list opcode.
* SMSG_CHANNEL_NOTIFY with ChannelNotification.NotModerator.
* Some comments. IMPORTANT: WCell's ChannelNotification enum is OUTDATED. This is one of the reasons why moderator status commands are broken. I'll get to this later.
Code
Index: Services/WCell.RealmServer/Chat/ChatChannel.cs
===================================================================
--- Services/WCell.RealmServer/Chat/ChatChannel.cs (revision 1053)
+++ Services/WCell.RealmServer/Chat/ChatChannel.cs (working copy)
@@ -205,7 +205,7 @@
}
/// <summary>
- /// Whether or not the channel is constant.
+ /// Whether or not the channel is constant. That is, General/LFG/Guild Rec., etc.
/// </summary>
public bool IsConstant { get; set; }
@@ -370,15 +370,15 @@
return;
}
- ChannelHandler.SendYouJoinedReply(user, Name);
+ ChannelHandler.SendYouJoinedReply(user, this);
- if (Announces)
- {
- ChannelHandler.SendJoinedReplyToEveryone(this, user.EntityId);
- }
-
var member = user.Role.IsStaff ? new ChannelMember(user, ChannelMemberFlags.Moderator) : new ChannelMember(user);
+ if (Announces)
+ {
+ ChannelHandler.SendJoinedReplyToEveryone(this, member);
+ }
+
if (!IsConstant && m_owner == null)
{
Owner = member;
Index: Services/WCell.RealmServer/Handlers/ChannelHandler.cs
===================================================================
--- Services/WCell.RealmServer/Handlers/ChannelHandler.cs (revision 1053)
+++ Services/WCell.RealmServer/Handlers/ChannelHandler.cs (working copy)
@@ -39,7 +39,8 @@
//int channelNumber = packet.ReadInt32();
uint channelId = packet.ReadUInt32(); // used for lookup in dbc for flags
- ushort unk = packet.ReadUInt16();// packet.SkipBytes(1); // Unknown
+ byte unk = packet.ReadByte(); // Unknown
+ byte unk2 = packet.ReadByte(); // Unknown
string channelName = packet.ReadCString();
string password = packet.ReadCString();
@@ -64,7 +65,7 @@
[ClientPacketHandler(RealmServerOpCode.CMSG_LEAVE_CHANNEL)]
public static void HandleLeaveChannel(IRealmClient client, RealmPacketIn packet)
{
- var channelNumber = packet.ReadUInt32();
+ var channelNumber = packet.ReadUInt32(); // unk
var channelName = packet.ReadCString();
var chan = ChatChannelGroup.RetrieveChannel(client.ActiveCharacter, channelName);
@@ -393,17 +394,17 @@
#endregion
#region Send Methods
- public static void SendChannelNotify(IPacketReceiver client, string chan, EntityId targetChr, ChannelNotification notification)
- {
- using (var packet = new RealmPacketOut(RealmServerOpCode.SMSG_CHANNEL_NOTIFY))
- {
- packet.WriteByte((byte)ChannelNotification.AlreadyOnChannel);
- packet.WriteCString(chan);
- packet.Write(targetChr);
+ //public static void SendChannelNotify(IPacketReceiver client, string chan, EntityId targetChr, ChannelNotification notification)
+ //{
+ // using (var packet = new RealmPacketOut(RealmServerOpCode.SMSG_CHANNEL_NOTIFY))
+ // {
+ // packet.WriteByte((byte)ChannelNotification.AlreadyOnChannel);
+ // packet.WriteCString(chan);
+ // packet.Write(targetChr);
- client.Send(packet);
- }
- }
+ // client.Send(packet);
+ // }
+ //}
/// <summary>
/// Send the "already on channel" reply
@@ -476,15 +477,15 @@
/// </summary>
/// <param name="client">the client the outdoing packet belongs to</param>
/// <param name="chan">name of channel</param>
- public static void SendYouJoinedReply(IPacketReceiver client, string chan)
+ public static void SendYouJoinedReply(IPacketReceiver client, ChatChannel chan)
{
using (RealmPacketOut packet = new RealmPacketOut(RealmServerOpCode.SMSG_CHANNEL_NOTIFY))
{
packet.WriteByte((byte)ChannelNotification.YouJoined);
- packet.WriteCString(chan);
- //packet.WriteUInt(channelNum);
+ packet.WriteCString(chan.Name);
+ packet.Write((byte)chan.Flags);
+ packet.WriteUInt(chan.ChannelId);
packet.WriteUInt(0);
- packet.WriteUInt(0);
client.Send(packet);
}
@@ -536,7 +537,6 @@
packet.WriteByte((byte)ChannelNotification.YouLeft);
packet.WriteCString(chan);
packet.WriteUInt(channelId);
- packet.WriteUInt(0);
packet.WriteByte(0);
client.Send(packet);
@@ -553,7 +553,7 @@
using (RealmPacketOut packet = new RealmPacketOut(RealmServerOpCode.SMSG_CHANNEL_NOTIFY))
{
packet.WriteByte((byte)ChannelNotification.NotModerator);
- packet.WriteCString(chan);
+ //packet.WriteCString(chan);
client.Send(packet);
}
@@ -660,24 +660,17 @@
{
using (var packet = new RealmPacketOut(RealmServerOpCode.SMSG_CHANNEL_LIST))
{
- packet.Write(0x03);
- packet.Write(chan.Members.Count);
+ packet.Write((byte)0x01); // unk - 0x03?
+ packet.WriteCString(chan.Name);
+ packet.Write((byte)chan.Flags);
+ // Note: InsertIntAt might be used here later if we want
+ // to do some sort of "GM shouldn't be included" check.
+ packet.WriteUInt(chan.Members.Count);
foreach (var mi in chan.Members.Values)
{
packet.Write(mi.User.EntityId);
-
- byte mode = 0;
- if (mi.IsMuted)
- {
- mode |= 0x04;
- }
- if (mi.IsModerator)
- {
- mode |= 0x02;
- }
-
- packet.WriteByte(mode);
+ packet.Write((byte)mi.Flags);
}
client.Send(packet);
@@ -689,15 +682,23 @@
/// </summary>
/// <param name="chan">name of channel</param>
/// <param name="sender">sender (to check the ignore list)</param>
- public static void SendJoinedReplyToEveryone(ChatChannel chan, EntityId sender)
+ public static void SendJoinedReplyToEveryone(ChatChannel chan, ChannelMember sender)
{
- using (RealmPacketOut packet = new RealmPacketOut(RealmServerOpCode.SMSG_CHANNEL_NOTIFY))
+ // the packet has the same size no matter the opcode, so it's really
+ // a retarded way of doing it... but blame blizz.
+ var opcode = chan.IsConstant ? RealmServerOpCode.SMSG_USERLIST_ADD
+ : RealmServerOpCode.SMSG_USERLIST_UPDATE;
+
+ using (RealmPacketOut packet = new RealmPacketOut(opcode))
{
- packet.WriteByte((byte)ChannelNotification.PlayerJoined);
- packet.WriteCString(chan.Name);
- packet.Write(sender);
+ //packet.WriteByte((byte)ChannelNotification.PlayerJoined);
+ packet.Write(sender.User.EntityId);
+ packet.Write((byte)sender.Flags);
+ packet.Write((byte)chan.ClientFlags);
+ packet.WriteUInt(chan.MemberCount);
+ packet.WriteCString(chan.Name);
- SendPacketToChannel(chan, packet, sender);
+ SendPacketToChannel(chan, packet, sender.User.EntityId);
}
}