private String getCustomMsg(bool firing, int ID) { DynamicConfigFile dataFile = null; if (firing) { dataFile = Interface.Oxide.DataFileSystem.GetDatafile("firingMsgs"); } else { dataFile = Interface.Oxide.DataFileSystem.GetDatafile("warningMsgs"); } if (dataFile[ID.ToString()] != null) { return((String)dataFile[ID.ToString()]); } else if (firing) { return(firingMsg); } else { return(warningMsg); } }
/// <summary> /// Gets a datafile /// </summary> /// <param name="name"></param> /// <returns></returns> public DynamicConfigFile GetDatafile(string name) { // See if it already exists DynamicConfigFile datafile; if (datafiles.TryGetValue(name, out datafile)) { return(datafile); } // Generate the filename string filename = Path.Combine(Directory, string.Format("{0}.json", SanitiseName(name))); // Does it exist? if (File.Exists(filename)) { // Load it datafile = new DynamicConfigFile(); datafile.Load(filename); } else { // Just make a new one datafile = new DynamicConfigFile(); datafile.Save(filename); } // Add and return datafiles.Add(name, datafile); return(datafile); }
public LuaTable GetDataTable(string name) { // Get the data file DynamicConfigFile datafile = Interface.GetMod().DataFileSystem.GetDatafile(name); if (datafile == null) { return(null); } // Check if it already exists LuaTable table; if (datafilemap.TryGetValue(datafile, out table)) { return(table); } // Create the table table = Utility.TableFromConfig(datafile, LuaEnvironment); datafilemap.Add(datafile, table); // Return return(table); }
void SaveData() { DynamicConfigFile file = Interface.Oxide.DataFileSystem.GetDatafile("TeamLobbyDoors"); file.Settings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; // allows you to store Vector3 file.WriteObject <StoredData>(storedData); }
void LoadSavedData() { locationConfig = Interface.Oxide.DataFileSystem.GetFile("GeoIP-Locations"); locationData = locationConfig.ReadObject <LocationData>(); blockConfig = Interface.Oxide.DataFileSystem.GetFile("GeoIP-Blocks"); blockData = blockConfig.ReadObject <BlockData>(); }
void Loaded() { lang.RegisterMessages(Messages, this); data = Interface.Oxide.DataFileSystem.GetFile("SpawnsDatabase/spawns_data"); SpawnCreation = new Dictionary <ulong, List <Vector3> >(); LoadedSpawnfiles = new Dictionary <string, List <Vector3> >(); }
void Loaded() { billBoards = new List <Rotator>(); data = Interface.Oxide.DataFileSystem.GetFile("billboard_data"); eyesAdjust = new Vector3(0f, 1.5f, 0f); lang.RegisterMessages(Messages, this); }
private void Loaded() { data = Interface.Oxide.DataFileSystem.GetFile("automaticauthorization_data"); permission.RegisterPermission("automaticauthorization.use", this); lang.RegisterMessages(Messages, this); LoadData(); }
private void Loaded() { permission.RegisterPermission("customanimalspawns.admin", this); lang.RegisterMessages(messages, this); casdata = Interface.Oxide.DataFileSystem.GetFile("CustomSpawns/cas_data"); casdata.Settings.Converters = new JsonConverter[] { new StringEnumConverter(), new UnityVector3Converter() }; }
public PythonDictionary GetData(string name) { // Get the data file DynamicConfigFile datafile = Interface.Oxide.DataFileSystem.GetDatafile(name); if (datafile == null) { return(null); } // Check if it already exists PythonDictionary dict; if (datafilemap.TryGetValue(datafile, out dict)) { return(dict); } // Create the table dict = Utility.DictionaryFromConfig(datafile, PythonEngine); datafilemap.Add(datafile, dict); // Return return(dict); }
public ObjectInstance GetData(string name) { // Get the data file DynamicConfigFile datafile = Interface.Oxide.DataFileSystem.GetDatafile(name); if (datafile == null) { return(null); } // Check if it already exists ObjectInstance obj; if (datafilemap.TryGetValue(datafile, out obj)) { return(obj); } // Create the table obj = Utility.ObjectFromConfig(datafile, JavaScriptEngine); datafilemap.Add(datafile, obj); // Return return(obj); }
void Init() { AreasFile = GetDataFile("areas"); FactionsFile = GetDataFile("factions"); PinsFile = GetDataFile("pins"); WarsFile = GetDataFile("wars"); }
private void customClear(BasePlayer player, string command, string[] args) { if (args.Length >= 1) { RaycastHit hit = new RaycastHit(); if (Physics.Raycast(player.eyes.HeadRay(), out hit, float.MaxValue)) { var entity = hit.GetEntity(); if (entity.GetBuildingPrivilege().authorizedPlayers.Any(x => x.userid == player.userID)) { if (entity is SamSite) { String ID = entity.GetInstanceID().ToString(); //removing msgs DynamicConfigFile warnings = Interface.Oxide.DataFileSystem.GetDatafile("warningMsgs"); DynamicConfigFile firings = Interface.Oxide.DataFileSystem.GetDatafile("firingMsgs"); warnings.Remove(ID); firings.Remove(ID); player.ChatMessage("custom Messages removed"); } else { player.ChatMessage("you are not looking at a SAM Site!"); } } else { player.ChatMessage("you are not authorized here!"); } } } }
void Loaded() { lang.RegisterMessages(new Dictionary <string, string> { //chat ["No Permission"] = "You cannot use this command!", ["/setwp Invalid Syntax"] = "Invalid syntax! /setwp <waypoint name>", ["/wp Invalid Syntax"] = "Invalid syntax! /wp <waypoint name>", ["/setglobalwp Invalid Syntax"] = "Invalid syntax! /setglobalwp <waypoint name>", ["/hideglobalwp Invalid Syntax"] = "Invalid syntax! /hideglobalwp <waypoint name>", ["/removewp Invalid Syntax"] = "Invalid syntax! /removewp <waypoint name>", ["Waypoint Removed"] = "This waypoint has been removed!", ["Waypoint Already Exists"] = "This waypoint name already exists!", ["Waypoint Added"] = "You successfully created a new waypoint!", ["Waypoint Not Found"] = "Waypoint was not found", ["Max Waypoints Allowed"] = "You already have the maxiumum amount of waypoints allowed!", ["Global Waypoint Hidden"] = "This waypoint will disapear on the next update cycle", ["Global Waypoint Already Showing"] = "This waypoint is already being broadcasted", ["No Waypoints"] = "You do not have any waypoints!", ["List 1st Line"] = "Your current waypoints are:", ["List Entry"] = "- {0}", }, this); exampleData = Interface.Oxide.DataFileSystem.GetFile("PersonalBeacon"); NextTick(() => { foreach (var entry in globalWaypointCache) { InitGlobalWaypoint(entry); } }); }
void Loaded() { // English lang.RegisterMessages(new Dictionary <string, string> { //chat ["BoostStart"] = "<color=#00FFFF>Engaging turbo gather! (x{0} resources for {1}s) </color>", ["BoostEnd"] = "<color=#00FFFF>Your ability has ended! (available again in {0}s) </color>", ["NoPermissions"] = "<color=#B20000>You do not have the required permissions to use this command! </color>", ["AlreadyInUse"] = "<color=#B20000>Your ability is already in use!</color>", ["OnCooldown"] = "<color=#B20000>You are currently on cooldown! ({0}s remaining) </color>", ["CooldownEnded"] = "<color=#00FFFF>Your cooldown has ended! </color>", ["AdminInvalidSyntax"] = "<color=#B20000>Invalid syntax! /giveturbo <playername> <length> <multiplier> </color>", ["PlayerOffline"] = "<color=#B20000>The playername / ID you entered is not online or invalid! </color>", ["PlayerGivenTurbo"] = "<color=#00FFFF>{0}'s TurboGather has been activated! (x{1} for {2}s) </color>", ["PlayerGivenTurbo(CONSOLE)"] = "{0}'s TurboGather has been activated! (x{1} for {2}s)", ["AdminBoostEnd"] = "<color=#00FFFF>Your admin applied ability has ended! </color>", ["AdminBoostStart"] = "<color=#00FFFF>An admin has given you turbo gather! (x{0} resources for {1}s) </color>", ["AnimalBoostEnd"] = "<color=#00FFFF>Your ability has ended!</color>", ["InvalidSyntaxGlobal"] = "<color=#B20000>Invalid syntax! /globalturbo <length> <multiplier> </color>", ["GlobalTurboInvoke"] = "<color=#00FFFF>An admin has started a global turbogather! (x{0} resources for {1}s!)</color>", ["GlobalTurboEnd"] = "<color=#00FFFF>Global turbogather has ended!</color>", }, this); turboGatherData = Interface.Oxide.DataFileSystem.GetFile("TurboGather"); }
// Gameplay Hooks object OnPlayerDeath(BasePlayer player, HitInfo info) // TODO: Send out messages on mark passing + refactor { DynamicConfigFile dataFile = Interface.Oxide.DataFileSystem.GetDatafile("MarkedForDeathData"); // player dying is marked if (player.userID == Convert.ToUInt64(dataFile["MarkedPlayerSteamID"])) { Puts($"Marked player '{dataFile["MarkedPlayerName"]}' died."); // initiator is not an NPC (must be a player) if (info != null && !(info.InitiatorPlayer is NPCPlayer) && info.InitiatorPlayer.userID != player.userID) { ChangeMarkedPlayer(info.InitiatorPlayer); ReloadInfoPanel(); Puts($"Mark has been passed from {player.displayName} to {info.InitiatorPlayer.displayName}."); player.ChatMessage($"{player.displayName} has been killed. {info.InitiatorPlayer.displayName} is the new mark."); } else // Non-transferable { Puts("Marked player killed self. No mark transfer."); } } return(null); }
private void UpdateLocation() { DynamicConfigFile dataFile = Interface.Oxide.DataFileSystem.GetDatafile("MarkedForDeathData"); ulong markID = Convert.ToUInt64(dataFile["MarkedPlayerSteamID"]); BasePlayer mark = null; foreach (BasePlayer player in BasePlayer.allPlayerList) { if (player.userID == markID) { mark = player; break; } } if (mark != null) { dataFile["MarkedPlayerLocation"] = GetScrambledMapCoords(mark.ServerPosition); dataFile.Save(); ReloadInfoPanel(); } else { Interface.Oxide.LogError($"Could not find player with SteamID {markID}"); } }
private void Loaded() { lang.RegisterMessages(new Dictionary <string, string> { //chat ["Null Crusher"] = "{0}'s skull was crushed", ["Crushed own skull"] = "{0} crushed their own skull!", ["Default Crush Message"] = "{0}'s skull was crushed by {1}", ["Skulls chat command reply"] = "You have crushed a total of {0} skulls", ["Economy Notice"] = "You received ${0} for crushing an enemies skull!", ["ServerRewards Notice"] = "You received {0} RP for crushing an enemies skull!" }, this); SkullCrusherData = Interface.Oxide.DataFileSystem.GetFile("SkullCrusher"); if (useEconomy) { if (!Economics) { PrintError("Economics.cs was not found, auto-disabling economic features"); useEconomy = false; } } if (useServerRewards) { if (!ServerRewards) { PrintError("ServerRewards.cs was not found, auto-disabling serverrewards features"); useServerRewards = false; } } }
void Loaded() { data = Interface.Oxide.DataFileSystem.GetFile("ueconomics_data"); lang.RegisterMessages(Messages, this); permission.RegisterPermission("ueconomics.admin", this); moneyCache = new Dictionary <string, double>(); }
private void OnServerInitialized() { RustNetwork = Convert.ToInt32(Protocol.network); RustSave = Convert.ToInt32(Protocol.save); RustWorldSize = ConVar.Server.worldsize; RustSeed = ConVar.Server.seed; Puts($"Game Version: {RustNetwork}.{RustSave}, size: {RustWorldSize}, seed: {RustSeed}"); DynamicConfigFile settingsData = Interface.Oxide.DataFileSystem.GetDatafile(nameof(ZLevelsRemasteredMySQL)); if (settingsData["RustNetwork"] == null) { settingsData["RustNetwork"] = RustNetwork; settingsData["RustSave"] = RustSave; settingsData["RustWorldSize"] = RustWorldSize; settingsData["RustSeed"] = RustSeed; settingsData.Save(); } if (conf.Options.TurncateDataOnMonthlyWipe == true) { if (Convert.ToInt32(settingsData["RustNetwork"]) != Convert.ToInt32(Protocol.network)) { Puts("Detected monthly rust update. Turncating data."); settingsData["RustNetwork"] = RustNetwork; settingsData["RustSave"] = RustSave; settingsData["RustWorldSize"] = RustWorldSize; settingsData["RustSeed"] = RustSeed; settingsData.Save(); TurncateData(); } } if (conf.Options.TurncateDataOnMapWipe == true) { if (Convert.ToInt32(settingsData["RustSeed"]) != Convert.ToInt32(ConVar.Server.seed)) { Puts("Detected map change. Turncating data."); settingsData["RustNetwork"] = RustNetwork; settingsData["RustSave"] = RustSave; settingsData["RustWorldSize"] = RustWorldSize; settingsData["RustSeed"] = RustSeed; settingsData.Save(); TurncateData(); } } if (conf.Options.UpdateAtStart) { UpdateStatsData(); } timer.Repeat((float)conf.Options.SaveTimer, 0, () => { UpdateStatsData(); }); }
private void Loaded() { statisticsData = Interface.Oxide.DataFileSystem.GetFile("EventManager/statistics_data"); LoadData(); Data.UpdateRankingScores(); }
void Loaded() { permission.RegisterPermission("customresourcespawns.admin", this); lang.RegisterMessages(messages, this); serverinput = typeof(BasePlayer).GetField("serverInput", (BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance | BindingFlags.NonPublic)); crsdata = Interface.Oxide.DataFileSystem.GetFile("CustomSpawns/crs_data"); crsdata.Settings.Converters = new JsonConverter[] { new StringEnumConverter(), new UnityVector3Converter() }; }
public Helpers(DynamicConfigFile config, HurtworldPlugin plugin, Permission permission, Action <ELogType, string> log) { _config = config; _plugin = plugin; _permission = permission; _log = log; }
void Loaded() { prisondata = Interface.Oxide.DataFileSystem.GetFile("Jail/prison_data"); prisonerdata = Interface.Oxide.DataFileSystem.GetFile("Jail/prisoner_data"); lang.RegisterMessages(Messages, this); permission.RegisterPermission("jail.canenter", this); }
void Loaded() { data = Interface.Oxide.DataFileSystem.GetFile("radpockets_data"); data.Settings.Converters = new JsonConverter[] { new StringEnumConverter(), new UnityVector3Converter(), }; RadiationZones = new List <RZ>(); lang.RegisterMessages(Messages, this); permission.RegisterPermission("radpockets.use", this); }
// Register permissions, load data / config variables void Init() { permission.RegisterPermission(permissionName, this); permission.RegisterPermission(permissionNameADMIN, this); LoadData(); LoadVariables(); offlineMessageData = Interface.Oxide.DataFileSystem.GetFile(Name); }
void Loaded() { billBoards = new List <Rotator>(); data = Interface.Oxide.DataFileSystem.GetFile("billboard_data"); eyesAdjust = new Vector3(0f, 1.5f, 0f); serverinput = typeof(BasePlayer).GetField("serverInput", (BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance | BindingFlags.NonPublic)); lang.RegisterMessages(Messages, this); }
void Loaded() { permission.RegisterPermission("jail.admin", this); lang.RegisterMessages(messages, this); JailData = Interface.Oxide.DataFileSystem.GetFile("jail_data"); JailData.Settings.Converters = new JsonConverter[] { new StringEnumConverter(), new UnityVector3Converter(), }; }
/// <summary> /// Copies and translates the contents of the specified config file into the specified object /// </summary> /// <param name="config"></param> /// <param name="engine"></param> /// <returns></returns> public static ObjectInstance ObjectFromConfig(DynamicConfigFile config, Engine engine) { var objInst = new ObjectInstance(engine) {Extensible = true}; foreach (var pair in config) { objInst.FastAddProperty(pair.Key, JsValueFromObject(pair.Value, engine), true, true, true); } return objInst; }
/// <summary> /// Copies and translates the contents of the specified table into the specified config file /// </summary> /// <param name="config"></param> /// <param name="objectInstance"></param> public static void SetConfigFromObject(DynamicConfigFile config, ObjectInstance objectInstance) { config.Clear(); foreach (var property in objectInstance.GetOwnProperties()) { var value = property.Value.Value?.ToObject(); if (value != null) config[property.Key] = value; } }
private void Loaded() { permission.RegisterPermission("bounty.use", this); permission.RegisterPermission("bounty.admin", this); lang.RegisterMessages(messages, this); data = Interface.Oxide.DataFileSystem.GetFile("Bounty/bounty_data"); }
private void Loaded() { permission.RegisterPermission("carcommanderlite.admin", this); permission.RegisterPermission("carcommanderlite.use", this); permission.RegisterPermission("carcommanderlite.canspawn", this); lang.RegisterMessages(Messages, this); data = Interface.Oxide.DataFileSystem.GetFile("carcommander_data"); }
/// <summary> /// Copies and translates the contents of the specified table into the specified config file /// </summary> /// <param name="config"></param> /// <param name="table"></param> public static void SetConfigFromTable(DynamicConfigFile config, LuaTable table) { config.Clear(); foreach (var key in table.Keys) { var keystr = key as string; if (keystr == null) continue; var value = TranslateLuaItemToConfigItem(table[key]); if (value != null) config[keystr] = value; } }
/// <summary> /// Copies and translates the contents of the specified config file into the specified dictionary /// </summary> /// <param name="config"></param> /// <param name="engine"></param> /// <returns></returns> public static PythonDictionary DictionaryFromConfig(DynamicConfigFile config, ScriptEngine engine) { PythonDictionary tbl = new PythonDictionary(); // Loop each item in config foreach (var pair in config) { // Translate and set on table tbl[pair.Key] = TranslateConfigItemToPythonItem(pair.Value); } // Return return tbl; }
/// <summary> /// Copies and translates the contents of the specified dictionary into the specified config file /// </summary> /// <param name="config"></param> /// <param name="dict"></param> public static void SetConfigFromDictionary(DynamicConfigFile config, PythonDictionary dict) { config.Clear(); foreach (object key in dict.Keys) { string keystr = key as string; if (keystr != null) { object value = TranslatePythonItemToConfigItem(dict[key]); if (value != null) config[keystr] = value; } } }
public void TestLuaTableConfig() { Lua lua = new Lua(); const string inputfile = "{ \"x\": 10, \"y\": \"hello\", \"z\": [ 10, \"yo\" ], \"w\": { \"a\": 20, \"b\": [ 500, 600 ] } }"; string filename = Path.GetTempFileName(); File.WriteAllText(filename, inputfile); var cfg = ConfigFile.Load<DynamicConfigFile>(filename); TestConfigFile(cfg); // This should always pass so long as the CoreTests pass LuaTable tbl = Utility.TableFromConfig(cfg, lua); Assert.AreEqual(10.0, tbl["x"], "Failed tbl.x"); Assert.AreEqual("hello", tbl["y"], "Failed tbl.y"); Assert.IsInstanceOfType(tbl["z"], typeof(LuaTable), "Failed tbl.z"); LuaTable ztbl = tbl["z"] as LuaTable; if (ztbl != null) { Assert.IsNull(ztbl[0], "Failed tbl.z[0]"); Assert.AreEqual(10.0, ztbl[1], "Failed tbl.z[1]"); Assert.AreEqual("yo", ztbl[2], "Failed tbl.z[2]"); Assert.IsNull(ztbl[3], "Failed tbl.z[3]"); } Assert.IsInstanceOfType(tbl["w"], typeof(LuaTable), "Failed tbl.w"); LuaTable wtbl = tbl["w"] as LuaTable; if (wtbl != null) { Assert.AreEqual(20.0, wtbl["a"], "Failed tbl.w.a"); Assert.IsInstanceOfType(wtbl["b"], typeof(LuaTable), "Failed tbl.w.b"); LuaTable wbtbl = wtbl["b"] as LuaTable; if (wbtbl != null) { Assert.IsNull(wbtbl[0], "Failed tbl.w.b[0]"); Assert.AreEqual(500.0, wbtbl[1], "Failed tbl.w.b[1]"); Assert.AreEqual(600.0, wbtbl[2], "Failed tbl.w.b[2]"); Assert.IsNull(wbtbl[3], "Failed tbl.w.b[3]"); } } cfg = new DynamicConfigFile(Path.GetTempFileName()); Utility.SetConfigFromTable(cfg, tbl); TestConfigFile(cfg); }
private void TestConfigFile(DynamicConfigFile cfg) { Assert.AreEqual(10, cfg["x"], "Failed cfg.x"); Assert.AreEqual("hello", cfg["y"], "Failed cfg.y"); var list = cfg["z"] as List<object>; Assert.AreNotEqual(null, list, "Failed cfg.z"); if (list != null) { Assert.AreEqual(2, list.Count, "Failed cfg.z.Count"); if (list.Count == 2) { Assert.AreEqual(10, list[0], "Failed cfg.z[0]"); Assert.AreEqual("yo", list[1], "Failed cfg.z[1]"); } } var dict = cfg["w"] as Dictionary<string, object>; Assert.AreNotEqual(null, dict, "Failed cfg.w"); if (dict != null) { Assert.AreEqual(2, dict.Count, "Failed cfg.w.Count"); if (dict.Count == 2) { object tmp; Assert.AreEqual(true, dict.TryGetValue("a", out tmp), "Failed cfg.w.a"); Assert.AreEqual(20, tmp, "Failed cfg.w.a"); Assert.AreEqual(true, dict.TryGetValue("b", out tmp), "Failed cfg.w.b"); list = tmp as List<object>; Assert.AreNotEqual(null, list, "Failed cfg.w.b"); if (list != null) { Assert.AreEqual(2, list.Count, "Failed cfg.w.b.Count"); if (list.Count == 2) { Assert.AreEqual(500, list[0], "Failed cfg.w.b[0]"); Assert.AreEqual(600, list[1], "Failed cfg.w.b[1]"); } } } } }
public void TestEmptyTableInConfig() { Lua lua = new Lua(); lua.LoadString("TeleportData = { AdminTP = {}, Test = 3, ABC=4 }", "test").Call(); LuaTable tdata = lua["TeleportData"] as LuaTable; DynamicConfigFile cfgfile = new DynamicConfigFile(); Utility.SetConfigFromTable(cfgfile, tdata); Assert.AreEqual(3, cfgfile["Test"], "Failed TeleportData.Test"); Assert.AreEqual(4, cfgfile["ABC"], "Failed TeleportData.ABC"); //Assert.IsInstanceOfType(cfgfile["AdminTP"], typeof(List<string, object>), "Failed TeleportData.AdminTP"); string tmp = Path.GetTempFileName(); cfgfile.Save(tmp); string text = File.ReadAllText(tmp); File.Delete(tmp); }
/// <summary> /// Copies and translates the contents of the specified config file into the specified table /// </summary> /// <param name="config"></param> /// <param name="lua"></param> /// <returns></returns> public static LuaTable TableFromConfig(DynamicConfigFile config, NLua.Lua lua) { // Make a table lua.NewTable("tmp"); LuaTable tbl = lua["tmp"] as LuaTable; lua["tmp"] = null; // Loop each item in config foreach (var pair in config) { CreateFullPath(pair.Key, tbl, lua); // Translate and set on table tbl[pair.Key] = TranslateConfigItemToLuaItem(lua, pair.Value); } // Return return tbl; }
///////////////////////////////////////// // OXIDE HOOKS ///////////////////////////////////////// ///////////////////////////////////////// // Loaded() // Called when the plugin is loaded ///////////////////////////////////////// private void Loaded() { ZoneManagerData = Interface.Oxide.DataFileSystem.GetFile("ZoneManager"); ZoneManagerData.Settings.Converters = new JsonConverter[] { new StringEnumConverter(), new UnityVector3Converter(), }; permission.RegisterPermission(PermZone, this); permission.RegisterPermission(PermCanDeploy, this); permission.RegisterPermission(PermCanBuild, this); /* for(int i = 0; i < 25; i ++) { Debug.Log(UnityEngine.LayerMask.LayerToName(i)); }*/ LoadData(); LoadVariables(); /*string[] options = new string[32]; for (int i = 0; i < 32; i++) { // get layer names options[i] = i + " : " + LayerMask.LayerToName(i); } Puts("Layers: {0}", string.Join(", ", options)); var sb = new StringBuilder(); sb.AppendLine(); for (int i = 0; i < 32; i++) { sb.Append(i + ":\t"); for (int j = 0; j < 32; j++) { sb.Append(Physics.GetIgnoreLayerCollision(i, j) ? " " : "X "); } sb.AppendLine(); } Puts(sb.ToString());*/ }