Fixes chat (#265)

- [X] Fixes crash from chat and newer clients
- [X] Fixes issue with fake names being used
- [X] Fixes potential issue with RawName being null
- [X] Adds chat to modernuo.json settings
- [X] Removes old chat
- [X] Removes chat event sink since it probably isn't needed.

Bumps release version
This commit is contained in:
Kamron Batman 2020-09-26 18:22:23 -07:00 • committed by GitHub
parent 160e9a33bc
commit ddc58ec707
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 47 additions and 149 deletions

View file

@ -90,9 +90,6 @@ namespace Server
public static void InvokeVirtueMacroRequest(Mobile mobile, int virtueID) => public static void InvokeVirtueMacroRequest(Mobile mobile, int virtueID) =>
VirtueMacroRequest?.Invoke(mobile, virtueID); VirtueMacroRequest?.Invoke(mobile, virtueID);
public static event Action<Mobile> ChatRequest;
public static void InvokeChatRequest(Mobile m) => ChatRequest?.Invoke(m);
public static event Action<Mobile, Mobile> PaperdollRequest; public static event Action<Mobile, Mobile> PaperdollRequest;
public static void InvokePaperdollRequest(Mobile beholder, Mobile beheld) => public static void InvokePaperdollRequest(Mobile beholder, Mobile beheld) =>

View file

@ -95,7 +95,6 @@ namespace Server.Network
Register(0xA7, 4, true, RequestScrollWindow); Register(0xA7, 4, true, RequestScrollWindow);
Register(0xAD, 0, true, UnicodeSpeech); Register(0xAD, 0, true, UnicodeSpeech);
Register(0xB1, 0, true, DisplayGumpResponse); Register(0xB1, 0, true, DisplayGumpResponse);
Register(0xB5, 64, true, ChatRequest);
Register(0xB6, 9, true, ObjectHelpRequest); Register(0xB6, 9, true, ObjectHelpRequest);
Register(0xB8, 0, true, ProfileReq); Register(0xB8, 0, true, ProfileReq);
Register(0xBB, 9, false, AccountID); Register(0xBB, 9, false, AccountID);
@ -437,11 +436,6 @@ namespace Server.Network
} }
} }
public static void ChatRequest(NetState state, PacketReader pvSrc)
{
EventSink.InvokeChatRequest(state.Mobile);
}
public static void SecureTrade(NetState state, PacketReader pvSrc) public static void SecureTrade(NetState state, PacketReader pvSrc)
{ {
switch (pvSrc.ReadByte()) switch (pvSrc.ReadByte())

View file

@ -1,14 +1,16 @@
using System; using System;
using System.IO;
using Server.Accounting;
using Server.Misc;
using Server.Network; using Server.Network;
namespace Server.Engines.Chat namespace Server.Engines.Chat
{ {
public class ChatSystem public static class ChatSystem
{ {
public static bool Enabled { get; set; } = true; public static bool Enabled { get; set; }
public static void Configure()
{
Enabled = ServerConfiguration.GetOrUpdateSetting("chat.enabled", false);
}
public static void Initialize() public static void Initialize()
{ {
@ -21,7 +23,7 @@ namespace Server.Engines.Chat
to?.Send(new ChatMessagePacket(null, (int)type + 20, param1, param2)); to?.Send(new ChatMessagePacket(null, (int)type + 20, param1, param2));
} }
public static void OpenChatWindowRequest(NetState state, PacketReader pvSrc) public static void OpenChatWindowRequest(NetState state, PacketReader reader)
{ {
var from = state.Mobile; var from = state.Mobile;
@ -31,71 +33,15 @@ namespace Server.Engines.Chat
return; return;
} }
pvSrc.Seek(2, SeekOrigin.Begin); // Newer clients don't send chat username anymore so we are ignoring the rest of this packet.
var chatName = pvSrc.ReadUnicodeStringSafe((0x40 - 2) >> 1).Trim();
var acct = state.Account as Account; // TODO: How does OSI handle incognito/disguise kits?
// TODO: Does OSI still allow duplicate names?
// For now we assume they should use their raw name.
var chatName = from.RawName ?? $"Unknown User {Utility.RandomMinMax(1000000, 9999999)}";
string accountChatName = null; SendCommandTo(from, ChatCommand.OpenChatWindow, chatName);
ChatUser.AddChatUser(from, chatName);
if (acct != null)
{
accountChatName = acct.GetTag("ChatName");
}
accountChatName = accountChatName?.Trim();
if (!string.IsNullOrEmpty(accountChatName))
{
if (chatName.Length > 0 && chatName != accountChatName)
{
from.SendMessage("You cannot change chat nickname once it has been set.");
}
}
else
{
if (chatName.Length == 0)
{
SendCommandTo(from, ChatCommand.AskNewNickname);
return;
}
if (NameVerification.Validate(chatName, 2, 31, true, true, true, 0, NameVerification.SpaceDashPeriodQuote) &&
chatName.ToLower().IndexOf("system") == -1)
{
// TODO: Optimize this search
foreach (Account checkAccount in Accounts.GetAccounts())
{
var existingName = checkAccount.GetTag("ChatName");
if (existingName != null)
{
existingName = existingName.Trim();
if (Insensitive.Equals(existingName, chatName))
{
from.SendMessage("Nickname already in use.");
SendCommandTo(from, ChatCommand.AskNewNickname);
return;
}
}
}
accountChatName = chatName;
acct?.AddTag("ChatName", chatName);
}
else
{
from.SendLocalizedMessage(501173); // That name is disallowed.
SendCommandTo(from, ChatCommand.AskNewNickname);
return;
}
}
SendCommandTo(from, ChatCommand.OpenChatWindow, accountChatName);
ChatUser.AddChatUser(from);
} }
public static ChatUser SearchForUser(ChatUser from, string name) public static ChatUser SearchForUser(ChatUser from, string name)
@ -110,7 +56,7 @@ namespace Server.Engines.Chat
return user; return user;
} }
public static void ChatAction(NetState state, PacketReader pvSrc) public static void ChatAction(NetState state, PacketReader reader)
{ {
if (!Enabled) if (!Enabled)
{ {
@ -127,36 +73,35 @@ namespace Server.Engines.Chat
return; return;
} }
var lang = pvSrc.ReadStringSafe(4); var lang = reader.ReadStringSafe(4);
int actionID = pvSrc.ReadInt16(); int actionID = reader.ReadInt16();
var param = pvSrc.ReadUnicodeString(); var param = reader.ReadUnicodeString();
var handler = ChatActionHandlers.GetHandler(actionID); var handler = ChatActionHandlers.GetHandler(actionID);
if (handler != null) if (handler == null)
{
var channel = user.CurrentChannel;
if (handler.RequireConference && channel == null)
/* You must be in a conference to do this.
* To join a conference, select one from the Conference menu.
*/
{
user.SendMessage(31);
}
else if (handler.RequireModerator && !user.IsModerator)
{
user.SendMessage(29); // You must have operator status to do this.
}
else
{
handler.Callback(user, channel, param);
}
}
else
{ {
Console.WriteLine("Client: {0}: Unknown chat action 0x{1:X}: {2}", state, actionID, param); Console.WriteLine("Client: {0}: Unknown chat action 0x{1:X}: {2}", state, actionID, param);
return;
} }
var channel = user.CurrentChannel;
if (handler.RequireConference && channel == null)
{
// You must be in a conference to do this.
// To join a conference, select one from the Conference menu.
user.SendMessage(31);
return;
}
if (handler.RequireModerator && !user.IsModerator)
{
user.SendMessage(29); // You must have operator status to do this.
return;
}
handler.Callback(user, channel, param);
} }
catch (Exception e) catch (Exception e)
{ {

View file

@ -1,3 +1,5 @@
using System;
namespace Server.Engines.Chat namespace Server.Engines.Chat
{ {
public class ChatActionHandlers public class ChatActionHandlers

View file

@ -12,11 +12,12 @@ namespace Server.Engines.Chat
private static readonly List<ChatUser> m_Users = new List<ChatUser>(); private static readonly List<ChatUser> m_Users = new List<ChatUser>();
private static readonly Dictionary<Mobile, ChatUser> m_Table = new Dictionary<Mobile, ChatUser>(); private static readonly Dictionary<Mobile, ChatUser> m_Table = new Dictionary<Mobile, ChatUser>();
public ChatUser(Mobile m) public ChatUser(Mobile m, string username)
{ {
Mobile = m; Mobile = m;
Ignored = new List<ChatUser>(); Ignored = new List<ChatUser>();
Ignoring = new List<ChatUser>(); Ignoring = new List<ChatUser>();
Username = username;
} }
public Mobile Mobile { get; } public Mobile Mobile { get; }
@ -25,25 +26,7 @@ namespace Server.Engines.Chat
public List<ChatUser> Ignoring { get; } public List<ChatUser> Ignoring { get; }
public string Username public string Username { get; }
{
get
{
if (Mobile.Account is Account acct)
{
return acct.GetTag("ChatName");
}
return null;
}
set
{
if (Mobile.Account is Account acct)
{
acct.SetTag("ChatName", value);
}
}
}
public Channel CurrentChannel { get; set; } public Channel CurrentChannel { get; set; }
@ -123,7 +106,7 @@ namespace Server.Engines.Chat
} }
} }
public static ChatUser AddChatUser(Mobile from) public static ChatUser AddChatUser(Mobile from, string username)
{ {
var user = GetChatUser(from); var user = GetChatUser(from);
@ -132,7 +115,7 @@ namespace Server.Engines.Chat
return user; return user;
} }
user = new ChatUser(from); user = new ChatUser(from, username);
m_Users.Add(user); m_Users.Add(user);
m_Table[from] = user; m_Table[from] = user;
@ -168,24 +151,16 @@ namespace Server.Engines.Chat
user.Ignoring[i].RemoveIgnored(user); user.Ignoring[i].RemoveIgnored(user);
} }
if (m_Users.Contains(user)) if (m_Users.Remove(user))
{ {
ChatSystem.SendCommandTo(user.Mobile, ChatCommand.CloseChatWindow); ChatSystem.SendCommandTo(user.Mobile, ChatCommand.CloseChatWindow);
user.CurrentChannel?.RemoveUser(user); user.CurrentChannel?.RemoveUser(user);
m_Users.Remove(user);
m_Table.Remove(user.Mobile); m_Table.Remove(user.Mobile);
} }
} }
public static void RemoveChatUser(Mobile from)
{
var user = GetChatUser(from);
RemoveChatUser(user);
}
public static ChatUser GetChatUser(Mobile from) public static ChatUser GetChatUser(Mobile from)
{ {
m_Table.TryGetValue(from, out var c); m_Table.TryGetValue(from, out var c);

View file

@ -1,15 +0,0 @@
namespace Server.Chat
{
public static class ChatSystem
{
public static void Initialize()
{
EventSink.ChatRequest += EventSink_ChatRequest;
}
private static void EventSink_ChatRequest(Mobile m)
{
m.SendMessage("Chat is not currently supported.");
}
}
}