WIP client special permissions (kick, ban, end round)
This commit is contained in:
@@ -136,19 +136,38 @@ namespace Barotrauma
|
|||||||
frame.Draw(spriteBatch);
|
frame.Draw(spriteBatch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static bool IsCommandPermitted(string command, GameClient client)
|
||||||
|
{
|
||||||
|
switch (command)
|
||||||
|
{
|
||||||
|
case "kick":
|
||||||
|
return client.HasPermission(ClientPermissions.Kick);
|
||||||
|
case "ban":
|
||||||
|
case "banip":
|
||||||
|
return client.HasPermission(ClientPermissions.Ban);
|
||||||
|
case "netstats":
|
||||||
|
case "help":
|
||||||
|
case "dumpids":
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void ExecuteCommand(string command, GameMain game)
|
public static void ExecuteCommand(string command, GameMain game)
|
||||||
{
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(command)) return;
|
||||||
|
string[] commands = command.Split(' ');
|
||||||
|
|
||||||
|
|
||||||
#if !DEBUG
|
#if !DEBUG
|
||||||
if (GameMain.Client != null)
|
if (GameMain.Client != null && !IsCommandPermitted(commands[0].ToLowerInvariant(), GameMain.Client))
|
||||||
{
|
{
|
||||||
ThrowError("Console commands are disabled in multiplayer mode");
|
ThrowError("You're not permitted to use the command ''" + commands[0].ToLowerInvariant()+"''!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (command == "") return;
|
|
||||||
string[] commands = command.Split(' ');
|
|
||||||
|
|
||||||
switch (commands[0].ToLowerInvariant())
|
switch (commands[0].ToLowerInvariant())
|
||||||
{
|
{
|
||||||
case "help":
|
case "help":
|
||||||
@@ -189,7 +208,6 @@ namespace Barotrauma
|
|||||||
|
|
||||||
NewMessage(" ", Color.Cyan);
|
NewMessage(" ", Color.Cyan);
|
||||||
|
|
||||||
|
|
||||||
NewMessage("kick [name]: kick a player out from the server", Color.Cyan);
|
NewMessage("kick [name]: kick a player out from the server", Color.Cyan);
|
||||||
NewMessage("ban [name]: kick and ban the player from the server", Color.Cyan);
|
NewMessage("ban [name]: kick and ban the player from the server", Color.Cyan);
|
||||||
NewMessage("banip [IP address]: ban the IP address from the server", Color.Cyan);
|
NewMessage("banip [IP address]: ban the IP address from the server", Color.Cyan);
|
||||||
@@ -284,13 +302,14 @@ namespace Barotrauma
|
|||||||
HumanAIController.DisableCrewAI = false;
|
HumanAIController.DisableCrewAI = false;
|
||||||
break;
|
break;
|
||||||
case "kick":
|
case "kick":
|
||||||
if (GameMain.Server == null || commands.Length < 2) break;
|
if (GameMain.NetworkMember == null || commands.Length < 2) break;
|
||||||
GameMain.Server.KickPlayer(string.Join(" ", commands.Skip(1)));
|
GameMain.NetworkMember.KickPlayer(string.Join(" ", commands.Skip(1)), false);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case "ban":
|
case "ban":
|
||||||
if (GameMain.Server == null || commands.Length < 2) break;
|
if (GameMain.NetworkMember == null || commands.Length < 2) break;
|
||||||
GameMain.Server.KickPlayer(string.Join(" ", commands.Skip(1)), true);
|
GameMain.NetworkMember.KickPlayer(string.Join(" ", commands.Skip(1)), true);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case "banip":
|
case "banip":
|
||||||
if (GameMain.Server == null || commands.Length < 2) break;
|
if (GameMain.Server == null || commands.Length < 2) break;
|
||||||
@@ -601,6 +620,7 @@ namespace Barotrauma
|
|||||||
DebugConsole.NewMessage("Deleted filelist", Color.Green);
|
DebugConsole.NewMessage("Deleted filelist", Color.Green);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (System.IO.File.Exists("Submarines/TutorialSub.sub"))
|
if (System.IO.File.Exists("Submarines/TutorialSub.sub"))
|
||||||
{
|
{
|
||||||
System.IO.File.Delete("Submarines/TutorialSub.sub");
|
System.IO.File.Delete("Submarines/TutorialSub.sub");
|
||||||
@@ -614,6 +634,13 @@ namespace Barotrauma
|
|||||||
DebugConsole.NewMessage("Deleted server settings", Color.Green);
|
DebugConsole.NewMessage("Deleted server settings", Color.Green);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (System.IO.File.Exists(GameServer.ClientPermissionsFile))
|
||||||
|
{
|
||||||
|
System.IO.File.Delete(GameServer.ClientPermissionsFile);
|
||||||
|
DebugConsole.NewMessage("Deleted client permission file", Color.Green);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if (System.IO.File.Exists("crashreport.txt"))
|
if (System.IO.File.Exists("crashreport.txt"))
|
||||||
{
|
{
|
||||||
System.IO.File.Delete("crashreport.txt");
|
System.IO.File.Delete("crashreport.txt");
|
||||||
|
|||||||
@@ -41,6 +41,11 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
|
|
||||||
public GUITickBox(Rectangle rect, string label, Alignment alignment, GUIComponent parent)
|
public GUITickBox(Rectangle rect, string label, Alignment alignment, GUIComponent parent)
|
||||||
|
: this(rect, label, alignment, GUI.Font, parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public GUITickBox(Rectangle rect, string label, Alignment alignment, SpriteFont font, GUIComponent parent)
|
||||||
: base(null)
|
: base(null)
|
||||||
{
|
{
|
||||||
if (parent != null)
|
if (parent != null)
|
||||||
@@ -50,7 +55,7 @@ namespace Barotrauma
|
|||||||
box.HoverColor = Color.Gray;
|
box.HoverColor = Color.Gray;
|
||||||
box.SelectedColor = Color.DarkGray;
|
box.SelectedColor = Color.DarkGray;
|
||||||
|
|
||||||
text = new GUITextBlock(new Rectangle(rect.X + 30, rect.Y+2, 20, rect.Height), label, Color.Transparent, Color.White, Alignment.TopLeft, null, this);
|
text = new GUITextBlock(new Rectangle(rect.Right + 10, rect.Y+2, 20, rect.Height), label, GUI.Style, this, font);
|
||||||
|
|
||||||
this.rect = new Rectangle(box.Rect.X, box.Rect.Y, 240, rect.Height);
|
this.rect = new Rectangle(box.Rect.X, box.Rect.Y, 240, rect.Height);
|
||||||
|
|
||||||
|
|||||||
@@ -166,7 +166,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (GameMain.Server != null)
|
if (GameMain.Server != null)
|
||||||
{
|
{
|
||||||
CoroutineManager.StartCoroutine(GameMain.Server.EndGame(endMessage));
|
//CoroutineManager.StartCoroutine(GameMain.Server.EndGame(endMessage));
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (GameMain.Client == null)
|
else if (GameMain.Client == null)
|
||||||
|
|||||||
@@ -79,9 +79,6 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
public GUIComponent CreateBanFrame(GUIComponent parent)
|
public GUIComponent CreateBanFrame(GUIComponent parent)
|
||||||
{
|
{
|
||||||
//GUIFrame banFrame = new GUIFrame(new Rectangle(0,0,0,0), null, Alignment.Center, GUI.Style, parent);
|
|
||||||
|
|
||||||
//new GUITextBlock(new Rectangle(0, -10, 0, 30), "Banned IPs:", GUI.Style, Alignment.Left, Alignment.Left, banFrame, false, GUI.LargeFont);
|
|
||||||
banFrame = new GUIListBox(new Rectangle(0, 0, 0, 0), GUI.Style, parent);
|
banFrame = new GUIListBox(new Rectangle(0, 0, 0, 0), GUI.Style, parent);
|
||||||
|
|
||||||
foreach (BannedPlayer bannedPlayer in bannedPlayers)
|
foreach (BannedPlayer bannedPlayer in bannedPlayers)
|
||||||
@@ -91,18 +88,14 @@ namespace Barotrauma.Networking
|
|||||||
bannedPlayer.IP + " (" + bannedPlayer.Name + ")",
|
bannedPlayer.IP + " (" + bannedPlayer.Name + ")",
|
||||||
GUI.Style,
|
GUI.Style,
|
||||||
Alignment.Left, Alignment.Left, banFrame);
|
Alignment.Left, Alignment.Left, banFrame);
|
||||||
textBlock.Padding = new Vector4(10.0f, 0.0f, 0.0f, 0.0f);
|
textBlock.Padding = new Vector4(10.0f, 10.0f, 0.0f, 0.0f);
|
||||||
textBlock.UserData = banFrame;
|
textBlock.UserData = banFrame;
|
||||||
|
|
||||||
var removeButton = new GUIButton(new Rectangle(0, 00, 100, 20), "Remove", Alignment.Right | Alignment.CenterY, GUI.Style, textBlock);
|
var removeButton = new GUIButton(new Rectangle(0, 0, 100, 20), "Remove", Alignment.Right | Alignment.CenterY, GUI.Style, textBlock);
|
||||||
removeButton.UserData = bannedPlayer;
|
removeButton.UserData = bannedPlayer;
|
||||||
removeButton.OnClicked = RemoveBan;
|
removeButton.OnClicked = RemoveBan;
|
||||||
}
|
}
|
||||||
|
|
||||||
//var closeButton = new GUIButton(new Rectangle(0,30,100,20), "Close", Alignment.BottomRight, GUI.Style, banFrame);
|
|
||||||
//closeButton.OnClicked = CloseFrame;
|
|
||||||
|
|
||||||
|
|
||||||
return banFrame;
|
return banFrame;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,169 @@
|
|||||||
|
using Barotrauma.Networking.ReliableMessages;
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
class Client
|
||||||
|
{
|
||||||
|
public string name;
|
||||||
|
public byte ID;
|
||||||
|
|
||||||
|
public Character Character;
|
||||||
|
public CharacterInfo characterInfo;
|
||||||
|
public NetConnection Connection { get; set; }
|
||||||
|
public string version;
|
||||||
|
public bool inGame;
|
||||||
|
|
||||||
|
private List<Client> kickVoters;
|
||||||
|
|
||||||
|
public bool ReadyToStart;
|
||||||
|
|
||||||
|
private object[] votes;
|
||||||
|
|
||||||
|
public List<JobPrefab> jobPreferences;
|
||||||
|
public JobPrefab assignedJob;
|
||||||
|
|
||||||
|
public FileStreamSender FileStreamSender;
|
||||||
|
|
||||||
|
public ReliableChannel ReliableChannel;
|
||||||
|
|
||||||
|
public float deleteDisconnectedTimer;
|
||||||
|
|
||||||
|
public ClientPermissions Permissions;
|
||||||
|
|
||||||
|
public int KickVoteCount
|
||||||
|
{
|
||||||
|
get { return kickVoters.Count; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public Client(NetPeer server, string name, byte ID)
|
||||||
|
: this(name, ID)
|
||||||
|
{
|
||||||
|
ReliableChannel = new ReliableChannel(server);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Client(string name, byte ID)
|
||||||
|
{
|
||||||
|
this.name = name;
|
||||||
|
this.ID = ID;
|
||||||
|
|
||||||
|
kickVoters = new List<Client>();
|
||||||
|
|
||||||
|
votes = new object[Enum.GetNames(typeof(VoteType)).Length];
|
||||||
|
|
||||||
|
jobPreferences = new List<JobPrefab>(JobPrefab.List.GetRange(0, 3));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool IsValidName(string name)
|
||||||
|
{
|
||||||
|
if (name.Contains("\n") || name.Contains("\r\n")) return false;
|
||||||
|
|
||||||
|
return (name.All(c =>
|
||||||
|
c != ';' &&
|
||||||
|
c != ',' &&
|
||||||
|
c != '<' &&
|
||||||
|
c != '/'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string SanitizeName(string name)
|
||||||
|
{
|
||||||
|
if (name.Length > 20)
|
||||||
|
{
|
||||||
|
name = name.Substring(0, 20);
|
||||||
|
}
|
||||||
|
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetPermissions(ClientPermissions permissions)
|
||||||
|
{
|
||||||
|
this.Permissions = permissions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void GivePermission(ClientPermissions permission)
|
||||||
|
{
|
||||||
|
this.Permissions |= permission;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemovePermission(ClientPermissions permission)
|
||||||
|
{
|
||||||
|
this.Permissions &= ~permission;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool HasPermission(ClientPermissions permission)
|
||||||
|
{
|
||||||
|
return Permissions.HasFlag(permission);
|
||||||
|
}
|
||||||
|
|
||||||
|
public T GetVote<T>(VoteType voteType)
|
||||||
|
{
|
||||||
|
return (votes[(int)voteType] is T) ? (T)votes[(int)voteType] : default(T);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetVote(VoteType voteType, object value)
|
||||||
|
{
|
||||||
|
votes[(int)voteType] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ResetVotes()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < votes.Length; i++)
|
||||||
|
{
|
||||||
|
votes[i] = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddKickVote(Client voter)
|
||||||
|
{
|
||||||
|
if (!kickVoters.Contains(voter)) kickVoters.Add(voter);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void RemoveKickVote(Client voter)
|
||||||
|
{
|
||||||
|
kickVoters.Remove(voter);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool HasKickVoteFromID(int id)
|
||||||
|
{
|
||||||
|
return kickVoters.Any(k => k.ID == id);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void UpdateKickVotes(List<Client> connectedClients)
|
||||||
|
{
|
||||||
|
foreach (Client client in connectedClients)
|
||||||
|
{
|
||||||
|
client.kickVoters.RemoveAll(voter => !connectedClients.Contains(voter));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CancelTransfer()
|
||||||
|
{
|
||||||
|
if (FileStreamSender == null) return;
|
||||||
|
|
||||||
|
FileStreamSender.CancelTransfer();
|
||||||
|
FileStreamSender.Dispose();
|
||||||
|
|
||||||
|
FileStreamSender = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,6 +7,7 @@ using FarseerPhysics;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Barotrauma.Items.Components;
|
using Barotrauma.Items.Components;
|
||||||
|
using System.ComponentModel;
|
||||||
|
|
||||||
namespace Barotrauma.Networking
|
namespace Barotrauma.Networking
|
||||||
{
|
{
|
||||||
@@ -21,7 +22,10 @@ namespace Barotrauma.Networking
|
|||||||
private FileStreamReceiver fileStreamReceiver;
|
private FileStreamReceiver fileStreamReceiver;
|
||||||
private Queue<Pair<string, FileTransferMessageType>> requestFileQueue;
|
private Queue<Pair<string, FileTransferMessageType>> requestFileQueue;
|
||||||
|
|
||||||
private GUITickBox endRoundButton;
|
private GUIButton endRoundButton;
|
||||||
|
private GUITickBox endVoteTickBox;
|
||||||
|
|
||||||
|
private ClientPermissions permissions;
|
||||||
|
|
||||||
private bool connected;
|
private bool connected;
|
||||||
|
|
||||||
@@ -51,8 +55,22 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
public GameClient(string newName)
|
public GameClient(string newName)
|
||||||
{
|
{
|
||||||
endRoundButton = new GUITickBox(new Rectangle(GameMain.GraphicsWidth - 170, 20, 20, 20), "End round", Alignment.TopLeft, inGameHUD);
|
endVoteTickBox = new GUITickBox(new Rectangle(GameMain.GraphicsWidth - 170, 20, 20, 20), "End round", Alignment.TopLeft, inGameHUD);
|
||||||
endRoundButton.OnSelected = ToggleEndRoundVote;
|
endVoteTickBox.OnSelected = ToggleEndRoundVote;
|
||||||
|
endVoteTickBox.Visible = false;
|
||||||
|
|
||||||
|
endRoundButton = new GUIButton(new Rectangle(GameMain.GraphicsWidth - 170 - 170, 20, 150, 20), "End round", Alignment.TopLeft, GUI.Style, inGameHUD);
|
||||||
|
endRoundButton.OnClicked = (btn, userdata) =>
|
||||||
|
{
|
||||||
|
if (!permissions.HasFlag(ClientPermissions.EndRound)) return false;
|
||||||
|
|
||||||
|
var msg = client.CreateMessage();
|
||||||
|
|
||||||
|
msg.Write((byte)PacketTypes.EndGame);
|
||||||
|
client.SendMessage(msg, NetDeliveryMethod.ReliableUnordered);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
};
|
||||||
endRoundButton.Visible = false;
|
endRoundButton.Visible = false;
|
||||||
|
|
||||||
newName = newName.Replace(":", "");
|
newName = newName.Replace(":", "");
|
||||||
@@ -227,10 +245,13 @@ namespace Barotrauma.Networking
|
|||||||
if (packetType == (byte)PacketTypes.LoggedIn)
|
if (packetType == (byte)PacketTypes.LoggedIn)
|
||||||
{
|
{
|
||||||
myID = inc.ReadByte();
|
myID = inc.ReadByte();
|
||||||
|
permissions = (ClientPermissions)inc.ReadInt32();
|
||||||
gameStarted = inc.ReadBoolean();
|
gameStarted = inc.ReadBoolean();
|
||||||
bool hasCharacter = inc.ReadBoolean();
|
bool hasCharacter = inc.ReadBoolean();
|
||||||
bool allowSpectating = inc.ReadBoolean();
|
bool allowSpectating = inc.ReadBoolean();
|
||||||
|
|
||||||
|
endRoundButton.Visible = permissions.HasFlag(ClientPermissions.EndRound);
|
||||||
|
|
||||||
if (gameStarted && Screen.Selected != GameMain.GameScreen)
|
if (gameStarted && Screen.Selected != GameMain.GameScreen)
|
||||||
{
|
{
|
||||||
new GUIMessageBox("Please wait",
|
new GUIMessageBox("Please wait",
|
||||||
@@ -549,6 +570,46 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
AddChatMessage(otherClient.name + " has joined the server", ChatMessageType.Server);
|
AddChatMessage(otherClient.name + " has joined the server", ChatMessageType.Server);
|
||||||
|
|
||||||
|
break;
|
||||||
|
case (byte)PacketTypes.Permissions:
|
||||||
|
ClientPermissions newPermissions = (ClientPermissions)inc.ReadInt32();
|
||||||
|
|
||||||
|
if (newPermissions != permissions)
|
||||||
|
{
|
||||||
|
if (GUIMessageBox.MessageBoxes.Count > 0)
|
||||||
|
{
|
||||||
|
var existingMsgBox = GUIMessageBox.MessageBoxes.Peek();
|
||||||
|
if (existingMsgBox.UserData as string == "permissions")
|
||||||
|
{
|
||||||
|
GUIMessageBox.MessageBoxes.Dequeue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//new GUIMessageBox("The host has changed you permissions. New permissions")
|
||||||
|
string msg = "";
|
||||||
|
if (newPermissions == ClientPermissions.None)
|
||||||
|
{
|
||||||
|
msg = "The host has removed all your special permissions.";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
msg = "Your current permissions:\n";
|
||||||
|
foreach (ClientPermissions permission in Enum.GetValues(typeof(ClientPermissions)))
|
||||||
|
{
|
||||||
|
if (!newPermissions.HasFlag(permissions) || permission == ClientPermissions.None) continue;
|
||||||
|
|
||||||
|
System.Reflection.FieldInfo fi = typeof(ClientPermissions).GetField(permission.ToString());
|
||||||
|
DescriptionAttribute[] attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
|
||||||
|
|
||||||
|
msg += " - " + attributes[0].Description+"\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
new GUIMessageBox("Permissions changed", msg).UserData = "permissions";
|
||||||
|
}
|
||||||
|
|
||||||
|
endRoundButton.Visible = permissions.HasFlag(ClientPermissions.EndRound);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case (byte)PacketTypes.RequestFile:
|
case (byte)PacketTypes.RequestFile:
|
||||||
bool accepted = inc.ReadBoolean();
|
bool accepted = inc.ReadBoolean();
|
||||||
@@ -573,11 +634,9 @@ namespace Barotrauma.Networking
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
||||||
fileStreamReceiver.ReadMessage(inc);
|
fileStreamReceiver.ReadMessage(inc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case (byte)PacketTypes.PlayerLeft:
|
case (byte)PacketTypes.PlayerLeft:
|
||||||
byte leavingID = inc.ReadByte();
|
byte leavingID = inc.ReadByte();
|
||||||
@@ -653,7 +712,7 @@ namespace Barotrauma.Networking
|
|||||||
{
|
{
|
||||||
if (Character != null) Character.Remove();
|
if (Character != null) Character.Remove();
|
||||||
|
|
||||||
endRoundButton.Selected = false;
|
endVoteTickBox.Selected = false;
|
||||||
|
|
||||||
int seed = inc.ReadInt32();
|
int seed = inc.ReadInt32();
|
||||||
string levelSeed = inc.ReadString();
|
string levelSeed = inc.ReadString();
|
||||||
@@ -746,7 +805,7 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
gameStarted = true;
|
gameStarted = true;
|
||||||
|
|
||||||
endRoundButton.Visible = Voting.AllowEndVoting && myCharacter != null;
|
endVoteTickBox.Visible = Voting.AllowEndVoting && myCharacter != null;
|
||||||
|
|
||||||
GameMain.GameScreen.Select();
|
GameMain.GameScreen.Select();
|
||||||
|
|
||||||
@@ -804,6 +863,11 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool HasPermission(ClientPermissions permission)
|
||||||
|
{
|
||||||
|
return permissions.HasFlag(permission);
|
||||||
|
}
|
||||||
|
|
||||||
public override void Draw(Microsoft.Xna.Framework.Graphics.SpriteBatch spriteBatch)
|
public override void Draw(Microsoft.Xna.Framework.Graphics.SpriteBatch spriteBatch)
|
||||||
{
|
{
|
||||||
base.Draw(spriteBatch);
|
base.Draw(spriteBatch);
|
||||||
@@ -839,6 +903,10 @@ namespace Barotrauma.Networking
|
|||||||
GUI.DrawRectangle(spriteBatch, new Rectangle(x, y, width, height), Color.Black * 0.7f, true);
|
GUI.DrawRectangle(spriteBatch, new Rectangle(x, y, width, height), Color.Black * 0.7f, true);
|
||||||
spriteBatch.DrawString(GUI.Font, "Network statistics:", new Vector2(x + 10, y + 10), Color.White);
|
spriteBatch.DrawString(GUI.Font, "Network statistics:", new Vector2(x + 10, y + 10), Color.White);
|
||||||
|
|
||||||
|
spriteBatch.DrawString(GUI.Font, "Ping: " + (int)(client.ServerConnection.AverageRoundtripTime * 1000.0f) + " ms", new Vector2(x + 10, y + 25), Color.White);
|
||||||
|
|
||||||
|
y += 15;
|
||||||
|
|
||||||
spriteBatch.DrawString(GUI.SmallFont, "Received bytes: " + client.Statistics.ReceivedBytes, new Vector2(x + 10, y + 45), Color.White);
|
spriteBatch.DrawString(GUI.SmallFont, "Received bytes: " + client.Statistics.ReceivedBytes, new Vector2(x + 10, y + 45), Color.White);
|
||||||
spriteBatch.DrawString(GUI.SmallFont, "Received packets: " + client.Statistics.ReceivedPackets, new Vector2(x + 10, y + 60), Color.White);
|
spriteBatch.DrawString(GUI.SmallFont, "Received packets: " + client.Statistics.ReceivedPackets, new Vector2(x + 10, y + 60), Color.White);
|
||||||
|
|
||||||
@@ -866,20 +934,34 @@ namespace Barotrauma.Networking
|
|||||||
Character character = obj as Character;
|
Character character = obj as Character;
|
||||||
if (character == null) return false;
|
if (character == null) return false;
|
||||||
|
|
||||||
if (character != myCharacter && Voting.AllowVoteKick)
|
if (character != myCharacter)
|
||||||
{
|
{
|
||||||
var client = GameMain.NetworkMember.ConnectedClients.Find(c => c.Character == character);
|
var client = GameMain.NetworkMember.ConnectedClients.Find(c => c.Character == character);
|
||||||
if (client != null)
|
if (client == null) return false;
|
||||||
|
|
||||||
|
if (HasPermission(ClientPermissions.Ban))
|
||||||
{
|
{
|
||||||
var kickButton = new GUIButton(new Rectangle(0, 0, 120, 20), "Vote to Kick", Alignment.BottomLeft, GUI.Style, characterFrame);
|
var banButton = new GUIButton(new Rectangle(0, 0, 100, 20), "Ban", Alignment.BottomRight, GUI.Style, characterFrame);
|
||||||
|
banButton.UserData = character.Name;
|
||||||
|
banButton.OnClicked += GameMain.NetLobbyScreen.BanPlayer;
|
||||||
|
}
|
||||||
|
if (HasPermission(ClientPermissions.Kick))
|
||||||
|
{
|
||||||
|
var kickButton = new GUIButton(new Rectangle(0, 0, 100, 20), "Kick", Alignment.BottomLeft, GUI.Style, characterFrame);
|
||||||
|
kickButton.UserData = character.Name;
|
||||||
|
kickButton.OnClicked += GameMain.NetLobbyScreen.KickPlayer;
|
||||||
|
}
|
||||||
|
else if (Voting.AllowVoteKick)
|
||||||
|
{
|
||||||
|
var kickVoteButton = new GUIButton(new Rectangle(0, 0, 120, 20), "Vote to Kick", Alignment.BottomLeft, GUI.Style, characterFrame);
|
||||||
|
|
||||||
if (GameMain.NetworkMember.ConnectedClients != null)
|
if (GameMain.NetworkMember.ConnectedClients != null)
|
||||||
{
|
{
|
||||||
kickButton.Enabled = !client.HasKickVoteFromID(myID);
|
kickVoteButton.Enabled = !client.HasKickVoteFromID(myID);
|
||||||
}
|
}
|
||||||
|
|
||||||
kickButton.UserData = character;
|
kickVoteButton.UserData = character;
|
||||||
kickButton.OnClicked += VoteForKick;
|
kickVoteButton.OnClicked += VoteForKick;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -981,6 +1063,19 @@ namespace Barotrauma.Networking
|
|||||||
client.SendMessage(msg, NetDeliveryMethod.ReliableUnordered);
|
client.SendMessage(msg, NetDeliveryMethod.ReliableUnordered);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void KickPlayer(string kickedName, bool ban)
|
||||||
|
{
|
||||||
|
if (!permissions.HasFlag(ClientPermissions.Kick) && !ban) return;
|
||||||
|
if (!permissions.HasFlag(ClientPermissions.Ban) && ban) return;
|
||||||
|
|
||||||
|
NetOutgoingMessage msg = client.CreateMessage();
|
||||||
|
msg.Write((byte)PacketTypes.KickPlayer);
|
||||||
|
msg.Write(ban);
|
||||||
|
msg.Write(kickedName);
|
||||||
|
|
||||||
|
client.SendMessage(msg, NetDeliveryMethod.ReliableUnordered);
|
||||||
|
}
|
||||||
|
|
||||||
public bool VoteForKick(GUIButton button, object userdata)
|
public bool VoteForKick(GUIButton button, object userdata)
|
||||||
{
|
{
|
||||||
var votedClient = otherClients.Find(c => c.Character == userdata);
|
var votedClient = otherClients.Find(c => c.Character == userdata);
|
||||||
@@ -1105,7 +1200,7 @@ namespace Barotrauma.Networking
|
|||||||
Character.Controlled = character;
|
Character.Controlled = character;
|
||||||
GameMain.LightManager.LosEnabled = true;
|
GameMain.LightManager.LosEnabled = true;
|
||||||
|
|
||||||
if (endRoundButton != null) endRoundButton.Visible = Voting.AllowEndVoting;
|
if (endVoteTickBox != null) endVoteTickBox.Visible = Voting.AllowEndVoting;
|
||||||
}
|
}
|
||||||
|
|
||||||
return character;
|
return character;
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ namespace Barotrauma.Networking
|
|||||||
//----------------------------------------
|
//----------------------------------------
|
||||||
|
|
||||||
var endRoundButton = new GUIButton(new Rectangle(GameMain.GraphicsWidth - 170, 20, 150, 20), "End round", Alignment.TopLeft, GUI.Style, inGameHUD);
|
var endRoundButton = new GUIButton(new Rectangle(GameMain.GraphicsWidth - 170, 20, 150, 20), "End round", Alignment.TopLeft, GUI.Style, inGameHUD);
|
||||||
endRoundButton.OnClicked = EndButtonHit;
|
endRoundButton.OnClicked = (btn, userdata) => { EndGame(); return true; };
|
||||||
|
|
||||||
log = new ServerLog(name);
|
log = new ServerLog(name);
|
||||||
showLogButton = new GUIButton(new Rectangle(GameMain.GraphicsWidth - 170 - 170, 20, 150, 20), "Server Log", Alignment.TopLeft, GUI.Style, inGameHUD);
|
showLogButton = new GUIButton(new Rectangle(GameMain.GraphicsWidth - 170 - 170, 20, 150, 20), "Server Log", Alignment.TopLeft, GUI.Style, inGameHUD);
|
||||||
@@ -108,10 +108,10 @@ namespace Barotrauma.Networking
|
|||||||
banList = new BanList();
|
banList = new BanList();
|
||||||
|
|
||||||
LoadSettings();
|
LoadSettings();
|
||||||
|
LoadClientPermissions();
|
||||||
|
|
||||||
//----------------------------------------
|
//----------------------------------------
|
||||||
|
|
||||||
|
|
||||||
CoroutineManager.StartCoroutine(StartServer(isPublic));
|
CoroutineManager.StartCoroutine(StartServer(isPublic));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -313,7 +313,7 @@ namespace Barotrauma.Networking
|
|||||||
Log("Ending round (submarine reached the end of the level)", Color.Cyan);
|
Log("Ending round (submarine reached the end of the level)", Color.Cyan);
|
||||||
}
|
}
|
||||||
|
|
||||||
EndButtonHit(null, null);
|
EndGame();
|
||||||
UpdateNetLobby(null,null);
|
UpdateNetLobby(null,null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -496,11 +496,7 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
case (byte)PacketTypes.Chatmessage:
|
case (byte)PacketTypes.Chatmessage:
|
||||||
//SendChatMessage(ChatMessage.ReadNetworkMessage(inc));
|
|
||||||
//!!!!!!!!!!!
|
|
||||||
|
|
||||||
ReadChatMessage(inc);
|
ReadChatMessage(inc);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case (byte)PacketTypes.PlayerLeft:
|
case (byte)PacketTypes.PlayerLeft:
|
||||||
DisconnectClient(inc.SenderConnection);
|
DisconnectClient(inc.SenderConnection);
|
||||||
@@ -508,6 +504,38 @@ namespace Barotrauma.Networking
|
|||||||
case (byte)PacketTypes.StartGame:
|
case (byte)PacketTypes.StartGame:
|
||||||
sender.ReadyToStart = true;
|
sender.ReadyToStart = true;
|
||||||
break;
|
break;
|
||||||
|
case (byte)PacketTypes.EndGame:
|
||||||
|
if (!sender.HasPermission(ClientPermissions.EndRound))
|
||||||
|
{
|
||||||
|
Log(sender.name+" attempted to end the round (insufficient permissions)", Color.Red);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log("Round ended by " + sender.name, Color.Red);
|
||||||
|
EndGame();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case (byte)PacketTypes.KickPlayer:
|
||||||
|
bool ban = inc.ReadBoolean();
|
||||||
|
string kickedName = inc.ReadString();
|
||||||
|
|
||||||
|
var kickedClient = connectedClients.Find(c => c.name.ToLowerInvariant() == kickedName.ToLowerInvariant());
|
||||||
|
if (kickedClient == null || kickedClient == sender) return;
|
||||||
|
|
||||||
|
if (ban && !sender.HasPermission(ClientPermissions.Ban))
|
||||||
|
{
|
||||||
|
Log(sender.name + " attempted to ban " + kickedClient.name + " (insufficient permissions)", Color.Red);
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (!sender.HasPermission(ClientPermissions.Kick))
|
||||||
|
{
|
||||||
|
Log(sender.name + " attempted to kick " + kickedClient.name + " (insufficient permissions)", Color.Red);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
KickClient(kickedClient, ban);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case (byte)PacketTypes.CharacterInfo:
|
case (byte)PacketTypes.CharacterInfo:
|
||||||
ReadCharacterData(inc);
|
ReadCharacterData(inc);
|
||||||
break;
|
break;
|
||||||
@@ -565,7 +593,7 @@ namespace Barotrauma.Networking
|
|||||||
((float)EndVoteCount / (float)EndVoteMax) >= EndVoteRequiredRatio)
|
((float)EndVoteCount / (float)EndVoteMax) >= EndVoteRequiredRatio)
|
||||||
{
|
{
|
||||||
Log("Ending round by votes (" + EndVoteCount + "/" + (EndVoteMax - EndVoteCount) + ")", Color.Cyan);
|
Log("Ending round by votes (" + EndVoteCount + "/" + (EndVoteMax - EndVoteCount) + ")", Color.Cyan);
|
||||||
EndButtonHit(null, null);
|
EndGame();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case (byte)PacketTypes.RequestNetLobbyUpdate:
|
case (byte)PacketTypes.RequestNetLobbyUpdate:
|
||||||
@@ -578,7 +606,6 @@ namespace Barotrauma.Networking
|
|||||||
var startMessage = CreateStartMessage(roundStartSeed, Submarine.MainSub, GameMain.GameSession.gameMode.Preset);
|
var startMessage = CreateStartMessage(roundStartSeed, Submarine.MainSub, GameMain.GameSession.gameMode.Preset);
|
||||||
server.SendMessage(startMessage, inc.SenderConnection, NetDeliveryMethod.ReliableOrdered);
|
server.SendMessage(startMessage, inc.SenderConnection, NetDeliveryMethod.ReliableOrdered);
|
||||||
|
|
||||||
sender.Spectating = true;
|
|
||||||
CoroutineManager.StartCoroutine(SyncSpectator(sender));
|
CoroutineManager.StartCoroutine(SyncSpectator(sender));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -619,7 +646,7 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
if (recipients == null)
|
if (recipients == null)
|
||||||
{
|
{
|
||||||
recipients = connectedClients.FindAll(c => c.Character != null || c.Spectating);
|
recipients = connectedClients.FindAll(c => c.inGame);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (recipients.Count == 0) return;
|
if (recipients.Count == 0) return;
|
||||||
@@ -1002,9 +1029,9 @@ namespace Barotrauma.Networking
|
|||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool EndButtonHit(GUIButton button, object obj)
|
public void EndGame()
|
||||||
{
|
{
|
||||||
if (!gameStarted) return false;
|
if (!gameStarted) return;
|
||||||
|
|
||||||
string endMessage = "The round has ended." + '\n';
|
string endMessage = "The round has ended." + '\n';
|
||||||
|
|
||||||
@@ -1019,11 +1046,6 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
if (SaveServerLogs) log.Save();
|
if (SaveServerLogs) log.Save();
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IEnumerable<object> EndGame(string endMessage)
|
|
||||||
{
|
|
||||||
Character.Controlled = null;
|
Character.Controlled = null;
|
||||||
myCharacter = null;
|
myCharacter = null;
|
||||||
GameMain.GameScreen.Cam.TargetPos = Vector2.Zero;
|
GameMain.GameScreen.Cam.TargetPos = Vector2.Zero;
|
||||||
@@ -1037,7 +1059,6 @@ namespace Barotrauma.Networking
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
respawnManager = null;
|
respawnManager = null;
|
||||||
|
|
||||||
gameStarted = false;
|
gameStarted = false;
|
||||||
|
|
||||||
if (connectedClients.Count > 0)
|
if (connectedClients.Count > 0)
|
||||||
@@ -1053,12 +1074,16 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
foreach (Client client in connectedClients)
|
foreach (Client client in connectedClients)
|
||||||
{
|
{
|
||||||
client.Spectating = false;
|
|
||||||
client.Character = null;
|
client.Character = null;
|
||||||
client.inGame = false;
|
client.inGame = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CoroutineManager.StartCoroutine(EndCinematic());
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<object> EndCinematic()
|
||||||
|
{
|
||||||
float endPreviewLength = 10.0f;
|
float endPreviewLength = 10.0f;
|
||||||
|
|
||||||
var cinematic = new TransitionCinematic(Submarine.MainSub, GameMain.GameScreen.Cam, endPreviewLength);
|
var cinematic = new TransitionCinematic(Submarine.MainSub, GameMain.GameScreen.Cam, endPreviewLength);
|
||||||
@@ -1077,7 +1102,6 @@ namespace Barotrauma.Networking
|
|||||||
GameMain.NetLobbyScreen.Select();
|
GameMain.NetLobbyScreen.Select();
|
||||||
|
|
||||||
yield return CoroutineStatus.Success;
|
yield return CoroutineStatus.Success;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendRespawnManagerMsg(List<Character> spawnedCharacters = null, List<Item> spawnedItems = null, List<NetConnection> recipients = null)
|
public void SendRespawnManagerMsg(List<Character> spawnedCharacters = null, List<Item> spawnedItems = null, List<NetConnection> recipients = null)
|
||||||
@@ -1163,7 +1187,7 @@ namespace Barotrauma.Networking
|
|||||||
//if (GameMain.GameSession!=null) GameMain.GameSession.CrewManager.CreateCrewFrame(crew);
|
//if (GameMain.GameSession!=null) GameMain.GameSession.CrewManager.CreateCrewFrame(crew);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void KickPlayer(string playerName, bool ban = false)
|
public override void KickPlayer(string playerName, bool ban)
|
||||||
{
|
{
|
||||||
playerName = playerName.ToLowerInvariant();
|
playerName = playerName.ToLowerInvariant();
|
||||||
|
|
||||||
@@ -1386,6 +1410,27 @@ namespace Barotrauma.Networking
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void UpdateClientPermissions(Client client)
|
||||||
|
{
|
||||||
|
var msg = server.CreateMessage();
|
||||||
|
msg.Write((byte)PacketTypes.Permissions);
|
||||||
|
msg.Write((int)client.Permissions);
|
||||||
|
|
||||||
|
server.SendMessage(msg, client.Connection, NetDeliveryMethod.ReliableUnordered);
|
||||||
|
|
||||||
|
clientPermissions.RemoveAll(cp => cp.IP == client.Connection.RemoteEndPoint.Address.ToString());
|
||||||
|
|
||||||
|
if (client.Permissions != ClientPermissions.None)
|
||||||
|
{
|
||||||
|
clientPermissions.Add(new SavedClientPermission(
|
||||||
|
client.name,
|
||||||
|
client.Connection.RemoteEndPoint.Address.ToString(),
|
||||||
|
client.Permissions));
|
||||||
|
}
|
||||||
|
|
||||||
|
SaveClientPermissions();
|
||||||
|
}
|
||||||
|
|
||||||
public override bool SelectCrewCharacter(GUIComponent component, object obj)
|
public override bool SelectCrewCharacter(GUIComponent component, object obj)
|
||||||
{
|
{
|
||||||
base.SelectCrewCharacter(component, obj);
|
base.SelectCrewCharacter(component, obj);
|
||||||
@@ -1794,131 +1839,4 @@ namespace Barotrauma.Networking
|
|||||||
server.Shutdown("The server has been shut down");
|
server.Shutdown("The server has been shut down");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Client
|
|
||||||
{
|
|
||||||
public string name;
|
|
||||||
public byte ID;
|
|
||||||
|
|
||||||
public Character Character;
|
|
||||||
public CharacterInfo characterInfo;
|
|
||||||
public NetConnection Connection { get; set; }
|
|
||||||
public string version;
|
|
||||||
public bool inGame;
|
|
||||||
|
|
||||||
private List<Client> kickVoters;
|
|
||||||
|
|
||||||
public bool ReadyToStart;
|
|
||||||
|
|
||||||
private object[] votes;
|
|
||||||
|
|
||||||
public List<JobPrefab> jobPreferences;
|
|
||||||
public JobPrefab assignedJob;
|
|
||||||
|
|
||||||
public FileStreamSender FileStreamSender;
|
|
||||||
|
|
||||||
public bool Spectating;
|
|
||||||
|
|
||||||
public ReliableChannel ReliableChannel;
|
|
||||||
|
|
||||||
public float deleteDisconnectedTimer;
|
|
||||||
|
|
||||||
public int KickVoteCount
|
|
||||||
{
|
|
||||||
get { return kickVoters.Count; }
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public Client(NetPeer server, string name, byte ID)
|
|
||||||
: this(name, ID)
|
|
||||||
{
|
|
||||||
ReliableChannel = new ReliableChannel(server);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Client(string name, byte ID)
|
|
||||||
{
|
|
||||||
this.name = name;
|
|
||||||
this.ID = ID;
|
|
||||||
|
|
||||||
kickVoters = new List<Client>();
|
|
||||||
|
|
||||||
votes = new object[Enum.GetNames(typeof(VoteType)).Length];
|
|
||||||
|
|
||||||
jobPreferences = new List<JobPrefab>(JobPrefab.List.GetRange(0,3));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool IsValidName(string name)
|
|
||||||
{
|
|
||||||
if (name.Contains("\n") || name.Contains("\r\n")) return false;
|
|
||||||
|
|
||||||
return (name.All(c =>
|
|
||||||
c != ';' &&
|
|
||||||
c != ',' &&
|
|
||||||
c != '<' &&
|
|
||||||
c != '/'));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string SanitizeName(string name)
|
|
||||||
{
|
|
||||||
if (name.Length > 20)
|
|
||||||
{
|
|
||||||
name = name.Substring(0, 20);
|
|
||||||
}
|
|
||||||
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public T GetVote<T>(VoteType voteType)
|
|
||||||
{
|
|
||||||
return (votes[(int)voteType] is T) ? (T)votes[(int)voteType] : default(T);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetVote(VoteType voteType, object value)
|
|
||||||
{
|
|
||||||
votes[(int)voteType] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ResetVotes()
|
|
||||||
{
|
|
||||||
for (int i = 0; i<votes.Length; i++)
|
|
||||||
{
|
|
||||||
votes[i] = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void AddKickVote(Client voter)
|
|
||||||
{
|
|
||||||
if (!kickVoters.Contains(voter)) kickVoters.Add(voter);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void RemoveKickVote(Client voter)
|
|
||||||
{
|
|
||||||
kickVoters.Remove(voter);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool HasKickVoteFromID(int id)
|
|
||||||
{
|
|
||||||
return kickVoters.Any(k => k.ID == id);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static void UpdateKickVotes(List<Client> connectedClients)
|
|
||||||
{
|
|
||||||
foreach (Client client in connectedClients)
|
|
||||||
{
|
|
||||||
client.kickVoters.RemoveAll(voter => !connectedClients.Contains(voter));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void CancelTransfer()
|
|
||||||
{
|
|
||||||
if (FileStreamSender == null) return;
|
|
||||||
|
|
||||||
FileStreamSender.CancelTransfer();
|
|
||||||
FileStreamSender.Dispose();
|
|
||||||
|
|
||||||
FileStreamSender = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -177,6 +177,12 @@ namespace Barotrauma.Networking
|
|||||||
newClient.Connection = inc.SenderConnection;
|
newClient.Connection = inc.SenderConnection;
|
||||||
newClient.version = version;
|
newClient.version = version;
|
||||||
|
|
||||||
|
var savedPermissions = clientPermissions.Find(cp => cp.IP == newClient.Connection.RemoteEndPoint.Address.ToString());
|
||||||
|
if (savedPermissions != null)
|
||||||
|
{
|
||||||
|
newClient.SetPermissions(savedPermissions.Permissions);
|
||||||
|
}
|
||||||
|
|
||||||
connectedClients.Add(newClient);
|
connectedClients.Add(newClient);
|
||||||
|
|
||||||
UpdateCrewFrame();
|
UpdateCrewFrame();
|
||||||
@@ -214,6 +220,7 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
outmsg.Write((byte)PacketTypes.LoggedIn);
|
outmsg.Write((byte)PacketTypes.LoggedIn);
|
||||||
outmsg.Write(sender.ID);
|
outmsg.Write(sender.ID);
|
||||||
|
outmsg.Write((int)sender.Permissions);
|
||||||
outmsg.Write(gameStarted);
|
outmsg.Write(gameStarted);
|
||||||
outmsg.Write(gameStarted && sender.Character != null && !sender.Character.IsDead);
|
outmsg.Write(gameStarted && sender.Character != null && !sender.Character.IsDead);
|
||||||
outmsg.Write(AllowSpectating);
|
outmsg.Write(AllowSpectating);
|
||||||
|
|||||||
@@ -21,7 +21,24 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
partial class GameServer : NetworkMember, IPropertyObject
|
partial class GameServer : NetworkMember, IPropertyObject
|
||||||
{
|
{
|
||||||
|
private class SavedClientPermission
|
||||||
|
{
|
||||||
|
public readonly string IP;
|
||||||
|
public readonly string Name;
|
||||||
|
|
||||||
|
public ClientPermissions Permissions;
|
||||||
|
|
||||||
|
public SavedClientPermission(string name, string ip, ClientPermissions permissions)
|
||||||
|
{
|
||||||
|
this.Name = name;
|
||||||
|
this.IP = ip;
|
||||||
|
|
||||||
|
this.Permissions = permissions;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public const string SettingsFile = "serversettings.xml";
|
public const string SettingsFile = "serversettings.xml";
|
||||||
|
public static readonly string ClientPermissionsFile = "Data" + Path.DirectorySeparatorChar + "clientpermissions.txt";
|
||||||
|
|
||||||
public Dictionary<string, ObjectProperty> ObjectProperties
|
public Dictionary<string, ObjectProperty> ObjectProperties
|
||||||
{
|
{
|
||||||
@@ -50,6 +67,8 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
private bool autoRestart;
|
private bool autoRestart;
|
||||||
|
|
||||||
|
private List<SavedClientPermission> clientPermissions = new List<SavedClientPermission>();
|
||||||
|
|
||||||
[HasDefaultValue(true, true)]
|
[HasDefaultValue(true, true)]
|
||||||
public bool RandomizeSeed
|
public bool RandomizeSeed
|
||||||
{
|
{
|
||||||
@@ -504,6 +523,60 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
|
|
||||||
banList.CreateBanFrame(settingsTabs[2]);
|
banList.CreateBanFrame(settingsTabs[2]);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void LoadClientPermissions()
|
||||||
|
{
|
||||||
|
if (!File.Exists(ClientPermissionsFile)) return;
|
||||||
|
|
||||||
|
string[] lines;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
lines = File.ReadAllLines(ClientPermissionsFile);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
DebugConsole.ThrowError("Failed to open client permission file " + ClientPermissionsFile, e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 ip = separatedLine[separatedLine.Length - 2];
|
||||||
|
|
||||||
|
ClientPermissions permissions = ClientPermissions.None;
|
||||||
|
if (Enum.TryParse<ClientPermissions>(separatedLine.Last(), out permissions))
|
||||||
|
{
|
||||||
|
clientPermissions.Add(new SavedClientPermission(name, ip, permissions));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SaveClientPermissions()
|
||||||
|
{
|
||||||
|
GameServer.Log("Saving client permissions", null);
|
||||||
|
|
||||||
|
List<string> lines = new List<string>();
|
||||||
|
|
||||||
|
foreach (SavedClientPermission clientPermission in clientPermissions)
|
||||||
|
{
|
||||||
|
lines.Add(clientPermission.Name + "|" + clientPermission.IP+"|"+clientPermission.Permissions.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
File.WriteAllLines(ClientPermissionsFile, lines);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
DebugConsole.ThrowError("Saving client permissions to " + ClientPermissionsFile + " failed", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool SwitchSubSelection(GUITickBox tickBox)
|
private bool SwitchSubSelection(GUITickBox tickBox)
|
||||||
|
|||||||
@@ -17,6 +17,10 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
PlayerJoined, PlayerLeft,
|
PlayerJoined, PlayerLeft,
|
||||||
|
|
||||||
|
KickPlayer,
|
||||||
|
|
||||||
|
Permissions,
|
||||||
|
|
||||||
RequestNetLobbyUpdate,
|
RequestNetLobbyUpdate,
|
||||||
|
|
||||||
StartGame, EndGame, CanStartGame,
|
StartGame, EndGame, CanStartGame,
|
||||||
@@ -330,6 +334,8 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
public virtual void SendChatMessage(string message, ChatMessageType? type = null) { }
|
public virtual void SendChatMessage(string message, ChatMessageType? type = null) { }
|
||||||
|
|
||||||
|
public virtual void KickPlayer(string kickedName, bool ban) { }
|
||||||
|
|
||||||
public virtual void Update(float deltaTime)
|
public virtual void Update(float deltaTime)
|
||||||
{
|
{
|
||||||
if (gameStarted && Screen.Selected == GameMain.GameScreen)
|
if (gameStarted && Screen.Selected == GameMain.GameScreen)
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ using FarseerPhysics.Dynamics;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.ComponentModel;
|
||||||
|
|
||||||
namespace Barotrauma
|
namespace Barotrauma
|
||||||
{
|
{
|
||||||
@@ -346,7 +348,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
subList.Enabled = GameMain.Server != null || GameMain.NetworkMember.Voting.AllowSubVoting;
|
subList.Enabled = GameMain.Server != null || GameMain.NetworkMember.Voting.AllowSubVoting;
|
||||||
shuttleList.Enabled = subList.Enabled;
|
shuttleList.Enabled = subList.Enabled;
|
||||||
playerList.Enabled = GameMain.Server != null;
|
//playerList.Enabled = GameMain.Server != null;
|
||||||
modeList.Enabled = GameMain.Server != null || GameMain.NetworkMember.Voting.AllowModeVoting;
|
modeList.Enabled = GameMain.Server != null || GameMain.NetworkMember.Voting.AllowModeVoting;
|
||||||
seedBox.Enabled = GameMain.Server != null;
|
seedBox.Enabled = GameMain.Server != null;
|
||||||
serverMessage.Enabled = GameMain.Server != null;
|
serverMessage.Enabled = GameMain.Server != null;
|
||||||
@@ -758,24 +760,91 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private bool SelectPlayer(GUIComponent component, object obj)
|
private bool SelectPlayer(GUIComponent component, object obj)
|
||||||
{
|
{
|
||||||
|
if (GameMain.Client != null)
|
||||||
|
{
|
||||||
|
if (!GameMain.Client.HasPermission(ClientPermissions.Ban) &&
|
||||||
|
!GameMain.Client.HasPermission(ClientPermissions.Kick))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
playerFrame = new GUIFrame(new Rectangle(0, 0, 0, 0), Color.Black * 0.3f);
|
playerFrame = new GUIFrame(new Rectangle(0, 0, 0, 0), Color.Black * 0.3f);
|
||||||
|
|
||||||
var playerFrameInner = new GUIFrame(new Rectangle(0,0,300,150), null, Alignment.Center, GUI.Style, playerFrame);
|
var playerFrameInner = new GUIFrame(new Rectangle(0, 0, 300, 150), null, Alignment.Center, GUI.Style, playerFrame);
|
||||||
playerFrameInner.Padding = new Vector4(20.0f, 20.0f, 20.0f, 20.0f);
|
playerFrameInner.Padding = new Vector4(20.0f, 20.0f, 20.0f, 20.0f);
|
||||||
|
|
||||||
new GUITextBlock(new Rectangle(0,0,200,20), component.UserData.ToString(),
|
new GUITextBlock(new Rectangle(0,0,200,20), component.UserData.ToString(),
|
||||||
GUI.Style, Alignment.TopLeft, Alignment.TopLeft,
|
GUI.Style, Alignment.TopLeft, Alignment.TopLeft,
|
||||||
playerFrameInner, false, GUI.LargeFont);
|
playerFrameInner, false, GUI.LargeFont);
|
||||||
|
|
||||||
var kickButton = new GUIButton(new Rectangle(0, -30, 100, 20), "Kick", Alignment.BottomLeft, GUI.Style, playerFrameInner);
|
if (GameMain.Server != null)
|
||||||
kickButton.UserData = obj;
|
{
|
||||||
kickButton.OnClicked += KickPlayer;
|
var selectedClient = GameMain.Server.ConnectedClients.Find(c => c.name == component.UserData.ToString());
|
||||||
kickButton.OnClicked += ClosePlayerFrame;
|
|
||||||
|
|
||||||
var banButton = new GUIButton(new Rectangle(0, 0, 100, 20), "Ban", Alignment.BottomLeft, GUI.Style, playerFrameInner);
|
new GUITextBlock(new Rectangle(0, 25, 150, 15), selectedClient.Connection.RemoteEndPoint.Address.ToString(), GUI.Style, playerFrameInner);
|
||||||
banButton.UserData = obj;
|
|
||||||
banButton.OnClicked += BanPlayer;
|
//var permissionsBox = new GUIFrame(new Rectangle(0, 60, 0, 85), GUI.Style, playerFrameInner);
|
||||||
banButton.OnClicked += ClosePlayerFrame;
|
//permissionsBox.Padding = new Vector4(5.0f, 5.0f, 5.0f, 5.0f);
|
||||||
|
//permissionsBox.UserData = selectedClient;
|
||||||
|
|
||||||
|
//new GUITextBlock(new Rectangle(0, 0, 0, 15), "Permissions:", GUI.Style, permissionsBox);
|
||||||
|
//int x = 0, y = 0;
|
||||||
|
//foreach (ClientPermissions permission in Enum.GetValues(typeof(ClientPermissions)))
|
||||||
|
//{
|
||||||
|
// if (permission == ClientPermissions.None) continue;
|
||||||
|
|
||||||
|
// FieldInfo fi = typeof(ClientPermissions).GetField(permission.ToString());
|
||||||
|
// DescriptionAttribute[] attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
|
||||||
|
|
||||||
|
// string permissionStr = attributes.Length > 0 ? attributes[0].Description : permission.ToString();
|
||||||
|
|
||||||
|
// var permissionTick = new GUITickBox(new Rectangle(x,y+20,15,15), permissionStr, Alignment.TopLeft, GUI.SmallFont, permissionsBox);
|
||||||
|
// permissionTick.UserData = permission;
|
||||||
|
// permissionTick.Selected = selectedClient.HasPermission(permission);
|
||||||
|
|
||||||
|
// permissionTick.OnSelected = (tickBox) =>
|
||||||
|
// {
|
||||||
|
// var client = tickBox.Parent.UserData as Client;
|
||||||
|
// if (client == null) return false;
|
||||||
|
|
||||||
|
// var thisPermission = (ClientPermissions)tickBox.UserData;
|
||||||
|
|
||||||
|
// if (tickBox.Selected)
|
||||||
|
// client.GivePermission(thisPermission);
|
||||||
|
// else
|
||||||
|
// client.RemovePermission(thisPermission);
|
||||||
|
|
||||||
|
// GameMain.Server.UpdateClientPermissions(client);
|
||||||
|
|
||||||
|
// return true;
|
||||||
|
// };
|
||||||
|
|
||||||
|
|
||||||
|
// y += 20;
|
||||||
|
// if (y >= permissionsBox.Rect.Height -20)
|
||||||
|
// {
|
||||||
|
// y = 0;
|
||||||
|
// x += 100;
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GameMain.Server != null || GameMain.Client.HasPermission(ClientPermissions.Kick))
|
||||||
|
{
|
||||||
|
var kickButton = new GUIButton(new Rectangle(0, -30, 100, 20), "Kick", Alignment.BottomLeft, GUI.Style, playerFrameInner);
|
||||||
|
kickButton.UserData = obj;
|
||||||
|
kickButton.OnClicked += KickPlayer;
|
||||||
|
kickButton.OnClicked += ClosePlayerFrame;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GameMain.Server != null || GameMain.Client.HasPermission(ClientPermissions.Ban))
|
||||||
|
{
|
||||||
|
var banButton = new GUIButton(new Rectangle(0, 0, 100, 20), "Ban", Alignment.BottomLeft, GUI.Style, playerFrameInner);
|
||||||
|
banButton.UserData = obj;
|
||||||
|
banButton.OnClicked += BanPlayer;
|
||||||
|
banButton.OnClicked += ClosePlayerFrame;
|
||||||
|
}
|
||||||
|
|
||||||
var closeButton = new GUIButton(new Rectangle(0, 0, 100, 20), "Close", Alignment.BottomRight, GUI.Style, playerFrameInner);
|
var closeButton = new GUIButton(new Rectangle(0, 0, 100, 20), "Close", Alignment.BottomRight, GUI.Style, playerFrameInner);
|
||||||
closeButton.OnClicked = ClosePlayerFrame;
|
closeButton.OnClicked = ClosePlayerFrame;
|
||||||
@@ -792,18 +861,32 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public bool KickPlayer(GUIButton button, object userData)
|
public bool KickPlayer(GUIButton button, object userData)
|
||||||
{
|
{
|
||||||
if (GameMain.Server == null || userData == null) return false;
|
if (userData == null) return false;
|
||||||
|
|
||||||
GameMain.Server.KickPlayer(userData.ToString());
|
if (GameMain.Server!=null)
|
||||||
|
{
|
||||||
|
GameMain.Server.KickPlayer(userData.ToString(), false);
|
||||||
|
}
|
||||||
|
else if (GameMain.Client != null && GameMain.Client.HasPermission(ClientPermissions.Kick))
|
||||||
|
{
|
||||||
|
GameMain.Client.KickPlayer(userData.ToString(), false);
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool BanPlayer(GUIButton button, object userData)
|
public bool BanPlayer(GUIButton button, object userData)
|
||||||
{
|
{
|
||||||
if (GameMain.Server == null || userData == null) return false;
|
if (userData == null) return false;
|
||||||
|
|
||||||
GameMain.Server.KickPlayer(userData.ToString(), true);
|
if (GameMain.Server != null)
|
||||||
|
{
|
||||||
|
GameMain.Server.KickPlayer(userData.ToString(), true);
|
||||||
|
}
|
||||||
|
else if (GameMain.Client != null && GameMain.Client.HasPermission(ClientPermissions.Ban))
|
||||||
|
{
|
||||||
|
GameMain.Client.KickPlayer(userData.ToString(), true);
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -914,15 +997,6 @@ namespace Barotrauma
|
|||||||
if ((prevSize == 1.0f && chatBox.BarScroll == 0.0f) || (prevSize < 1.0f && chatBox.BarScroll == 1.0f)) chatBox.BarScroll = 1.0f;
|
if ((prevSize == 1.0f && chatBox.BarScroll == 0.0f) || (prevSize < 1.0f && chatBox.BarScroll == 1.0f)) chatBox.BarScroll = 1.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
//public bool EnterChatMessage(GUITextBox textBox, string message)
|
|
||||||
//{
|
|
||||||
// if (String.IsNullOrEmpty(message)) return false;
|
|
||||||
|
|
||||||
// GameMain.NetworkMember.SendChatMessage(ChatMessage.Create(message, ChatMessageType.Default, null));
|
|
||||||
|
|
||||||
// return true;
|
|
||||||
//}
|
|
||||||
|
|
||||||
private void UpdatePreviewPlayer(CharacterInfo characterInfo)
|
private void UpdatePreviewPlayer(CharacterInfo characterInfo)
|
||||||
{
|
{
|
||||||
GUIComponent existing = myPlayerFrame.FindChild("playerhead");
|
GUIComponent existing = myPlayerFrame.FindChild("playerhead");
|
||||||
|
|||||||
Reference in New Issue
Block a user