Add a /resizelvl command.

This commit is contained in:
UnknownShadow200 2016-07-20 10:26:33 +10:00
parent 38a6b5e5cf
commit 187f751a8c
6 changed files with 162 additions and 75 deletions

View File

@ -39,15 +39,15 @@ namespace MCGalaxy.Commands.World {
}
string seed = args.Length == 6 ? args[5] : "";
if (!MapGen.OkayAxis(x)) { Player.Message(p, "width must divisible by 16, and >= 16"); return; }
if (!MapGen.OkayAxis(x)) { Player.Message(p, "width must be divisible by 16, and >= 16"); return; }
if (!MapGen.OkayAxis(y)) { Player.Message(p, "height must be divisible by 16, and >= 16"); return; }
if (!MapGen.OkayAxis(z)) { Player.Message(p, "length must be divisible by 16, and >= to 16."); return; }
if (!MapGen.OkayAxis(z)) { Player.Message(p, "length must be divisible by 16, and >= 16."); return; }
if (!CheckMapSize(p, x, y, z)) return;
if (!ValidName(p, name, "level")) return;
if (LevelInfo.ExistsOffline(name)) {
Player.Message(p, "Level \"" + name + "\" already exists!"); return;
}
if (!CheckMapSize(p, x, y, z)) return;
Player.Message(p, "Level \"{0}\" already exists", name); return;
}
try {
using (Level lvl = new Level(name, x, y, z, args[4], seed)) {

View File

@ -15,22 +15,21 @@
or implied. See the Licenses for the specific language governing
permissions and limitations under the Licenses.
*/
using System;
using System.IO;
using MCGalaxy.SQL;
using System;
namespace MCGalaxy.Commands.World {
public sealed class CmdRenameLvl : Command {
public override string name { get { return "renamelvl"; } }
public override string shortcut { get { return ""; } }
public override string type { get { return CommandTypes.Moderation; } }
public override string type { get { return CommandTypes.World; } }
public override bool museumUsable { get { return true; } }
public override LevelPermission defaultRank { get { return LevelPermission.Admin; } }
public CmdRenameLvl() { }
public override void Use(Player p, string message) {
if (message == "" || message.IndexOf(' ') == -1) { Help(p); return; }
string[] args = message.Split(' ');
if (args.Length != 2) { Help(p); return; }
Level lvl = LevelInfo.FindMatches(p, args[0]);
if (lvl == null) return;
string newName = args[1];

View File

@ -0,0 +1,90 @@
/*
Copyright 2015 MCGalaxy team
Dual-licensed under the Educational Community License, Version 2.0 and
the GNU General Public License, Version 3 (the "Licenses"); you may
not use this file except in compliance with the Licenses. You may
obtain a copy of the Licenses at
http://www.opensource.org/licenses/ecl2.php
http://www.gnu.org/licenses/gpl-3.0.html
Unless required by applicable law or agreed to in writing,
software distributed under the Licenses are distributed on an "AS IS"
BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
or implied. See the Licenses for the specific language governing
permissions and limitations under the Licenses.
*/
using System;
using System.IO;
using MCGalaxy.SQL;
using MCGalaxy.Levels.IO;
namespace MCGalaxy.Commands.World {
public sealed class CmdResizeLvl : Command {
public override string name { get { return "resizelvl"; } }
public override string shortcut { get { return ""; } }
public override string type { get { return CommandTypes.World; } }
public override bool museumUsable { get { return true; } }
public override LevelPermission defaultRank { get { return LevelPermission.Admin; } }
public CmdResizeLvl() { }
public override void Use(Player p, string message) {
string[] args = message.Split(' ');
if (args.Length < 4) { Help(p); return; }
Level lvl = LevelInfo.FindMatches(p, args[0]);
if (lvl == null) return;
ushort x, y, z;
if (!UInt16.TryParse(args[1], out x) || !UInt16.TryParse(args[2], out y) || !UInt16.TryParse(args[3], out z)) {
Player.Message(p, "Invalid dimensions."); return;
}
if (!MapGen.OkayAxis(x)) { Player.Message(p, "width must be divisible by 16, and >= 16"); return; }
if (!MapGen.OkayAxis(y)) { Player.Message(p, "height must be divisible by 16, and >= 16"); return; }
if (!MapGen.OkayAxis(z)) { Player.Message(p, "length must be divisible by 16, and >= 16."); return; }
if (!CmdNewLvl.CheckMapSize(p, x, y, z)) return;
bool confirmed = args.Length > 4 && args[4].CaselessEq("confirm");
if (!confirmed && (x < lvl.Width || y < lvl.Height || z < lvl.Length)) {
Player.Message(p, "New level dimensions are smaller than the current dimensions, &cyou will lose blocks%S.");
Player.Message(p, "Type %T/resizelvl {0} {1} {2} {3} confirm %Sif you are sure.", args[0], x, y, z);
return;
}
Level newLvl = ResizeLevel(lvl, x, y, z);
LevelActions.Replace(lvl, newLvl);
}
static Level ResizeLevel(Level lvl, ushort width, ushort height, ushort length) {
using (Level temp = new Level(lvl.name, width, height, length)) {
for (ushort y = 0; y < Math.Min(height, lvl.Height); y++)
for (ushort z = 0; z < Math.Min(length, lvl.Length); z++)
for (ushort x = 0; x < Math.Min(width, lvl.Width); x++)
{
byte block = lvl.blocks[x + lvl.Width * (z + y * lvl.Length)];
temp.blocks[x + width * (z + y * length)] = block;
if (block != Block.custom_block) continue;
byte extBlock = lvl.GetExtTile(x, y, z);
temp.SetExtTileNoCheck(x, y, z, extBlock);
}
lock (lvl.saveLock) {
lvl.Backup(true);
LvlFile.Save(temp, LevelInfo.LevelPath(lvl.name));
lvl.saveLevel = false;
}
}
GC.Collect();
GC.WaitForPendingFinalizers();
return Level.Load(lvl.name);
}
public override void Help(Player p) {
Player.Message(p, "%T/resizelvl [level] [width] [height] [length]");
Player.Message(p, "%HResizes the given level.");
}
}
}

View File

@ -56,7 +56,11 @@ namespace MCGalaxy.Commands {
}
static void DoRestore(Level lvl, string backup) {
File.Copy(LevelInfo.BackupPath(lvl.name, backup), LevelInfo.LevelPath(lvl.name), true);
lock (lvl.saveLock) {
File.Copy(LevelInfo.BackupPath(lvl.name, backup), LevelInfo.LevelPath(lvl.name), true);
lvl.saveLevel = false;
}
Level restore = Level.Load(lvl.name);
if (restore != null) {
LevelActions.Replace(lvl, restore);

View File

@ -94,6 +94,7 @@ namespace MCGalaxy
public bool cancelunload;
public bool changed;
public bool physicschanged { get { return ListCheck.Count > 0; } }
internal bool saveLevel = true;
public bool ctfmode;
public int currentUndo;
@ -288,7 +289,6 @@ namespace MCGalaxy
}
void Init(string n, ushort x, ushort y, ushort z) {
//onLevelSave += null;
Width = x;
Height = y;
Length = z;
@ -321,10 +321,7 @@ namespace MCGalaxy
listUpdateExists = new SparseBitSet(Width, Height, Length);
}
public List<Player> players
{
get { return getPlayers(); }
}
public List<Player> players { get { return getPlayers(); } }
#region IDisposable Members
@ -351,6 +348,7 @@ namespace MCGalaxy
/// <summary> Whether block changes made on this level should be
/// saved to the BlockDB and .lvl files. </summary>
public bool ShouldSaveChanges() {
if (!saveLevel) return false;
if (Server.zombie.Running && !ZombieGame.SaveLevelBlockchanges &&
(name.CaselessEq(Server.zombie.CurLevelName)
|| name.CaselessEq(Server.zombie.LastLevelName))) return false;
@ -387,8 +385,7 @@ namespace MCGalaxy
return true;
}
public bool Unload(bool silent = false, bool save = true)
{
public bool Unload(bool silent = false, bool save = true) {
if (Server.mainLevel == this || IsMuseum) return false;
if (Server.lava.active && Server.lava.map == this) return false;
if (LevelUnload != null)
@ -403,10 +400,8 @@ namespace MCGalaxy
if (save && changed && ShouldSaveChanges()) Save(false, true);
if (save && ShouldSaveChanges()) saveChanges();
if (TntWarsGame.Find(this) != null)
{
foreach (TntWarsGame.player pl in TntWarsGame.Find(this).Players)
{
if (TntWarsGame.Find(this) != null) {
foreach (TntWarsGame.player pl in TntWarsGame.Find(this).Players) {
pl.p.CurrentTntGameNumber = -1;
Player.Message(pl.p, "TNT Wars: The TNT Wars game you are currently playing has been deleted!");
pl.p.PlayingTntWars = false;
@ -574,59 +569,57 @@ namespace MCGalaxy
LevelDB.CreateTables(name);
string path = LevelInfo.LevelPath(name);
if (File.Exists(path))
{
try
{
Level level = LvlFile.Load(name, path);
level.setPhysics(phys);
level.backedup = true;
LevelDB.LoadZones(level, name);
level.jailx = (ushort)(level.spawnx * 32);
level.jaily = (ushort)(level.spawny * 32);
level.jailz = (ushort)(level.spawnz * 32);
level.jailrotx = level.rotx;
level.jailroty = level.roty;
level.StartPhysics();
try {
LevelDB.LoadMetadata(level, name);
} catch (Exception e) {
Server.ErrorLog(e);
}
try {
string propsPath = LevelInfo.FindPropertiesFile(level.name);
if (propsPath != null)
LvlProperties.Load(level, propsPath);
else
Server.s.Log(".properties file for level " + level.name + " was not found.");
LvlProperties.LoadEnv(level, level.name);
} catch (Exception e) {
Server.ErrorLog(e);
}
BlockDefinition[] defs = BlockDefinition.Load(false, level);
for (int i = 0; i < defs.Length; i++) {
if (defs[i] == null) continue;
level.CustomBlockDefs[i] = defs[i];
}
Bots.BotsFile.LoadBots(level);
Server.s.Log(string.Format("Level \"{0}\" loaded.", level.name));
if (LevelLoaded != null)
LevelLoaded(level);
OnLevelLoadedEvent.Call(level);
return level;
} catch (Exception ex) {
Server.ErrorLog(ex);
return null;
}
if (!File.Exists(path)) {
Server.s.Log("Attempted to load " + name + ", but the level file does not exist.");
return null;
}
try {
Level level = LvlFile.Load(name, path);
level.setPhysics(phys);
level.backedup = true;
LevelDB.LoadZones(level, name);
level.jailx = (ushort)(level.spawnx * 32);
level.jaily = (ushort)(level.spawny * 32);
level.jailz = (ushort)(level.spawnz * 32);
level.jailrotx = level.rotx;
level.jailroty = level.roty;
level.StartPhysics();
try {
LevelDB.LoadMetadata(level, name);
} catch (Exception e) {
Server.ErrorLog(e);
}
try {
string propsPath = LevelInfo.FindPropertiesFile(level.name);
if (propsPath != null)
LvlProperties.Load(level, propsPath);
else
Server.s.Log(".properties file for level " + level.name + " was not found.");
LvlProperties.LoadEnv(level, level.name);
} catch (Exception e) {
Server.ErrorLog(e);
}
BlockDefinition[] defs = BlockDefinition.Load(false, level);
for (int i = 0; i < defs.Length; i++) {
if (defs[i] == null) continue;
level.CustomBlockDefs[i] = defs[i];
}
Bots.BotsFile.LoadBots(level);
Server.s.Log(string.Format("Level \"{0}\" loaded.", level.name));
if (LevelLoaded != null)
LevelLoaded(level);
OnLevelLoadedEvent.Call(level);
return level;
} catch (Exception ex) {
Server.ErrorLog(ex);
return null;
}
Server.s.Log("ERROR loading level.");
return null;
}
public static bool CheckLoadOnGoto(string givenName) {

View File

@ -385,6 +385,7 @@
<Compile Include="Commands\World\CmdPermissions.cs" />
<Compile Include="Commands\World\CmdPhysics.cs" />
<Compile Include="Commands\World\CmdRenameLvl.cs" />
<Compile Include="Commands\World\CmdResizeLvl.cs" />
<Compile Include="Commands\World\CmdRestore.cs" />
<Compile Include="Commands\World\CmdReload.cs" />
<Compile Include="Commands\World\CmdSave.cs" />