mirror of
https://github.com/SoDOff-Project/sodoff-mmo.git
synced 2025-10-11 08:18:49 -07:00
updates related to chat moderation
* getting viking ID from API * distinction between VikingName and DisplayName (+ fix typo) * set DisplayName based on SUV * support for names with spaces in tempmute command * list of all clients in Server (for future usage in plugins) partially based on PR7 Co-authored-by: Hipposgrumm <hipposgrumm@gmail.com>
This commit is contained in:
parent
d18360ec33
commit
97ce6fdd06
@ -11,33 +11,35 @@ class ChatMessageHandler : CommandHandler {
|
|||||||
string message = receivedObject.Get<NetworkObject>("p").Get<string>("chm");
|
string message = receivedObject.Get<NetworkObject>("p").Get<string>("chm");
|
||||||
if (ManagementCommandProcessor.ProcessCommand(message, client))
|
if (ManagementCommandProcessor.ProcessCommand(message, client))
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
if (client.TempMuted) {
|
|
||||||
ClientMuted(client);
|
|
||||||
return Task.CompletedTask;
|
|
||||||
}
|
|
||||||
if (!Configuration.ServerConfiguration.EnableChat && !client.Room.AllowChatOverride) {
|
if (!Configuration.ServerConfiguration.EnableChat && !client.Room.AllowChatOverride) {
|
||||||
ChatDisabled(client);
|
ChatDisabled(client, message);
|
||||||
|
} else if (Configuration.ServerConfiguration.Authentication >= AuthenticationMode.RequiredForChat && client.PlayerData.VikingId != 0) {
|
||||||
|
ChatRequiredAuthentication(client, message);
|
||||||
|
} else if (client.Muted) {
|
||||||
|
ClientMuted(client, message);
|
||||||
} else {
|
} else {
|
||||||
Chat(client, message);
|
Chat(client, message);
|
||||||
}
|
}
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ChatDisabled(Client client) {
|
// NOTE: message is passed also for functions that refuse to send messages (this can be useful at the level of the chat moderation plugin)
|
||||||
|
|
||||||
|
public void ChatDisabled(Client client, string message) {
|
||||||
client.Send(Utils.BuildServerSideMessage("Unfortunately, chat has been disabled by server administrators", "Server"));
|
client.Send(Utils.BuildServerSideMessage("Unfortunately, chat has been disabled by server administrators", "Server"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ClientMuted(Client client) {
|
public void ChatRequiredAuthentication(Client client, string message) {
|
||||||
|
client.Send(Utils.BuildServerSideMessage("You must be authenticated to use the chat", "Server"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ClientMuted(Client client, string message) {
|
||||||
client.Send(Utils.BuildServerSideMessage("You have been muted by the moderators", "Server"));
|
client.Send(Utils.BuildServerSideMessage("You have been muted by the moderators", "Server"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Chat(Client client, string message) {
|
public void Chat(Client client, string message) {
|
||||||
if (Configuration.ServerConfiguration.Authentication >= AuthenticationMode.RequiredForChat && client.PlayerData.DiplayName == "placeholder") {
|
client.Room.Send(Utils.BuildChatMessage(client.PlayerData.Uid, message, client.PlayerData.DisplayName), client);
|
||||||
client.Send(Utils.BuildServerSideMessage("You must be authenticated to use the chat", "Server"));
|
// NOTE: using DisplayName not VikingName here for consistency with client behavior, preventing "placeholder" in not authenticated modes and support for changing name while logged on MMO
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
client.Room.Send(Utils.BuildChatMessage(client.PlayerData.Uid, message, client.PlayerData.DiplayName), client);
|
|
||||||
|
|
||||||
NetworkObject cmd = new();
|
NetworkObject cmd = new();
|
||||||
NetworkObject data = new();
|
NetworkObject data = new();
|
||||||
|
@ -84,7 +84,8 @@ class LoginHandler : CommandHandler
|
|||||||
|
|
||||||
AuthenticationInfo info = Utils.DeserializeXml<AuthenticationInfo>(responseString);
|
AuthenticationInfo info = Utils.DeserializeXml<AuthenticationInfo>(responseString);
|
||||||
if (info.Authenticated) {
|
if (info.Authenticated) {
|
||||||
client.PlayerData.DiplayName = info.DisplayName;
|
client.PlayerData.VikingName = info.VikingName;
|
||||||
|
client.PlayerData.VikingId = info.Id;
|
||||||
client.PlayerData.Role = info.Role;
|
client.PlayerData.Role = info.Role;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,8 @@ public class Client {
|
|||||||
public PlayerData PlayerData { get; set; } = new();
|
public PlayerData PlayerData { get; set; } = new();
|
||||||
public Room? Room { get; private set; }
|
public Room? Room { get; private set; }
|
||||||
public bool OldApi { get; set; } = false;
|
public bool OldApi { get; set; } = false;
|
||||||
public bool TempMuted { get; set; } = false;
|
|
||||||
|
public bool Muted { get; set; } = false;
|
||||||
|
|
||||||
private readonly Socket socket;
|
private readonly Socket socket;
|
||||||
SocketBuffer socketBuffer = new();
|
SocketBuffer socketBuffer = new();
|
||||||
|
@ -90,7 +90,7 @@ public class SpecialRoom : Room {
|
|||||||
Console.WriteLine("Started event " +alert + " in room " + Name);
|
Console.WriteLine("Started event " +alert + " in room " + Name);
|
||||||
} else {
|
} else {
|
||||||
specificClient.Send(packet);
|
specificClient.Send(packet);
|
||||||
Console.WriteLine("Added " + specificClient.PlayerData.DiplayName + " to event " + alert + " with " + duration + " seconds remaining");
|
Console.WriteLine("Added " + specificClient.PlayerData.DisplayName + " to event " + alert + " with " + duration + " seconds remaining");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using sodoffmmo.Core;
|
using sodoffmmo.Core;
|
||||||
using sodoffmmo.Management;
|
using sodoffmmo.Management;
|
||||||
|
using System.Text.Json;
|
||||||
|
|
||||||
namespace sodoffmmo.Data;
|
namespace sodoffmmo.Data;
|
||||||
public class PlayerData {
|
public class PlayerData {
|
||||||
@ -35,7 +36,13 @@ public class PlayerData {
|
|||||||
// animation bitfield (animations used by avatar, e.g. mounted, swim, ...)
|
// animation bitfield (animations used by avatar, e.g. mounted, swim, ...)
|
||||||
public int Mbf { get; set; }
|
public int Mbf { get; set; }
|
||||||
|
|
||||||
public string DiplayName { get; set; } = "placeholder";
|
// Name of player used by MMO
|
||||||
|
public string DisplayName { get; set; } = "placeholder";
|
||||||
|
// Name of player from API database
|
||||||
|
public string VikingName { get; set; } = "";
|
||||||
|
// ID of player from API database, zero for not authenticated players
|
||||||
|
public int VikingId { get; set; } = 0;
|
||||||
|
// role of player for management
|
||||||
public Role Role { get; set; } = Role.User;
|
public Role Role { get; set; } = Role.User;
|
||||||
|
|
||||||
public long last_ue_time { get; set; } = 0;
|
public long last_ue_time { get; set; } = 0;
|
||||||
@ -90,6 +97,18 @@ public class PlayerData {
|
|||||||
value = FixMountState(value);
|
value = FixMountState(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// update the playername (sent with avatardata) if it changes
|
||||||
|
// this is also sent when the player joins the room
|
||||||
|
if (varName == "A" && variables.GetValueOrDefault("A") != value) {
|
||||||
|
try {
|
||||||
|
string? name = JsonSerializer.Deserialize<AvatarData>(value)?.DisplayName;
|
||||||
|
if (name != null && name != DisplayName) {
|
||||||
|
DisplayName = name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (JsonException) {} // Don't break if the data is malformed or something.
|
||||||
|
}
|
||||||
|
|
||||||
// store in directory
|
// store in directory
|
||||||
variables[varName] = value;
|
variables[varName] = value;
|
||||||
return value;
|
return value;
|
||||||
|
@ -6,19 +6,27 @@ namespace sodoffmmo.Management.Commands;
|
|||||||
[ManagementCommand("tempmute", Role.Moderator)]
|
[ManagementCommand("tempmute", Role.Moderator)]
|
||||||
class TempMuteCommand : IManagementCommand {
|
class TempMuteCommand : IManagementCommand {
|
||||||
public void Handle(Client client, string[] arguments) {
|
public void Handle(Client client, string[] arguments) {
|
||||||
if (arguments.Length != 1) {
|
if (arguments.Length < 1) {
|
||||||
client.Send(Utils.BuildServerSideMessage("TempMute: Invalid number of arguments", "Server"));
|
client.Send(Utils.BuildServerSideMessage("TempMute: Invalid number of arguments", "Server"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Client? target = client.Room.Clients.FirstOrDefault(x => x.PlayerData.DiplayName == arguments[0]);
|
string name = string.Join(' ', arguments);
|
||||||
if (target == null) {
|
var targets = client.Room.Clients.Where(x => x.PlayerData.DisplayName == name);
|
||||||
client.Send(Utils.BuildServerSideMessage($"TempMute: user {arguments[0]} not found", "Server"));
|
// NOTE: using DisplayName here because this is the name displayed in client-side chat history
|
||||||
|
if (targets.Count() == 0) {
|
||||||
|
client.Send(Utils.BuildServerSideMessage($"TempMute: user {name} not found", "Server"));
|
||||||
|
return;
|
||||||
|
} else if (targets.Count() > 1) {
|
||||||
|
client.Send(Utils.BuildServerSideMessage($"TempMute: found multiple users with the name: {name}", "Server"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
target.TempMuted = !target.TempMuted;
|
|
||||||
if (target.TempMuted)
|
Client target = targets.First();
|
||||||
client.Send(Utils.BuildServerSideMessage($"TempMute: {arguments[0]} has been temporarily muted", "Server"));
|
if (target.Muted) {
|
||||||
else
|
client.Send(Utils.BuildServerSideMessage($"TempMute: {name} is already muted", "Server"));
|
||||||
client.Send(Utils.BuildServerSideMessage($"TempMute: {arguments[0]} has been unmuted", "Server"));
|
} else {
|
||||||
|
target.Muted = true;
|
||||||
|
client.Send(Utils.BuildServerSideMessage($"TempMute: {name} has been temporarily muted", "Server"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,7 @@ public class ManagementCommandProcessor {
|
|||||||
|
|
||||||
if (commands.TryGetValue(new Tuple<string, Role>(commandName, currentRole), out Type? commandType)) {
|
if (commands.TryGetValue(new Tuple<string, Role>(commandName, currentRole), out Type? commandType)) {
|
||||||
IManagementCommand command = (IManagementCommand)Activator.CreateInstance(commandType)!;
|
IManagementCommand command = (IManagementCommand)Activator.CreateInstance(commandType)!;
|
||||||
Console.WriteLine($"Management command {commandName} by {client.PlayerData.DiplayName} ({client.PlayerData.Uid}) in {client.Room.Name}");
|
Console.WriteLine($"Management command {commandName} by {client.PlayerData.VikingName} ({client.PlayerData.Uid}) in {client.Room.Name}");
|
||||||
command.Handle(client, arguments);
|
command.Handle(client, arguments);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,10 @@ public class AuthenticationInfo {
|
|||||||
public bool Authenticated { get; set; }
|
public bool Authenticated { get; set; }
|
||||||
|
|
||||||
[XmlElement]
|
[XmlElement]
|
||||||
public string DisplayName { get; set; }
|
public int Id { get; set; }
|
||||||
|
|
||||||
|
[XmlElement]
|
||||||
|
public string VikingName { get; set; }
|
||||||
|
|
||||||
[XmlElement]
|
[XmlElement]
|
||||||
public Role Role { get; set; }
|
public Role Role { get; set; }
|
||||||
@ -17,4 +20,4 @@ public class AuthenticationInfo {
|
|||||||
[Serializable]
|
[Serializable]
|
||||||
public enum Role {
|
public enum Role {
|
||||||
User = 0, Moderator = 1, Admin = 2
|
User = 0, Moderator = 1, Admin = 2
|
||||||
}
|
}
|
11
src/Schema/AvatarData.cs
Normal file
11
src/Schema/AvatarData.cs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace sodoffmmo.Management;
|
||||||
|
|
||||||
|
public class AvatarData {
|
||||||
|
public string? DisplayName { get; set; }
|
||||||
|
}
|
@ -7,18 +7,26 @@ using System.Net.Sockets;
|
|||||||
|
|
||||||
namespace sodoffmmo;
|
namespace sodoffmmo;
|
||||||
public class Server {
|
public class Server {
|
||||||
|
static object lck = new();
|
||||||
|
static readonly List<Client> clients = new();
|
||||||
|
|
||||||
readonly int port;
|
readonly int port;
|
||||||
readonly IPAddress ipAddress;
|
readonly IPAddress ipAddress;
|
||||||
readonly bool IPv6AndIPv4;
|
readonly bool IPv6AndIPv4;
|
||||||
ModuleManager moduleManager = new();
|
ModuleManager moduleManager = new();
|
||||||
|
|
||||||
|
public static int TotalClientCount => clients.Count;
|
||||||
|
|
||||||
public Server(IPAddress ipAdress, int port, bool IPv6AndIPv4) {
|
public Server(IPAddress ipAdress, int port, bool IPv6AndIPv4) {
|
||||||
this.ipAddress = ipAdress;
|
this.ipAddress = ipAdress;
|
||||||
this.port = port;
|
this.port = port;
|
||||||
this.IPv6AndIPv4 = IPv6AndIPv4;
|
this.IPv6AndIPv4 = IPv6AndIPv4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Client[] GetAllClients() {
|
||||||
|
return clients.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
public async Task Run() {
|
public async Task Run() {
|
||||||
moduleManager.RegisterModules();
|
moduleManager.RegisterModules();
|
||||||
ManagementCommandProcessor.Initialize();
|
ManagementCommandProcessor.Initialize();
|
||||||
@ -47,6 +55,7 @@ public class Server {
|
|||||||
|
|
||||||
private async Task HandleClient(Socket handler) {
|
private async Task HandleClient(Socket handler) {
|
||||||
Client client = new(handler);
|
Client client = new(handler);
|
||||||
|
lock (lck) clients.Add(client);
|
||||||
try {
|
try {
|
||||||
while (client.Connected) {
|
while (client.Connected) {
|
||||||
await client.Receive();
|
await client.Receive();
|
||||||
@ -60,6 +69,7 @@ public class Server {
|
|||||||
try {
|
try {
|
||||||
client.SetRoom(null);
|
client.SetRoom(null);
|
||||||
} catch (Exception) { }
|
} catch (Exception) { }
|
||||||
|
lock (lck) clients.Remove(client);
|
||||||
client.Disconnect();
|
client.Disconnect();
|
||||||
Console.WriteLine("Socket disconnected IID: " + client.ClientID);
|
Console.WriteLine("Socket disconnected IID: " + client.ClientID);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user