Merge branch 'permission-overhaul'. Closes #49
Conflicts: Barotrauma/BarotraumaShared/Source/DebugConsole.cs Barotrauma/BarotraumaShared/Source/Networking/ChatMessage.cs
This commit is contained in:
@@ -7,7 +7,7 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
enum ChatMessageType
|
||||
{
|
||||
Default, Error, Dead, Server, Radio, Private, MessageBox
|
||||
Default, Error, Dead, Server, Radio, Private, Console, MessageBox
|
||||
}
|
||||
|
||||
partial class ChatMessage
|
||||
@@ -25,7 +25,8 @@ namespace Barotrauma.Networking
|
||||
new Color(63, 72, 204), //dead
|
||||
new Color(157, 225, 160), //server
|
||||
new Color(238, 208, 0), //radio
|
||||
new Color(64, 240, 89) //private
|
||||
new Color(64, 240, 89), //private
|
||||
new Color(255, 255, 255) //console
|
||||
};
|
||||
|
||||
public readonly string Text;
|
||||
|
||||
@@ -1,29 +1,10 @@
|
||||
using Lidgren.Network;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
|
||||
namespace Barotrauma.Networking
|
||||
{
|
||||
[Flags]
|
||||
enum ClientPermissions
|
||||
{
|
||||
None = 0,
|
||||
[Description("End round")]
|
||||
EndRound = 1,
|
||||
[Description("Kick")]
|
||||
Kick = 2,
|
||||
[Description("Ban")]
|
||||
Ban = 4,
|
||||
[Description("Select submarine")]
|
||||
SelectSub = 8,
|
||||
[Description("Select game mode")]
|
||||
SelectMode = 16,
|
||||
[Description("Manage campaign")]
|
||||
ManageCampaign = 32
|
||||
}
|
||||
|
||||
class Client
|
||||
{
|
||||
public string Name;
|
||||
@@ -96,6 +77,11 @@ namespace Barotrauma.Networking
|
||||
public float DeleteDisconnectedTimer;
|
||||
|
||||
public ClientPermissions Permissions = ClientPermissions.None;
|
||||
public List<DebugConsole.Command> PermittedConsoleCommands
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public bool SpectateOnly;
|
||||
|
||||
@@ -130,6 +116,7 @@ namespace Barotrauma.Networking
|
||||
this.Name = name;
|
||||
this.ID = ID;
|
||||
|
||||
PermittedConsoleCommands = new List<DebugConsole.Command>();
|
||||
kickVoters = new List<Client>();
|
||||
|
||||
votes = new object[Enum.GetNames(typeof(VoteType)).Length];
|
||||
@@ -171,9 +158,10 @@ namespace Barotrauma.Networking
|
||||
return rName;
|
||||
}
|
||||
|
||||
public void SetPermissions(ClientPermissions permissions)
|
||||
public void SetPermissions(ClientPermissions permissions, List<DebugConsole.Command> permittedConsoleCommands)
|
||||
{
|
||||
this.Permissions = permissions;
|
||||
this.PermittedConsoleCommands = new List<DebugConsole.Command>(permittedConsoleCommands);
|
||||
}
|
||||
|
||||
public void GivePermission(ClientPermissions permission)
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.IO;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Barotrauma.Networking
|
||||
{
|
||||
[Flags]
|
||||
enum ClientPermissions
|
||||
{
|
||||
None = 0,
|
||||
[Description("End round")]
|
||||
EndRound = 1,
|
||||
[Description("Kick")]
|
||||
Kick = 2,
|
||||
[Description("Ban")]
|
||||
Ban = 4,
|
||||
[Description("Select submarine")]
|
||||
SelectSub = 8,
|
||||
[Description("Select game mode")]
|
||||
SelectMode = 16,
|
||||
[Description("Manage campaign")]
|
||||
ManageCampaign = 32,
|
||||
[Description("Console commands")]
|
||||
ConsoleCommands = 64
|
||||
}
|
||||
|
||||
class PermissionPreset
|
||||
{
|
||||
public static List<PermissionPreset> List = new List<PermissionPreset>();
|
||||
|
||||
public readonly string Name;
|
||||
public readonly string Description;
|
||||
public readonly ClientPermissions Permissions;
|
||||
public readonly List<DebugConsole.Command> PermittedCommands;
|
||||
|
||||
public PermissionPreset(XElement element)
|
||||
{
|
||||
Name = element.GetAttributeString("name", "");
|
||||
Description = element.GetAttributeString("description", "");
|
||||
|
||||
string permissionsStr = element.GetAttributeString("permissions", "");
|
||||
if (!Enum.TryParse(permissionsStr, out Permissions))
|
||||
{
|
||||
DebugConsole.ThrowError("Error in permission preset \"" + Name + "\" - " + permissionsStr + " is not a valid permission!");
|
||||
}
|
||||
|
||||
PermittedCommands = new List<DebugConsole.Command>();
|
||||
if (Permissions.HasFlag(ClientPermissions.ConsoleCommands))
|
||||
{
|
||||
foreach (XElement subElement in element.Elements())
|
||||
{
|
||||
if (subElement.Name.ToString().ToLowerInvariant() != "command") continue;
|
||||
string commandName = subElement.GetAttributeString("name", "");
|
||||
|
||||
DebugConsole.Command command = DebugConsole.FindCommand(commandName);
|
||||
if (command == null)
|
||||
{
|
||||
DebugConsole.ThrowError("Error in permission preset \"" + Name + "\" - " + commandName + "\" is not a valid console command.");
|
||||
continue;
|
||||
}
|
||||
|
||||
PermittedCommands.Add(command);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void LoadAll(string file)
|
||||
{
|
||||
if (!File.Exists(file)) return;
|
||||
|
||||
XDocument doc = XMLExtensions.TryLoadXml(file);
|
||||
if (doc == null || doc.Root == null) return;
|
||||
|
||||
foreach (XElement element in doc.Root.Elements())
|
||||
{
|
||||
List.Add(new PermissionPreset(element));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -125,8 +125,9 @@ namespace Barotrauma.Networking
|
||||
banList = new BanList();
|
||||
|
||||
LoadSettings();
|
||||
PermissionPreset.LoadAll(PermissionPresetFile);
|
||||
LoadClientPermissions();
|
||||
|
||||
|
||||
CoroutineManager.StartCoroutine(StartServer(isPublic));
|
||||
}
|
||||
|
||||
@@ -795,6 +796,11 @@ namespace Barotrauma.Networking
|
||||
campaign.ServerRead(inc, sender);
|
||||
}
|
||||
break;
|
||||
case ClientPermissions.ConsoleCommands:
|
||||
string consoleCommand = inc.ReadString();
|
||||
Vector2 clientCursorPos = new Vector2(inc.ReadSingle(), inc.ReadSingle());
|
||||
DebugConsole.ExecuteClientCommand(sender, clientCursorPos, consoleCommand);
|
||||
break;
|
||||
}
|
||||
|
||||
inc.ReadPadBits();
|
||||
@@ -853,7 +859,7 @@ namespace Barotrauma.Networking
|
||||
outmsg.Write(GameStarted);
|
||||
outmsg.Write(AllowSpectating);
|
||||
|
||||
outmsg.Write((byte)c.Permissions);
|
||||
WritePermissions(outmsg, c);
|
||||
}
|
||||
|
||||
private void ClientWriteIngame(Client c)
|
||||
@@ -1636,6 +1642,18 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
}
|
||||
|
||||
public void SendChatMessage(string txt, Client recipient)
|
||||
{
|
||||
ChatMessage msg = ChatMessage.Create("", txt, ChatMessageType.Server, null);
|
||||
SendChatMessage(msg, recipient);
|
||||
}
|
||||
|
||||
public void SendConsoleMessage(string txt, Client recipient)
|
||||
{
|
||||
ChatMessage msg = ChatMessage.Create("", txt, ChatMessageType.Console, null);
|
||||
SendChatMessage(msg, recipient);
|
||||
}
|
||||
|
||||
public void SendChatMessage(ChatMessage msg, Client recipient)
|
||||
{
|
||||
msg.NetStateID = recipient.ChatMsgQueue.Count > 0 ?
|
||||
@@ -1936,16 +1954,34 @@ namespace Barotrauma.Networking
|
||||
clientPermissions.Add(new SavedClientPermission(
|
||||
client.Name,
|
||||
client.Connection.RemoteEndPoint.Address.ToString(),
|
||||
client.Permissions));
|
||||
client.Permissions,
|
||||
client.PermittedConsoleCommands));
|
||||
}
|
||||
|
||||
var msg = server.CreateMessage();
|
||||
msg.Write((byte)ServerPacketHeader.PERMISSIONS);
|
||||
msg.Write((byte)client.Permissions);
|
||||
WritePermissions(msg, client);
|
||||
|
||||
server.SendMessage(msg, client.Connection, NetDeliveryMethod.ReliableUnordered);
|
||||
|
||||
SaveClientPermissions();
|
||||
}
|
||||
|
||||
private void WritePermissions(NetBuffer msg, Client client)
|
||||
{
|
||||
msg.Write((byte)client.Permissions);
|
||||
if (client.Permissions.HasFlag(ClientPermissions.ConsoleCommands))
|
||||
{
|
||||
msg.Write((UInt16)client.PermittedConsoleCommands.Sum(c => c.names.Length));
|
||||
foreach (DebugConsole.Command command in client.PermittedConsoleCommands)
|
||||
{
|
||||
foreach (string commandName in command.names)
|
||||
{
|
||||
msg.Write(commandName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void SetClientCharacter(Client client, Character newCharacter)
|
||||
{
|
||||
|
||||
@@ -218,11 +218,11 @@ namespace Barotrauma.Networking
|
||||
var savedPermissions = clientPermissions.Find(cp => cp.IP == newClient.Connection.RemoteEndPoint.Address.ToString());
|
||||
if (savedPermissions != null)
|
||||
{
|
||||
newClient.SetPermissions(savedPermissions.Permissions);
|
||||
newClient.SetPermissions(savedPermissions.Permissions, savedPermissions.PermittedCommands);
|
||||
}
|
||||
else
|
||||
{
|
||||
newClient.SetPermissions(ClientPermissions.None);
|
||||
newClient.SetPermissions(ClientPermissions.None, new List<DebugConsole.Command>());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,20 +25,23 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
public readonly string IP;
|
||||
public readonly string Name;
|
||||
public List<DebugConsole.Command> PermittedCommands;
|
||||
|
||||
public ClientPermissions Permissions;
|
||||
|
||||
public SavedClientPermission(string name, string ip, ClientPermissions permissions)
|
||||
public SavedClientPermission(string name, string ip, ClientPermissions permissions, List<DebugConsole.Command> permittedCommands)
|
||||
{
|
||||
this.Name = name;
|
||||
this.IP = ip;
|
||||
|
||||
this.Permissions = permissions;
|
||||
this.PermittedCommands = permittedCommands;
|
||||
}
|
||||
}
|
||||
|
||||
public const string SettingsFile = "serversettings.xml";
|
||||
public static readonly string ClientPermissionsFile = "Data" + Path.DirectorySeparatorChar + "clientpermissions.txt";
|
||||
public static readonly string PermissionPresetFile = "Data" + Path.DirectorySeparatorChar + "permissionpresets.xml";
|
||||
public static readonly string ClientPermissionsFile = "Data" + Path.DirectorySeparatorChar + "clientpermissions.xml";
|
||||
|
||||
public Dictionary<string, SerializableProperty> SerializableProperties
|
||||
{
|
||||
@@ -323,12 +326,67 @@ namespace Barotrauma.Networking
|
||||
|
||||
public void LoadClientPermissions()
|
||||
{
|
||||
if (!File.Exists(ClientPermissionsFile)) return;
|
||||
|
||||
clientPermissions.Clear();
|
||||
|
||||
if (File.Exists("Data/clientpermissions.txt") && !File.Exists(ClientPermissionsFile))
|
||||
{
|
||||
LoadClientPermissionsOld("Data/clientpermissions.txt");
|
||||
return;
|
||||
}
|
||||
|
||||
XDocument doc = XMLExtensions.TryLoadXml(ClientPermissionsFile);
|
||||
foreach (XElement clientElement in doc.Root.Elements())
|
||||
{
|
||||
string clientName = clientElement.GetAttributeString("name", "");
|
||||
string clientIP = clientElement.GetAttributeString("ip", "");
|
||||
if (string.IsNullOrWhiteSpace(clientName) || string.IsNullOrWhiteSpace(clientIP))
|
||||
{
|
||||
DebugConsole.ThrowError("Error in " + ClientPermissionsFile + " - all clients must have a name and an IP address.");
|
||||
continue;
|
||||
}
|
||||
|
||||
string permissionsStr = clientElement.GetAttributeString("permissions", "");
|
||||
ClientPermissions permissions;
|
||||
if (!Enum.TryParse(permissionsStr, out permissions))
|
||||
{
|
||||
DebugConsole.ThrowError("Error in " + ClientPermissionsFile + " - \"" + permissionsStr + "\" is not a valid client permission.");
|
||||
continue;
|
||||
}
|
||||
|
||||
List<DebugConsole.Command> permittedCommands = new List<DebugConsole.Command>();
|
||||
if (permissions.HasFlag(ClientPermissions.ConsoleCommands))
|
||||
{
|
||||
foreach (XElement commandElement in clientElement.Elements())
|
||||
{
|
||||
if (commandElement.Name.ToString().ToLowerInvariant() != "command") continue;
|
||||
|
||||
string commandName = commandElement.GetAttributeString("name", "");
|
||||
DebugConsole.Command command = DebugConsole.FindCommand(commandName);
|
||||
if (command == null)
|
||||
{
|
||||
DebugConsole.ThrowError("Error in " + ClientPermissionsFile + " - \"" + commandName + "\" is not a valid console command.");
|
||||
continue;
|
||||
}
|
||||
|
||||
permittedCommands.Add(command);
|
||||
}
|
||||
}
|
||||
|
||||
clientPermissions.Add(new SavedClientPermission(clientName, clientIP, permissions, permittedCommands));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Method for loading old .txt client permission files to provide backwards compatibility
|
||||
/// </summary>
|
||||
private void LoadClientPermissionsOld(string file)
|
||||
{
|
||||
if (!File.Exists(file)) return;
|
||||
|
||||
string[] lines;
|
||||
try
|
||||
{
|
||||
lines = File.ReadAllLines(ClientPermissionsFile);
|
||||
lines = File.ReadAllLines(file);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -337,36 +395,63 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
|
||||
clientPermissions.Clear();
|
||||
|
||||
foreach (string line in lines)
|
||||
{
|
||||
string[] separatedLine = line.Split('|');
|
||||
if (separatedLine.Length < 3) continue;
|
||||
|
||||
string name = String.Join("|", separatedLine.Take(separatedLine.Length - 2));
|
||||
string name = string.Join("|", separatedLine.Take(separatedLine.Length - 2));
|
||||
string ip = separatedLine[separatedLine.Length - 2];
|
||||
|
||||
ClientPermissions permissions = ClientPermissions.None;
|
||||
if (Enum.TryParse<ClientPermissions>(separatedLine.Last(), out permissions))
|
||||
if (Enum.TryParse(separatedLine.Last(), out permissions))
|
||||
{
|
||||
clientPermissions.Add(new SavedClientPermission(name, ip, permissions));
|
||||
clientPermissions.Add(new SavedClientPermission(name, ip, permissions, new List<DebugConsole.Command>()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void SaveClientPermissions()
|
||||
{
|
||||
GameServer.Log("Saving client permissions", ServerLog.MessageType.ServerMessage);
|
||||
//delete old client permission file
|
||||
if (File.Exists("Data/clientpermissions.txt"))
|
||||
{
|
||||
File.Delete("Data/clientpermissions.txt");
|
||||
}
|
||||
|
||||
List<string> lines = new List<string>();
|
||||
Log("Saving client permissions", ServerLog.MessageType.ServerMessage);
|
||||
|
||||
XDocument doc = new XDocument(new XElement("ClientPermissions"));
|
||||
|
||||
foreach (SavedClientPermission clientPermission in clientPermissions)
|
||||
{
|
||||
lines.Add(clientPermission.Name + "|" + clientPermission.IP+"|"+clientPermission.Permissions.ToString());
|
||||
XElement clientElement = new XElement("Client",
|
||||
new XAttribute("name", clientPermission.Name),
|
||||
new XAttribute("ip", clientPermission.IP),
|
||||
new XAttribute("permissions", clientPermission.Permissions.ToString()));
|
||||
|
||||
if (clientPermission.Permissions.HasFlag(ClientPermissions.ConsoleCommands))
|
||||
{
|
||||
foreach (DebugConsole.Command command in clientPermission.PermittedCommands)
|
||||
{
|
||||
clientElement.Add(new XElement("command", new XAttribute("name", command.names[0])));
|
||||
}
|
||||
}
|
||||
|
||||
doc.Root.Add(clientElement);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
File.WriteAllLines(ClientPermissionsFile, lines);
|
||||
XmlWriterSettings settings = new XmlWriterSettings();
|
||||
settings.Indent = true;
|
||||
settings.NewLineOnAttributes = true;
|
||||
|
||||
using (var writer = XmlWriter.Create(ClientPermissionsFile, settings))
|
||||
{
|
||||
doc.Save(writer);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
||||
@@ -28,18 +28,20 @@ namespace Barotrauma.Networking
|
||||
Attack,
|
||||
Spawning,
|
||||
ServerMessage,
|
||||
ConsoleUsage,
|
||||
Error
|
||||
}
|
||||
|
||||
private readonly Color[] messageColor =
|
||||
{
|
||||
Color.LightBlue,
|
||||
new Color(255, 142, 0),
|
||||
new Color(238, 208, 0),
|
||||
new Color(204, 74, 78),
|
||||
new Color(163, 73, 164),
|
||||
new Color(157, 225, 160),
|
||||
Color.Red
|
||||
Color.LightBlue, //Chat
|
||||
new Color(255, 142, 0), //ItemInteraction
|
||||
new Color(238, 208, 0), //Inventory
|
||||
new Color(204, 74, 78), //Attack
|
||||
new Color(163, 73, 164), //Spawning
|
||||
new Color(157, 225, 160), //ServerMessage
|
||||
new Color(0, 162, 232), //ConsoleUsage
|
||||
Color.Red //Error
|
||||
};
|
||||
|
||||
private readonly string[] messageTypeName =
|
||||
@@ -50,6 +52,7 @@ namespace Barotrauma.Networking
|
||||
"Attack & death",
|
||||
"Spawning",
|
||||
"Server message",
|
||||
"Console usage",
|
||||
"Error"
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user