mirror of
https://github.com/ClassiCube/MCGalaxy.git
synced 2025-09-23 20:53:40 -04:00
Now with less linq and less tabs.
This commit is contained in:
parent
2f29aeaccd
commit
4a3a1b82c5
@ -75,7 +75,7 @@ namespace MCGalaxy.Commands {
|
|||||||
}
|
}
|
||||||
|
|
||||||
WhoInfo FromOffline(OfflinePlayer target, string message) {
|
WhoInfo FromOffline(OfflinePlayer target, string message) {
|
||||||
Group group = Group.Find(Group.findPlayer(target.name));
|
Group group = Group.findPlayerGroup(target.name);
|
||||||
string color = target.color == "" ? group.color : target.color;
|
string color = target.color == "" ? group.color : target.color;
|
||||||
string prefix = target.title == "" ? "" : color + "[" + target.titleColor + target.title + color + "] ";
|
string prefix = target.title == "" ? "" : color + "[" + target.titleColor + target.title + color + "] ";
|
||||||
|
|
||||||
|
@ -1,82 +1,80 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2010 MCSharp team (Modified for use with MCZall/MCLawl/MCGalaxy)
|
Copyright 2010 MCSharp team (Modified for use with MCZall/MCLawl/MCGalaxy)
|
||||||
|
|
||||||
Dual-licensed under the Educational Community License, Version 2.0 and
|
Dual-licensed under the Educational Community License, Version 2.0 and
|
||||||
the GNU General Public License, Version 3 (the "Licenses"); you may
|
the GNU General Public License, Version 3 (the "Licenses"); you may
|
||||||
not use this file except in compliance with the Licenses. You may
|
not use this file except in compliance with the Licenses. You may
|
||||||
obtain a copy of the Licenses at
|
obtain a copy of the Licenses at
|
||||||
|
|
||||||
http://www.opensource.org/licenses/ecl2.php
|
http://www.opensource.org/licenses/ecl2.php
|
||||||
http://www.gnu.org/licenses/gpl-3.0.html
|
http://www.gnu.org/licenses/gpl-3.0.html
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing,
|
Unless required by applicable law or agreed to in writing,
|
||||||
software distributed under the Licenses are distributed on an "AS IS"
|
software distributed under the Licenses are distributed on an "AS IS"
|
||||||
BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||||
or implied. See the Licenses for the specific language governing
|
or implied. See the Licenses for the specific language governing
|
||||||
permissions and limitations under the Licenses.
|
permissions and limitations under the Licenses.
|
||||||
*/
|
*/
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace MCGalaxy.BlockPhysics {
|
namespace MCGalaxy.BlockPhysics {
|
||||||
|
public static class BirdPhysics {
|
||||||
public static class BirdPhysics {
|
|
||||||
|
public static void Do(Level lvl, ref Check C) {
|
||||||
public static void Do(Level lvl, ref Check C) {
|
Random rand = lvl.physRandom;
|
||||||
Random rand = lvl.physRandom;
|
ushort x, y, z;
|
||||||
ushort x, y, z;
|
lvl.IntToPos(C.b, out x, out y, out z);
|
||||||
lvl.IntToPos(C.b, out x, out y, out z);
|
|
||||||
|
|
||||||
switch (rand.Next(1, 15)) {
|
switch (rand.Next(1, 15)) {
|
||||||
case 1:
|
case 1:
|
||||||
if (lvl.GetTile(x, (ushort)(y - 1), z) == Block.air)
|
if (lvl.GetTile(x, (ushort)(y - 1), z) == Block.air)
|
||||||
lvl.AddUpdate(lvl.PosToInt(x, (ushort)(y - 1), z), lvl.blocks[C.b]);
|
lvl.AddUpdate(lvl.PosToInt(x, (ushort)(y - 1), z), lvl.blocks[C.b]);
|
||||||
else goto case 3;
|
else goto case 3;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
if (lvl.GetTile(x, (ushort)(y + 1), z) == Block.air)
|
if (lvl.GetTile(x, (ushort)(y + 1), z) == Block.air)
|
||||||
lvl.AddUpdate(lvl.PosToInt(x, (ushort)(y + 1), z), lvl.blocks[C.b]);
|
lvl.AddUpdate(lvl.PosToInt(x, (ushort)(y + 1), z), lvl.blocks[C.b]);
|
||||||
else goto case 6;
|
else goto case 6;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
case 4:
|
case 4:
|
||||||
case 5:
|
case 5:
|
||||||
FlyTo(lvl, ref C, x - 1, y, z);
|
FlyTo(lvl, ref C, x - 1, y, z);
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
case 7:
|
case 7:
|
||||||
case 8:
|
case 8:
|
||||||
FlyTo(lvl, ref C, x + 1, y, z);
|
FlyTo(lvl, ref C, x + 1, y, z);
|
||||||
break;
|
break;
|
||||||
case 9:
|
case 9:
|
||||||
case 10:
|
case 10:
|
||||||
case 11:
|
case 11:
|
||||||
FlyTo(lvl, ref C, x, y, z - 1);
|
FlyTo(lvl, ref C, x, y, z - 1);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
FlyTo(lvl, ref C, x, y, z + 1);
|
FlyTo(lvl, ref C, x, y, z + 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
lvl.AddUpdate(C.b, Block.air);
|
lvl.AddUpdate(C.b, Block.air);
|
||||||
C.data.Data = 255;
|
C.data.Data = 255;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void FlyTo(Level lvl, ref Check C, int x, int y, int z) {
|
static void FlyTo(Level lvl, ref Check C, int x, int y, int z) {
|
||||||
int index = lvl.PosToInt((ushort)x, (ushort)y, (ushort)z);
|
int index = lvl.PosToInt((ushort)x, (ushort)y, (ushort)z);
|
||||||
if (index < 0)
|
if (index < 0) return;
|
||||||
return;
|
|
||||||
|
switch (lvl.blocks[index]) {
|
||||||
switch (lvl.blocks[index]) {
|
case Block.air:
|
||||||
case Block.air:
|
lvl.AddUpdate(index, lvl.blocks[C.b]);
|
||||||
lvl.AddUpdate(index, lvl.blocks[C.b]);
|
break;
|
||||||
break;
|
case Block.op_air:
|
||||||
case Block.op_air:
|
break;
|
||||||
break;
|
default:
|
||||||
default:
|
PhysicsArgs args = default(PhysicsArgs);
|
||||||
PhysicsArgs args = default(PhysicsArgs);
|
args.Type1 = PhysicsArgs.Dissipate; args.Value1 = 25;
|
||||||
args.Type1 = PhysicsArgs.Dissipate; args.Value1 = 25;
|
lvl.AddUpdate(C.b, Block.red, false, args);
|
||||||
lvl.AddUpdate(C.b, Block.red, false, args);
|
break;
|
||||||
break;
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,6 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
|
||||||
|
|
||||||
namespace MCGalaxy {
|
namespace MCGalaxy {
|
||||||
/// <summary> This is the group object, where ranks and their data are stored </summary>
|
/// <summary> This is the group object, where ranks and their data are stored </summary>
|
||||||
@ -53,11 +52,8 @@ namespace MCGalaxy {
|
|||||||
public PlayerList playerList;
|
public PlayerList playerList;
|
||||||
public string MOTD = String.Empty;
|
public string MOTD = String.Empty;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary> Create a new group object </summary>
|
||||||
/// Create a new group object
|
public Group() {
|
||||||
/// </summary>
|
|
||||||
public Group()
|
|
||||||
{
|
|
||||||
Permission = LevelPermission.Null;
|
Permission = LevelPermission.Null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,11 +84,9 @@ namespace MCGalaxy {
|
|||||||
OnGroupLoaded(this);
|
OnGroupLoaded(this);
|
||||||
OnGroupLoadedEvent.Call(this);
|
OnGroupLoadedEvent.Call(this);
|
||||||
}
|
}
|
||||||
/// <summary>
|
|
||||||
/// Fill the commands that this group can use
|
/// <summary> Fill the commands that this group can use </summary>
|
||||||
/// </summary>
|
public void fillCommands() {
|
||||||
public void fillCommands()
|
|
||||||
{
|
|
||||||
CommandList _commands = new CommandList();
|
CommandList _commands = new CommandList();
|
||||||
GrpCommands.AddCommands(out _commands, Permission);
|
GrpCommands.AddCommands(out _commands, Permission);
|
||||||
commands = _commands;
|
commands = _commands;
|
||||||
@ -101,7 +95,7 @@ namespace MCGalaxy {
|
|||||||
public bool CanExecute(string cmdName) {
|
public bool CanExecute(string cmdName) {
|
||||||
return commands.Contains(Command.all.Find(cmdName));
|
return commands.Contains(Command.all.Find(cmdName));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Check to see if this group can excute cmd </summary>
|
/// <summary> Check to see if this group can excute cmd </summary>
|
||||||
/// <param name="cmd">The command object to check</param>
|
/// <param name="cmd">The command object to check</param>
|
||||||
/// <returns>True if this group can use it, false if they cant</returns>
|
/// <returns>True if this group can use it, false if they cant</returns>
|
||||||
@ -114,25 +108,32 @@ namespace MCGalaxy {
|
|||||||
/// <summary> Load up all server groups </summary>
|
/// <summary> Load up all server groups </summary>
|
||||||
public static void InitAll() {
|
public static void InitAll() {
|
||||||
GroupList = new List<Group>();
|
GroupList = new List<Group>();
|
||||||
|
|
||||||
if (File.Exists("properties/ranks.properties"))
|
if (File.Exists("properties/ranks.properties"))
|
||||||
GroupProperties.InitAll();
|
GroupProperties.InitAll();
|
||||||
|
|
||||||
if (findPerm(LevelPermission.Banned) == null) GroupList.Add(new Group(LevelPermission.Banned, 1, 1, "Banned", '8', String.Empty, "banned.txt"));
|
if (findPerm(LevelPermission.Banned) == null)
|
||||||
if (findPerm(LevelPermission.Guest) == null) GroupList.Add(new Group(LevelPermission.Guest, 1, 120, "Guest", '7', String.Empty, "guest.txt"));
|
GroupList.Add(new Group(LevelPermission.Banned, 1, 1, "Banned", '8', String.Empty, "banned.txt"));
|
||||||
if (findPerm(LevelPermission.Builder) == null) GroupList.Add(new Group(LevelPermission.Builder, 400, 300, "Builder", '2', String.Empty, "builders.txt"));
|
if (findPerm(LevelPermission.Guest) == null)
|
||||||
if (findPerm(LevelPermission.AdvBuilder) == null) GroupList.Add(new Group(LevelPermission.AdvBuilder, 1200, 900, "AdvBuilder", '3', String.Empty, "advbuilders.txt"));
|
GroupList.Add(new Group(LevelPermission.Guest, 1, 120, "Guest", '7', String.Empty, "guest.txt"));
|
||||||
if (findPerm(LevelPermission.Operator) == null) GroupList.Add(new Group(LevelPermission.Operator, 2500, 5400, "Operator", 'c', String.Empty, "operators.txt"));
|
if (findPerm(LevelPermission.Builder) == null)
|
||||||
if (findPerm(LevelPermission.Admin) == null) GroupList.Add(new Group(LevelPermission.Admin, 65536, int.MaxValue, "SuperOP", 'e', String.Empty, "uberOps.txt"));
|
GroupList.Add(new Group(LevelPermission.Builder, 400, 300, "Builder", '2', String.Empty, "builders.txt"));
|
||||||
|
if (findPerm(LevelPermission.AdvBuilder) == null)
|
||||||
|
GroupList.Add(new Group(LevelPermission.AdvBuilder, 1200, 900, "AdvBuilder", '3', String.Empty, "advbuilders.txt"));
|
||||||
|
if (findPerm(LevelPermission.Operator) == null)
|
||||||
|
GroupList.Add(new Group(LevelPermission.Operator, 2500, 5400, "Operator", 'c', String.Empty, "operators.txt"));
|
||||||
|
if (findPerm(LevelPermission.Admin) == null)
|
||||||
|
GroupList.Add(new Group(LevelPermission.Admin, 65536, int.MaxValue, "SuperOP", 'e', String.Empty, "uberOps.txt"));
|
||||||
GroupList.Add(new Group(LevelPermission.Nobody, 65536, -1, "Nobody", '0', String.Empty, "nobody.txt"));
|
GroupList.Add(new Group(LevelPermission.Nobody, 65536, -1, "Nobody", '0', String.Empty, "nobody.txt"));
|
||||||
GroupList.Sort((a, b) => a.Permission.CompareTo(b.Permission));
|
GroupList.Sort((a, b) => a.Permission.CompareTo(b.Permission));
|
||||||
|
|
||||||
if (Group.Find(Server.defaultRank) != null) standard = Group.Find(Server.defaultRank);
|
if (Group.Find(Server.defaultRank) != null)
|
||||||
else standard = Group.findPerm(LevelPermission.Guest);
|
standard = Group.Find(Server.defaultRank);
|
||||||
|
else
|
||||||
|
standard = Group.findPerm(LevelPermission.Guest);
|
||||||
|
|
||||||
Player[] players = PlayerInfo.Online.Items;
|
Player[] players = PlayerInfo.Online.Items;
|
||||||
foreach (Player pl in players)
|
foreach (Player pl in players)
|
||||||
pl.group = GroupList.Find(g => g.name == pl.group.name);
|
pl.group = Find(pl.group.name);
|
||||||
if (OnGroupLoad != null)
|
if (OnGroupLoad != null)
|
||||||
OnGroupLoad();
|
OnGroupLoad();
|
||||||
OnGroupLoadEvent.Call();
|
OnGroupLoadEvent.Call();
|
||||||
@ -142,9 +143,9 @@ namespace MCGalaxy {
|
|||||||
/// <summary> Save givenList group </summary>
|
/// <summary> Save givenList group </summary>
|
||||||
/// <param name="givenList">The list of groups to save</param>
|
/// <param name="givenList">The list of groups to save</param>
|
||||||
public static void saveGroups(List<Group> givenList) {
|
public static void saveGroups(List<Group> givenList) {
|
||||||
lock (saveLock)
|
lock (saveLock)
|
||||||
GroupProperties.SaveGroups(givenList);
|
GroupProperties.SaveGroups(givenList);
|
||||||
|
|
||||||
if (OnGroupSave != null) OnGroupSave();
|
if (OnGroupSave != null) OnGroupSave();
|
||||||
OnGroupSaveEvent.Call();
|
OnGroupSaveEvent.Call();
|
||||||
}
|
}
|
||||||
@ -152,14 +153,21 @@ namespace MCGalaxy {
|
|||||||
/// <summary> Check whether a group with that name exists. </summary>
|
/// <summary> Check whether a group with that name exists. </summary>
|
||||||
public static bool Exists(string name) {
|
public static bool Exists(string name) {
|
||||||
name = name.ToLower();
|
name = name.ToLower();
|
||||||
return GroupList.Any(gr => gr.name == name);
|
foreach (Group grp in GroupList) {
|
||||||
|
if (grp.name == name) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Find the group which has the given name. </summary>
|
/// <summary> Find the group which has the given name. </summary>
|
||||||
public static Group Find(string name) {
|
public static Group Find(string name) {
|
||||||
name = name.ToLower();
|
name = name.ToLower();
|
||||||
MapName(ref name);
|
MapName(ref name);
|
||||||
return GroupList.Find(gr => gr.name == name);
|
|
||||||
|
foreach (Group grp in GroupList) {
|
||||||
|
if (grp.name == name) return grp;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Find the group(s) which contain the given name. </summary>
|
/// <summary> Find the group(s) which contain the given name. </summary>
|
||||||
@ -172,11 +180,11 @@ namespace MCGalaxy {
|
|||||||
|
|
||||||
/// <summary> Find the group(s) which contain the given name. </summary>
|
/// <summary> Find the group(s) which contain the given name. </summary>
|
||||||
public static Group FindMatches(Player p, string name) {
|
public static Group FindMatches(Player p, string name) {
|
||||||
int matches = 0; return FindMatches(p, name, out matches);
|
int matches = 0; return FindMatches(p, name, out matches);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void MapName(ref string name) {
|
static void MapName(ref string name) {
|
||||||
if (name == "adv") name = "advbuilder";
|
if (name == "adv") name = "advbuilder";
|
||||||
if (name == "op") name = "operator";
|
if (name == "op") name = "operator";
|
||||||
if (name == "super" || (name == "admin" && !Group.Exists("admin"))) name = "superop";
|
if (name == "super" || (name == "admin" && !Group.Exists("admin"))) name = "superop";
|
||||||
if (name == "noone") name = "nobody";
|
if (name == "noone") name = "nobody";
|
||||||
@ -193,40 +201,32 @@ namespace MCGalaxy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Get the group name that player /playerName/ is in </summary>
|
/// <summary> Get the group name that player /playerName/ is in </summary>
|
||||||
/// <param name="playerName">The player Name</param>
|
/// <param name="name">The player Name</param>
|
||||||
/// <returns>The group name</returns>
|
/// <returns>The group name</returns>
|
||||||
public static string findPlayer(string playerName) {
|
public static string findPlayer(string name) { return findPlayerGroup(name).name; }
|
||||||
foreach (Group grp in Group.GroupList.Where(grp => grp.playerList.Contains(playerName))) {
|
|
||||||
return grp.name;
|
|
||||||
}
|
|
||||||
return Group.standard.name;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary> Find the group object that the player /playerName/ is in </summary>
|
/// <summary> Find the group object that the player /playerName/ is in </summary>
|
||||||
/// <param name="playerName">The player name</param>
|
/// <param name="name">The player name</param>
|
||||||
/// <returns>The group object that the player is in</returns>
|
/// <returns>The group object that the player is in</returns>
|
||||||
public static Group findPlayerGroup(string playerName) {
|
public static Group findPlayerGroup(string name) {
|
||||||
foreach (Group grp in Group.GroupList.Where(grp => grp.playerList.Contains(playerName))) {
|
foreach (Group grp in Group.GroupList) {
|
||||||
return grp;
|
if (grp.playerList.Contains(name)) return grp;
|
||||||
}
|
}
|
||||||
return Group.standard;
|
return Group.standard;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string concatList(bool includeColor = true, bool skipExtra = false, bool permissions = false) {
|
public static string concatList(bool includeColor = true, bool skipExtra = false, bool permissions = false) {
|
||||||
string returnString = "";
|
string sum = "";
|
||||||
foreach (Group grp in Group.GroupList.Where(grp => !skipExtra || (grp.Permission > LevelPermission.Guest && grp.Permission < LevelPermission.Nobody)))
|
foreach (Group grp in Group.GroupList) {
|
||||||
{
|
if (skipExtra && (grp.Permission < LevelPermission.Guest || grp.Permission >= LevelPermission.Nobody)) continue;
|
||||||
if (includeColor)
|
|
||||||
returnString += ", " + grp.color + grp.name + Server.DefaultColor;
|
if (includeColor) sum += ", " + grp.ColoredName + Server.DefaultColor;
|
||||||
else if (permissions)
|
else if (permissions) sum += ", " + ((int)grp.Permission);
|
||||||
returnString += ", " + ((int)grp.Permission).ToString(CultureInfo.InvariantCulture);
|
else sum += ", " + grp.name;
|
||||||
else
|
|
||||||
returnString += ", " + grp.name;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (includeColor) returnString = returnString.Remove(returnString.Length - 2);
|
if (includeColor) sum = sum.Remove(sum.Length - 2);
|
||||||
|
return sum.Remove(0, 2);
|
||||||
return returnString.Remove(0, 2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Returns whether the given player is in the banned rank. </summary>
|
/// <summary> Returns whether the given player is in the banned rank. </summary>
|
||||||
|
@ -18,7 +18,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
|
||||||
|
|
||||||
namespace MCGalaxy {
|
namespace MCGalaxy {
|
||||||
public class GrpCommands {
|
public class GrpCommands {
|
||||||
@ -163,20 +162,16 @@ namespace MCGalaxy {
|
|||||||
|
|
||||||
public static string getInts(List<LevelPermission> givenList) {
|
public static string getInts(List<LevelPermission> givenList) {
|
||||||
if (givenList == null) return "";
|
if (givenList == null) return "";
|
||||||
string returnString = ""; bool foundOne = false;
|
return givenList.Join(p => ((int)p).ToString(), ",");
|
||||||
foreach (LevelPermission Perm in givenList)
|
|
||||||
{
|
|
||||||
foundOne = true;
|
|
||||||
returnString += "," + (int)Perm;
|
|
||||||
}
|
|
||||||
if (foundOne) returnString = returnString.Remove(0, 1);
|
|
||||||
return returnString;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void AddCommands(out CommandList commands, LevelPermission perm) {
|
public static void AddCommands(out CommandList commands, LevelPermission perm) {
|
||||||
commands = new CommandList();
|
commands = new CommandList();
|
||||||
foreach (rankAllowance aV in allowedCommands.Where(aV => (aV.lowestRank <= perm && !aV.disallow.Contains(perm)) || aV.allow.Contains(perm)))
|
foreach (rankAllowance perms in allowedCommands) {
|
||||||
commands.Add(Command.all.Find(aV.commandName));
|
bool canUse = perms.lowestRank <= perm && !perms.disallow.Contains(perm);
|
||||||
|
if (canUse || perms.allow.Contains(perm))
|
||||||
|
commands.Add(Command.all.Find(perms.commandName));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -75,7 +75,8 @@ namespace MCGalaxy {
|
|||||||
SendMessage("You currently have &a" + money + " %S" + Server.moneys);
|
SendMessage("You currently have &a" + money + " %S" + Server.moneys);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if ( !Group.Find("Nobody").commands.Contains("award") && !Group.Find("Nobody").commands.Contains("awards") && !Group.Find("Nobody").commands.Contains("awardmod") )
|
Group nobody = Group.findPerm(LevelPermission.Nobody);
|
||||||
|
if (!nobody.commands.Contains("award") && !nobody.commands.Contains("awards") && !nobody.commands.Contains("awardmod") )
|
||||||
SendMessage("You have " + Awards.AwardAmount(name) + " awards.");
|
SendMessage("You have " + Awards.AwardAmount(name) + " awards.");
|
||||||
} catch {
|
} catch {
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user