第一次提交
This commit is contained in:
423
Assets/Scripts/System/MapConfig.cs
Normal file
423
Assets/Scripts/System/MapConfig.cs
Normal file
@@ -0,0 +1,423 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Xml;
|
||||
using UnityEngine;
|
||||
|
||||
namespace HxGame.Data
|
||||
{
|
||||
//<2F><>ɫ<EFBFBD><C9AB>Ϸģʽ
|
||||
[Flags]
|
||||
public enum RoleMode
|
||||
{
|
||||
PK = 1 << 0, //PK
|
||||
ShiZu = 1 << 1, //<2F><><EFBFBD><EFBFBD>
|
||||
Team = 1 << 2, //<2F>Ŷ<EFBFBD>
|
||||
LianJi = 1 << 3, //<2F><><EFBFBD><EFBFBD>
|
||||
ChengZhan = 1 << 4 //<2F><>ս
|
||||
}
|
||||
|
||||
//ʹ<><CAB9>ģʽ
|
||||
[Flags]
|
||||
public enum UseMode
|
||||
{
|
||||
UseRandom = 1 << 0, //<2F>ܷ<EFBFBD>ʹ<EFBFBD><CAB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
UseUnderground = 1 << 1, //<2F>ܷ<EFBFBD>ʹ<EFBFBD>õس<C3B5>
|
||||
UseBack = 1 << 2, //<2F>ܷ<EFBFBD>ʹ<EFBFBD>ûس<C3BB>
|
||||
UseItem = 1 << 3, //<2F>ܷ<EFBFBD>ʹ<EFBFBD><CAB9>ҩƷ
|
||||
FuBen = 1 << 4, //<2F>Ƿ<C7B7><F1B8B1B1><EFBFBD>ͼ
|
||||
}
|
||||
|
||||
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
public enum ReliveType
|
||||
{
|
||||
Normal, //<2F><>ͨ<EFBFBD><CDA8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
ChengZhan1, //<2F><>ս<EFBFBD><D5BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>1
|
||||
ChengZhan2, //<2F><>ս<EFBFBD><D5BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>2
|
||||
}
|
||||
|
||||
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
public enum ConditionMode
|
||||
{
|
||||
GM, //GM
|
||||
Team, //<2F><><EFBFBD><EFBFBD>
|
||||
Clan, //<2F><><EFBFBD><EFBFBD>
|
||||
Task, //<2F><><EFBFBD><EFBFBD>
|
||||
Activity, //<2F>
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class MapConfig
|
||||
{
|
||||
//<2F><><EFBFBD>͵<EFBFBD>
|
||||
public class TeleportConfig
|
||||
{
|
||||
public Vector2Int pos; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
public int nextMapId; //<2F>¼<EFBFBD><C2BC><EFBFBD>ͼ
|
||||
public Vector2Int nextMapPos; //<2F>¼<EFBFBD><C2BC><EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD><EFBFBD>
|
||||
}
|
||||
|
||||
//<2F><><EFBFBD><EFBFBD>
|
||||
public class AreaConfig
|
||||
{
|
||||
public Vector2Int pos; //<2F><><EFBFBD>ĵ<EFBFBD><C4B5><EFBFBD><EFBFBD><EFBFBD>
|
||||
public int radius; //<2F>뾶
|
||||
}
|
||||
|
||||
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
public class ReliveConfig
|
||||
{
|
||||
public ReliveType reliveType; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
public int mapId; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ
|
||||
public Vector2Int pos; //<2F><><EFBFBD>ĵ<EFBFBD><C4B5><EFBFBD><EFBFBD><EFBFBD>
|
||||
public int radius; //<2F>뾶
|
||||
}
|
||||
|
||||
//<2F><>Ч<EFBFBD><D0A7><EFBFBD><EFBFBD>
|
||||
public class AudioTriggerConfig
|
||||
{
|
||||
public Vector2Int pos; //<2F><><EFBFBD>ĵ<EFBFBD><C4B5><EFBFBD><EFBFBD><EFBFBD>
|
||||
public int radius; //<2F>뾶
|
||||
public string name; //<2F><>Ч<EFBFBD><D0A7><EFBFBD><EFBFBD>
|
||||
}
|
||||
|
||||
public class ConditionConfig
|
||||
{
|
||||
public ConditionMode mode; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
public int level; //<2F><><EFBFBD><EFBFBD><EFBFBD>ȼ<EFBFBD>
|
||||
public int itemId; //<2F><><EFBFBD>ĵ<EFBFBD><C4B5><EFBFBD>
|
||||
public int money; //<2F><><EFBFBD>Ļ<EFBFBD><C4BB><EFBFBD>
|
||||
public int time; //<2F><><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>
|
||||
}
|
||||
|
||||
|
||||
public string mapName; //<2F><>ͼ<EFBFBD><CDBC><EFBFBD><EFBFBD>
|
||||
public int enterLv; //<2F><><EFBFBD><EFBFBD><EFBFBD>ȼ<EFBFBD>
|
||||
public int returnMapId; //<2F>سǵ<D8B3>ͼID
|
||||
public Vector2Int returnMapCellPoint; //<2F>سǵ<D8B3>ͼ<EFBFBD><CDBC><EFBFBD><EFBFBD>
|
||||
public RoleMode roleMode; //<2F><>ɫ<EFBFBD><C9AB>Ϸģʽ
|
||||
public UseMode useMode; //ʹ<><CAB9>ģʽ
|
||||
public bool deadFall; //<2F>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
public List<TeleportConfig> teleportConfigs = new List<TeleportConfig>();
|
||||
public List<ReliveConfig> relivesConfig = new List<ReliveConfig>();
|
||||
public List<AreaConfig> sellAreasConfig = new List<AreaConfig>();
|
||||
public List<AudioTriggerConfig> audioTriggersConfig = new List<AudioTriggerConfig>();
|
||||
public List<ConditionConfig> conditionsConfig = new List<ConditionConfig>();
|
||||
|
||||
public MapConfig()
|
||||
{
|
||||
roleMode = 0;
|
||||
useMode = 0;
|
||||
deadFall = false;
|
||||
}
|
||||
|
||||
public void SaveXML(int mapId)
|
||||
{
|
||||
string path = PathUtil.GetXmlPath(mapId, "MapConfig");
|
||||
string tmp = path.Substring(0, path.LastIndexOf('/'));
|
||||
if (!Directory.Exists(tmp))
|
||||
Directory.CreateDirectory(tmp);
|
||||
|
||||
if (File.Exists(path))
|
||||
File.Delete(path);
|
||||
|
||||
XmlDocument xml = new XmlDocument();
|
||||
XmlDeclaration node = xml.CreateXmlDeclaration("1.0", "utf-8", "no");
|
||||
xml.AppendChild(node);
|
||||
|
||||
XmlElement Root = xml.CreateElement("config");
|
||||
xml.AppendChild(Root);
|
||||
|
||||
XmlElement Settings = xml.CreateElement("Settings");//<2F>ڵ<EFBFBD>Settings
|
||||
xml.DocumentElement.AppendChild(Settings);
|
||||
XmlElement Teleports = xml.CreateElement("Teleports");
|
||||
xml.DocumentElement.AppendChild(Teleports);
|
||||
XmlElement ReliveAreas = xml.CreateElement("ReliveAreas");
|
||||
xml.DocumentElement.AppendChild(ReliveAreas);
|
||||
XmlElement SellAreas = xml.CreateElement("SellAreas");
|
||||
xml.DocumentElement.AppendChild(SellAreas);
|
||||
XmlElement AudioTriggers = xml.CreateElement("AudioTriggers");
|
||||
xml.DocumentElement.AppendChild(AudioTriggers);
|
||||
XmlElement Conditions = xml.CreateElement("Conditions");
|
||||
xml.DocumentElement.AppendChild(Conditions);
|
||||
|
||||
SaveMapInfoConfig(mapId, Settings);
|
||||
SaveTeleports(xml, Teleports);
|
||||
SaveRelives(xml, ReliveAreas);
|
||||
SaveSellAreas(xml, SellAreas);
|
||||
SaveAudioTriggers(xml, AudioTriggers);
|
||||
SaveConditions(xml, Conditions);
|
||||
|
||||
xml.Save(path);
|
||||
UIWindow.Instance.ShowMessage("<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD>óɹ<C3B3>");
|
||||
}
|
||||
|
||||
private void SaveMapInfoConfig(int mapId, XmlElement xmlSettings)
|
||||
{
|
||||
xmlSettings.SetAttribute("mapID", mapId.ToString());
|
||||
xmlSettings.SetAttribute("mapName", mapName);
|
||||
xmlSettings.SetAttribute("enterLv", enterLv.ToString());
|
||||
xmlSettings.SetAttribute("returnMapId", returnMapId.ToString());
|
||||
xmlSettings.SetAttribute("returnMapCellPointX", returnMapCellPoint.x.ToString());
|
||||
xmlSettings.SetAttribute("returnMapCellPointY", returnMapCellPoint.y.ToString());
|
||||
xmlSettings.SetAttribute("roleMode", ((int)roleMode).ToString());
|
||||
xmlSettings.SetAttribute("useMode", ((int)useMode).ToString());
|
||||
xmlSettings.SetAttribute("deadFall", deadFall ? "1" : "0");
|
||||
}
|
||||
|
||||
|
||||
private void SaveTeleports(XmlDocument xml, XmlElement xmlElement)
|
||||
{
|
||||
XmlElement child = null;
|
||||
for(int i=0; i<teleportConfigs.Count; i++)
|
||||
{
|
||||
child = xml.CreateElement("Teleport");
|
||||
child.SetAttribute("posIndexX", teleportConfigs[i].pos.x.ToString());
|
||||
child.SetAttribute("posIndexY", teleportConfigs[i].pos.y.ToString());
|
||||
child.SetAttribute("nextMapId", teleportConfigs[i].nextMapId.ToString());
|
||||
child.SetAttribute("nextMapPosIndexX", teleportConfigs[i].nextMapPos.x.ToString());
|
||||
child.SetAttribute("nextMapPosIndexY", teleportConfigs[i].nextMapPos.y.ToString());
|
||||
xmlElement.AppendChild(child);
|
||||
}
|
||||
}
|
||||
|
||||
private void SaveRelives(XmlDocument xml, XmlElement xmlElement)
|
||||
{
|
||||
XmlElement child = null;
|
||||
for (int i = 0; i < relivesConfig.Count; i++)
|
||||
{
|
||||
child = xml.CreateElement("ReliveArea");
|
||||
child.SetAttribute("type", ((int)relivesConfig[i].reliveType).ToString());
|
||||
child.SetAttribute("mapId", relivesConfig[i].mapId.ToString());
|
||||
child.SetAttribute("indexX", relivesConfig[i].pos.x.ToString());
|
||||
child.SetAttribute("indexY", relivesConfig[i].pos.y.ToString());
|
||||
child.SetAttribute("radius", relivesConfig[i].radius.ToString());
|
||||
xmlElement.AppendChild(child);
|
||||
}
|
||||
}
|
||||
|
||||
private void SaveSellAreas(XmlDocument xml, XmlElement xmlElement)
|
||||
{
|
||||
XmlElement child = null;
|
||||
for (int i = 0; i < sellAreasConfig.Count; i++)
|
||||
{
|
||||
child = xml.CreateElement("SellArea");
|
||||
child.SetAttribute("indexX", sellAreasConfig[i].pos.x.ToString());
|
||||
child.SetAttribute("indexY", sellAreasConfig[i].pos.y.ToString());
|
||||
child.SetAttribute("radius", sellAreasConfig[i].radius.ToString());
|
||||
xmlElement.AppendChild(child);
|
||||
}
|
||||
}
|
||||
|
||||
private void SaveAudioTriggers(XmlDocument xml, XmlElement xmlElement)
|
||||
{
|
||||
XmlElement child = null;
|
||||
for (int i = 0; i < audioTriggersConfig.Count; i++)
|
||||
{
|
||||
child = xml.CreateElement("AudioTrigger");
|
||||
child.SetAttribute("indexX", audioTriggersConfig[i].pos.x.ToString());
|
||||
child.SetAttribute("indexY", audioTriggersConfig[i].pos.y.ToString());
|
||||
child.SetAttribute("radius", audioTriggersConfig[i].radius.ToString());
|
||||
child.SetAttribute("name", audioTriggersConfig[i].name);
|
||||
xmlElement.AppendChild(child);
|
||||
}
|
||||
}
|
||||
|
||||
private void SaveConditions(XmlDocument xml, XmlElement xmlElement)
|
||||
{
|
||||
XmlElement child = null;
|
||||
|
||||
for (int i = 0; i < conditionsConfig.Count; i++)
|
||||
{
|
||||
child = xml.CreateElement("Condition");
|
||||
child.SetAttribute("mode", ((int)conditionsConfig[i].mode).ToString());
|
||||
child.SetAttribute("level", conditionsConfig[i].level.ToString());
|
||||
child.SetAttribute("itemId", conditionsConfig[i].itemId.ToString());
|
||||
child.SetAttribute("money", conditionsConfig[i].money.ToString());
|
||||
child.SetAttribute("time", conditionsConfig[i].time.ToString());
|
||||
|
||||
xmlElement.AppendChild(child);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public bool LoadXML(int mapId)
|
||||
{
|
||||
string path = PathUtil.GetXmlPath(mapId, "MapConfig");
|
||||
if (!File.Exists(path))
|
||||
{
|
||||
UIWindow.Instance.ShowMessage("û<><C3BB><EFBFBD>ҵ<EFBFBD><D2B5><EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>");
|
||||
return false;
|
||||
}
|
||||
|
||||
XmlDocument xmlDocument = new XmlDocument();
|
||||
xmlDocument.Load(path);
|
||||
|
||||
XmlNode xmlRoot = xmlDocument.SelectSingleNode("config");
|
||||
XmlNode xmlSettings = xmlRoot.SelectSingleNode("Settings");
|
||||
XmlNode xmlTeleports = xmlRoot.SelectSingleNode("Teleports");
|
||||
XmlNode xmlReliveAreas = xmlRoot.SelectSingleNode("ReliveAreas");
|
||||
XmlNode xmlSellAreas = xmlRoot.SelectSingleNode("SellAreas");
|
||||
XmlNode xmlAudioTriggers = xmlRoot.SelectSingleNode("AudioTriggers");
|
||||
XmlNode xmlConditions = xmlRoot.SelectSingleNode("Conditions");
|
||||
|
||||
int id = Convert.ToInt32(xmlSettings.Attributes.GetNamedItem("mapID").Value);
|
||||
if(id != mapId)
|
||||
{
|
||||
UIWindow.Instance.ShowMessage("<22><>ͼID<49><44><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>MapConfig<69><67><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>");
|
||||
return false;
|
||||
}
|
||||
|
||||
LoadMapInfoConfig(xmlSettings);
|
||||
LoadTeleports(xmlTeleports);
|
||||
LoadRelivesArea(xmlReliveAreas);
|
||||
LoadSellAreas(xmlSellAreas);
|
||||
LoadAudioTriggers(xmlAudioTriggers);
|
||||
LoadConditions(xmlConditions);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void LoadMapInfoConfig(XmlNode xmlSettings)
|
||||
{
|
||||
mapName = xmlSettings.Attributes.GetNamedItem("mapName").Value;
|
||||
enterLv = Convert.ToInt32(xmlSettings.Attributes.GetNamedItem("enterLv").Value);
|
||||
returnMapId = Convert.ToInt32(xmlSettings.Attributes.GetNamedItem("returnMapId").Value);
|
||||
int x, y;
|
||||
x = Convert.ToInt32(xmlSettings.Attributes.GetNamedItem("returnMapCellPointX").Value);
|
||||
y = Convert.ToInt32(xmlSettings.Attributes.GetNamedItem("returnMapCellPointY").Value);
|
||||
returnMapCellPoint = new Vector2Int(x, y);
|
||||
|
||||
roleMode = (RoleMode)Convert.ToInt32(xmlSettings.Attributes.GetNamedItem("roleMode").Value);
|
||||
useMode = (UseMode)Convert.ToInt32(xmlSettings.Attributes.GetNamedItem("useMode").Value);
|
||||
deadFall = xmlSettings.Attributes.GetNamedItem("enterLv").Value == "1" ? true : false;
|
||||
}
|
||||
|
||||
private void LoadTeleports(XmlNode xmlNodes)
|
||||
{
|
||||
if (xmlNodes == null)
|
||||
return;
|
||||
|
||||
XmlNode xmlNode = null;
|
||||
XmlNodeList xmlNodeList = xmlNodes.ChildNodes;
|
||||
int x, y;
|
||||
for(int i=0; i<xmlNodeList.Count; i++)
|
||||
{
|
||||
xmlNode = xmlNodeList.Item(i);
|
||||
if (xmlNode.Name != "Teleport")
|
||||
continue;
|
||||
|
||||
TeleportConfig tc = new TeleportConfig();
|
||||
x = Convert.ToInt32(xmlNode.Attributes.GetNamedItem("posIndexX").Value);
|
||||
y = Convert.ToInt32(xmlNode.Attributes.GetNamedItem("posIndexY").Value);
|
||||
tc.pos = new Vector2Int(x, y);
|
||||
tc.nextMapId = Convert.ToInt32(xmlNode.Attributes.GetNamedItem("nextMapId").Value);
|
||||
x = Convert.ToInt32(xmlNode.Attributes.GetNamedItem("nextMapPosIndexX").Value);
|
||||
y = Convert.ToInt32(xmlNode.Attributes.GetNamedItem("nextMapPosIndexY").Value);
|
||||
tc.nextMapPos = new Vector2Int(x, y);
|
||||
teleportConfigs.Add(tc);
|
||||
}
|
||||
}
|
||||
|
||||
private void LoadRelivesArea(XmlNode xmlNodes)
|
||||
{
|
||||
if (xmlNodes == null)
|
||||
return;
|
||||
|
||||
XmlNode xmlNode = null;
|
||||
XmlNodeList xmlNodeList = xmlNodes.ChildNodes;
|
||||
int x, y;
|
||||
for (int i = 0; i < xmlNodeList.Count; i++)
|
||||
{
|
||||
xmlNode = xmlNodeList.Item(i);
|
||||
if (xmlNode.Name != "ReliveArea")
|
||||
continue;
|
||||
|
||||
ReliveConfig rc = new ReliveConfig();
|
||||
rc.reliveType = (ReliveType)Convert.ToInt32(xmlNode.Attributes.GetNamedItem("type").Value);
|
||||
rc.mapId = Convert.ToInt32(xmlNode.Attributes.GetNamedItem("mapId").Value);
|
||||
x = Convert.ToInt32(xmlNode.Attributes.GetNamedItem("indexX").Value);
|
||||
y = Convert.ToInt32(xmlNode.Attributes.GetNamedItem("indexY").Value);
|
||||
rc.pos = new Vector2Int(x, y);
|
||||
rc.radius = Convert.ToInt32(xmlNode.Attributes.GetNamedItem("radius").Value);
|
||||
relivesConfig.Add(rc);
|
||||
}
|
||||
}
|
||||
|
||||
private void LoadSellAreas(XmlNode xmlNodes)
|
||||
{
|
||||
if (xmlNodes == null)
|
||||
return;
|
||||
|
||||
XmlNode xmlNode = null;
|
||||
XmlNodeList xmlNodeList = xmlNodes.ChildNodes;
|
||||
int x, y;
|
||||
for (int i = 0; i < xmlNodeList.Count; i++)
|
||||
{
|
||||
xmlNode = xmlNodeList.Item(i);
|
||||
if (xmlNode.Name != "SellArea")
|
||||
continue;
|
||||
|
||||
AreaConfig ac = new AreaConfig();
|
||||
x = Convert.ToInt32(xmlNode.Attributes.GetNamedItem("indexX").Value);
|
||||
y = Convert.ToInt32(xmlNode.Attributes.GetNamedItem("indexY").Value);
|
||||
ac.pos = new Vector2Int(x, y);
|
||||
ac.radius = Convert.ToInt32(xmlNode.Attributes.GetNamedItem("radius").Value);
|
||||
sellAreasConfig.Add(ac);
|
||||
}
|
||||
}
|
||||
|
||||
private void LoadAudioTriggers(XmlNode xmlNodes)
|
||||
{
|
||||
if (xmlNodes == null)
|
||||
return;
|
||||
|
||||
XmlNode xmlNode = null;
|
||||
XmlNodeList xmlNodeList = xmlNodes.ChildNodes;
|
||||
int x, y;
|
||||
for (int i = 0; i < xmlNodeList.Count; i++)
|
||||
{
|
||||
xmlNode = xmlNodeList.Item(i);
|
||||
if (xmlNode.Name != "AudioTrigger")
|
||||
continue;
|
||||
|
||||
AudioTriggerConfig at = new AudioTriggerConfig();
|
||||
x = Convert.ToInt32(xmlNode.Attributes.GetNamedItem("indexX").Value);
|
||||
y = Convert.ToInt32(xmlNode.Attributes.GetNamedItem("indexY").Value);
|
||||
at.pos = new Vector2Int(x, y);
|
||||
at.radius = Convert.ToInt32(xmlNode.Attributes.GetNamedItem("radius").Value);
|
||||
at.name = xmlNode.Attributes.GetNamedItem("name").Value;
|
||||
audioTriggersConfig.Add(at);
|
||||
}
|
||||
}
|
||||
|
||||
private void LoadConditions(XmlNode xmlNodes)
|
||||
{
|
||||
if (xmlNodes == null)
|
||||
return;
|
||||
|
||||
XmlNode xmlNode = null;
|
||||
XmlNodeList xmlNodeList = xmlNodes.ChildNodes;
|
||||
|
||||
int x, y;
|
||||
for (int i = 0; i < xmlNodeList.Count; i++)
|
||||
{
|
||||
xmlNode = xmlNodeList.Item(i);
|
||||
if (xmlNode.Name != "Condition")
|
||||
continue;
|
||||
|
||||
var t = new ConditionConfig();
|
||||
t.mode = (ConditionMode)Convert.ToInt32(xmlNode.Attributes.GetNamedItem("mode").Value);
|
||||
t.level = Convert.ToInt32(xmlNode.Attributes.GetNamedItem("level").Value);
|
||||
t.itemId = Convert.ToInt32(xmlNode.Attributes.GetNamedItem("itemId").Value);
|
||||
t.money = Convert.ToInt32(xmlNode.Attributes.GetNamedItem("money").Value);
|
||||
t.time = Convert.ToInt32(xmlNode.Attributes.GetNamedItem("time").Value);
|
||||
conditionsConfig.Add(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user